Explorar el Código

Merge branch 'deploy' of http://git.chelingzhu.com/chelingzhu-web/storeCheck-app into deploy

lilei hace 4 años
padre
commit
978403d296

+ 820 - 0
components/mx-datepicker/mx-datepicker.vue

@@ -0,0 +1,820 @@
+<template>
+	<view v-if="isShow" class="picker">
+		<u-mask :show="isShow" @click="onCancel"></u-mask>
+		<!-- 日期选择器 -->
+		<view v-if="type!='time'" class="picker-modal">
+			<view class="picker-modal-header">
+				<view class="picker-icon picker-icon-zuozuo" :hover-stay-time="100" hover-class="picker-icon-active" @click="onSetYear('-1')"></view>
+				<view class="picker-icon picker-icon-zuo" :hover-stay-time="100" hover-class="picker-icon-active" @click="onSetMonth('-1')"></view>
+				<text class="picker-modal-header-title">{{title}}</text>
+				<view class="picker-icon picker-icon-you" :hover-stay-time="100" hover-class="picker-icon-active" @click="onSetMonth('+1')"></view>
+				<view class="picker-icon picker-icon-youyou" :hover-stay-time="100" hover-class="picker-icon-active" @click="onSetYear('+1')"></view>
+			</view>
+			<swiper class="picker-modal-body" :circular="true" :duration="200" :skip-hidden-item-layout="true" :current="calendarIndex" @change="onSwiperChange">
+				<swiper-item class="picker-calendar" v-for="(calendar,calendarIndex2) in calendars" :key="calendarIndex2">
+					<view class="picker-calendar-view" v-for="(week,index) in weeks" :key="index - 7">
+						<view class="picker-calendar-view-item">{{week}}</view>
+					</view>
+					<view class="picker-calendar-view" v-for="(date,dateIndex) in calendar" :key="dateIndex" @click="onSelectDate(date)">
+						<!-- 背景样式 -->
+						<view v-show="date.bgStyle.type" :class="'picker-calendar-view-'+date.bgStyle.type" :style="{background: date.bgStyle.background}"></view>
+						<!-- 正常和选中样式 -->
+						<view class="picker-calendar-view-item" :style="{opacity: date.statusStyle.opacity, color: date.statusStyle.color, background: date.statusStyle.background}">
+							<text>{{date.title}}</text>
+						</view>
+						<!-- 小圆点样式 -->
+						<view class="picker-calendar-view-dot" :style="{opacity: date.dotStyle.opacity, background: date.dotStyle.background}"></view>
+						<!-- 信息样式 -->
+						<view v-show="date.tips" class="picker-calendar-view-tips">{{date.tips}}</view>
+					</view>
+				</swiper-item>
+			</swiper>
+			<view class="picker-modal-footer">
+				<view class="picker-modal-footer-info">
+					<block v-if="isMultiSelect">
+						<view class="picker-display">
+							<text>{{beginText}}日期</text>
+							<text class="picker-display-text">{{BeginTitle}}</text>
+							<view v-if="isContainTime" class="picker-display-link" :hover-stay-time="100" hover-class="picker-display-link-active"
+							 :style="{color}" @click="onShowTimePicker('begin')">{{BeginTimeTitle}}</view>
+						</view>
+						<view class="picker-display">
+							<text>{{endText}}日期</text>
+							<text class="picker-display-text">{{EndTitle}}</text>
+							<view v-if="isContainTime" class="picker-display-link" :hover-stay-time="100" hover-class="picker-display-link-active"
+							 :style="{color}" @click="onShowTimePicker('end')">{{EndTimeTitle}}</view>
+						</view>
+					</block>
+					<block v-else>
+						<view class="picker-display">
+							<text>当前选择</text>
+							<text class="picker-display-text">{{BeginTitle}}</text>
+							<view v-if="isContainTime" class="picker-display-link" :hover-stay-time="100" hover-class="picker-display-link-active"
+							 :style="{color}" @click="onShowTimePicker('begin')">{{BeginTimeTitle}}</view>
+						</view>
+					</block>
+				</view>
+				<view class="picker-modal-footer-btn">
+					<view class="picker-btn" :hover-stay-time="100" hover-class="picker-btn-active" @click="onCancel">取消</view>
+					<view class="picker-btn" :style="{color}" :hover-stay-time="100" hover-class="picker-btn-active" @click="onConfirm">确定</view>
+				</view>
+			</view>
+		</view>
+		<!-- 时间选择器 -->
+		<view v-if="showTimePicker" class="picker">
+			<view class="picker-modal picker-time">
+				<view class="picker-modal-header">
+					<text class="picker-modal-header-title">选择日期</text>
+				</view>
+				<picker-view class="picker-modal-time" indicator-class="picker-modal-time-item" :value="timeValue" @change="onTimeChange">
+					<picker-view-column>
+						<view v-for="(v,i) in 24" :key="i">{{i<10?'0'+i:i}}时</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view v-for="(v,i) in 60" :key="i">{{i<10?'0'+i:i}}分</view>
+					</picker-view-column>
+					<picker-view-column v-if="showSeconds">
+						<view v-for="(v,i) in 60" :key="i">{{i<10?'0'+i:i}}秒</view>
+					</picker-view-column>
+				</picker-view>
+				<view class="picker-modal-footer">
+					<view class="picker-modal-footer-info">
+						<view class="picker-display">
+							<text>当前选择</text>
+							<text class="picker-display-text">{{PickerTimeTitle}}</text>
+						</view>
+					</view>
+					<view class="picker-modal-footer-btn">
+						<view class="picker-btn" :hover-stay-time="100" hover-class="picker-btn-active" @click="onCancelTime">取消</view>
+						<view class="picker-btn" :style="{color}" :hover-stay-time="100" hover-class="picker-btn-active" @click="onConfirmTime">确定</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * 工具函数库
+	 */
+	const DateTools = {
+		/**
+		 * 获取公历节日
+		 * @param date Date对象
+		 */
+		getHoliday(date) {
+			let holidays = {
+				'0101': '元旦',
+				'0214': '情人',
+				'0308': '妇女',
+				'0312': '植树',
+				'0401': '愚人',
+				'0501': '劳动',
+				'0504': '青年',
+				'0601': '儿童',
+				'0701': '建党',
+				'0801': '建军',
+				'0903': '抗日',
+				'0910': '教师',
+				'1001': '国庆',
+				'1031': '万圣',
+				'1224': '平安',
+				'1225': '圣诞'
+			};
+			let value = this.format(date, 'mmdd');
+			if (holidays[value]) return holidays[value];
+			return false;
+		},
+		/**
+		 * 解析标准日期格式
+		 * @param s 日期字符串
+		 * @return 返回Date对象
+		 */
+		parse: s => new Date(s.replace(/(年|月|-)/g, '/').replace(/(日)/g, '')),
+		/**
+		 * 比较日期是否为同一天
+		 * @param a Date对象
+		 * @param b Date对象
+		 * @return Boolean
+		 */
+		isSameDay: (a, b) => a.getMonth() == b.getMonth() && a.getFullYear() == b.getFullYear() && a.getDate() == b.getDate(),
+		/**
+		 * 格式化Date对象
+		 * @param d 日期对象
+		 * @param f 格式字符串
+		 * @return 返回格式化后的字符串
+		 */
+		format(d, f) {
+			var o = {
+				"m+": d.getMonth() + 1,
+				"d+": d.getDate(),
+				"h+": d.getHours(),
+				"i+": d.getMinutes(),
+				"s+": d.getSeconds(),
+				"q+": Math.floor((d.getMonth() + 3) / 3),
+			};
+			if (/(y+)/.test(f))
+				f = f.replace(RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length));
+			for (var k in o)
+				if (new RegExp("(" + k + ")").test(f))
+					f = f.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
+			return f;
+		},
+		/**
+		 * 用于format格式化后的反解析
+		 * @param s 日期字符串
+		 * @param f 格式字符串
+		 * @return 返回Date对象
+		 */
+		inverse(s, f) {
+			var o = {
+				"y": '',
+				"m": '',
+				"d": '',
+				"h": '',
+				"i": '',
+				"s": '',
+			};
+			let d = new Date();
+			if (s.length != f.length) return d;
+			for (let i in f)
+				if (o[f[i]] != undefined) o[f[i]] += s[i];
+			if (o.y) d.setFullYear(o.y.length < 4 ? (d.getFullYear() + '').substr(0, 4 - o.y.length) + o.y : o.y);
+			o.m && d.setMonth(o.m - 1, 1);
+			o.d && d.setDate(o.d - 0);
+			o.h && d.setHours(o.h - 0);
+			o.i && d.setMinutes(o.i - 0);
+			o.s && d.setSeconds(o.s - 0);
+			return d;
+		},
+		/**
+		 * 获取日历数组(42天)
+		 * @param date 日期对象或日期字符串
+		 * @param proc 处理日历(和forEach类似),传递一个数组中的item
+		 * @return Array
+		 */
+		getCalendar(date, proc) {
+			let it = new Date(date),
+				calendars = [];
+			it.setDate(1);
+			it.setDate(it.getDate() - ((it.getDay() == 0 ? 7 : it.getDay()) - 1)); //偏移量
+			for (let i = 0; i < 42; i++) {
+				let tmp = {
+					dateObj: new Date(it),
+					title: it.getDate(),
+					isOtherMonth: it.getMonth() < date.getMonth() || it.getMonth() > date.getMonth()
+				};
+				calendars.push(Object.assign(tmp, proc ? proc(tmp) : {}));
+				it.setDate(it.getDate() + 1);
+			}
+			return calendars;
+		},
+		/**
+		 * 获取日期到指定的月份1号(不改变原来的date对象)
+		 * @param d Date对象
+		 * @param v 指定的月份
+		 * @return Date对象
+		 */
+		getDateToMonth(d, v) {
+			let n = new Date(d);
+			n.setMonth(v, 1);
+			return n;
+		},
+		/**
+		 * 把时间数组转为时间字符串
+		 * @param t Array[时,分,秒]
+		 * @param showSecinds 是否显示秒
+		 * @return 字符串 时:分[:秒]
+		 */
+		formatTimeArray(t, s) {
+			let r = [...t];
+			if (!s) r.length = 2;
+			r.forEach((v, k) => r[k] = ('0' + v).slice(-2));
+			return r.join(':');
+		}
+	};
+
+	export default {
+		props: {
+			//颜色
+			color: {
+				type: String,
+				default: '#409eff'
+			},
+			//是否显示秒 针对type为datetime或time时生效
+			showSeconds: {
+				type: Boolean,
+				default: false
+			},
+			//初始的值
+			value: [String, Array],
+			//类型date time datetime range rangetime
+			type: {
+				type: String,
+				default: 'range'
+			},
+			//是否显示
+			show: {
+				type: Boolean,
+				default: false
+			},
+			//初始格式
+			format: {
+				type: String,
+				default: ''
+			},
+			//显示公历节日
+			showHoliday: {
+				type: Boolean,
+				default: true
+			},
+			//显示提示
+			showTips: {
+				type: Boolean,
+				default: false
+			},
+			//开始文案 针对type为范围选择时生效
+			beginText: {
+				type: String,
+				default: '开始'
+			},
+			//结束文案 针对type为范围选择时生效
+			endText: {
+				type: String,
+				default: '结束'
+			}
+		},
+		data() {
+			return {
+				isShow: false, //是否显示
+				isMultiSelect: false, //是否为多选
+				isContainTime: false, //是否包含时间
+				date: {}, //当前日期对象
+				weeks: ["一", "二", "三", "四", "五", "六", "日"],
+				title: '初始化', //标题
+				calendars: [[],[],[]], //日历数组
+				calendarIndex: 1, //当前日历索引
+				checkeds: [], //选中的日期对象集合
+				showTimePicker: false, //是否显示时间选择器
+				timeValue: [0, 0, 0], //时间选择器的值
+				timeType: 'begin', //当前时间选择的类型
+				beginTime: [0, 0, 0], //当前所选的开始时间值
+				endTime: [0, 0, 0], //当前所选的结束时间值
+			};
+		},
+		methods: {
+			//设置值
+			setValue(value) {
+				this.date = new Date();
+				this.checkeds = [];
+				this.isMultiSelect = this.type.indexOf('range') >= 0;
+				this.isContainTime = this.type.indexOf('time') >= 0;
+				//将字符串解析为Date对象
+				let parseDateStr = (str) => (this.format ? DateTools.inverse(str, this.format) : DateTools.parse(str));
+				if (value) {
+					if (this.isMultiSelect) {
+						Array.isArray(value) && value.forEach((dateStr, index) => {
+							let date = parseDateStr(dateStr);
+							let time = [date.getHours(), date.getMinutes(), date.getSeconds()];
+							if (index == 0) this.beginTime = time;
+							else this.endTime = time;
+							this.checkeds.push(date);
+						});
+					} else {
+						if (this.type == 'time') {
+							let date = parseDateStr('2019/1/1 ' + value);
+							this.beginTime = [date.getHours(), date.getMinutes(), date.getSeconds()];
+							this.onShowTimePicker('begin');
+						} else {
+							this.checkeds.push(parseDateStr(value));
+							if (this.isContainTime) this.beginTime = [
+								this.checkeds[0].getHours(),
+								this.checkeds[0].getMinutes(),
+								this.checkeds[0].getSeconds()
+							];
+						}
+					}
+					if (this.checkeds.length) this.date = new Date(this.checkeds[0]);
+				} else {
+					if (this.isContainTime) {
+						this.beginTime = [this.date.getHours(), this.date.getMinutes(), this.date.getSeconds()];
+						if (this.isMultiSelect) this.endTime = [...this.beginTime];
+					}
+					this.checkeds.push(new Date(this.date));
+				}
+				if (this.type != 'time') this.refreshCalendars(true);
+				else this.onShowTimePicker('begin');
+			},
+			//改变年份
+			onSetYear(value) {
+				this.date.setFullYear(this.date.getFullYear() + parseInt(value));
+				this.refreshCalendars(true);
+			},
+			//改变月份
+			onSetMonth(value) {
+				this.date.setMonth(this.date.getMonth() + parseInt(value));
+				this.refreshCalendars(true);
+			},
+			//时间选择变更
+			onTimeChange(e) {
+				this.timeValue = e.detail.value;
+			},
+			//设置时间选择器的显示状态
+			onShowTimePicker(type) {
+				this.showTimePicker = true;
+				this.timeType = type;
+				this.timeValue = type == 'begin' ? [...this.beginTime] : [...this.endTime];
+			},
+			//处理日历
+			procCalendar(item) {
+				//定义初始样式
+				item.statusStyle = {
+					opacity: 1,
+					color: item.isOtherMonth ? '#ddd' : '#000',
+					background: 'transparent'
+				};
+				item.bgStyle = {
+					type: '',
+					background: 'transparent'
+				};
+				item.dotStyle = {
+					opacity: 1,
+					background: 'transparent'
+				};
+				item.tips = "";
+				//标记今天的日期
+				if (DateTools.isSameDay(new Date(), item.dateObj)) {
+					item.statusStyle.color = this.color;
+					if (item.isOtherMonth) item.statusStyle.opacity = 0.3;
+				}
+				//标记选中项
+				this.checkeds.forEach(date => {
+					if (DateTools.isSameDay(date, item.dateObj)) {
+						item.statusStyle.background = this.color;
+						item.statusStyle.color = '#fff';
+						item.statusStyle.opacity = 1;
+						if (this.isMultiSelect && this.showTips) item.tips = this.beginText;
+					}
+				});
+				//节假日或今日的日期标点
+				if (item.statusStyle.background != this.color) {
+					let holiday = this.showHoliday ? DateTools.getHoliday(item.dateObj) : false;
+					if (holiday || DateTools.isSameDay(new Date(), item.dateObj)) {
+						item.title = holiday || item.title;
+						item.dotStyle.background = this.color;
+						if (item.isOtherMonth) item.dotStyle.opacity = 0.2;
+					}
+				} else {
+					item.title = item.dateObj.getDate();
+				}
+				//有两个日期
+				if (this.checkeds.length == 2) {
+					if (DateTools.isSameDay(this.checkeds[0], item.dateObj)) { //开始日期
+						item.bgStyle.type = 'bgbegin';
+					}
+					if (DateTools.isSameDay(this.checkeds[1], item.dateObj)) { //结束日期
+						if (this.isMultiSelect && this.showTips) item.tips = item.bgStyle.type ? this.beginText + ' / ' + this.endText : this.endText;
+						if (!item.bgStyle.type) { //开始日期不等于结束日期
+							item.bgStyle.type = 'bgend';
+						} else {
+							item.bgStyle.type = '';
+						}
+					}
+					if (!item.bgStyle.type && (+item.dateObj > +this.checkeds[0] && +item.dateObj < +this.checkeds[1])) { //中间的日期
+						item.bgStyle.type = 'bg';
+						item.statusStyle.color = this.color;
+					}
+					if (item.bgStyle.type) {
+						item.bgStyle.background = this.color;
+						item.dotStyle.opacity = 1;
+						item.statusStyle.opacity = 1;
+					}
+				}
+			},
+			//刷新日历
+			refreshCalendars(refresh = false) {
+				let date = new Date(this.date);
+				let before = DateTools.getDateToMonth(date, date.getMonth() - 1);
+				let after = DateTools.getDateToMonth(date, date.getMonth() + 1);
+				if (this.calendarIndex == 0) {
+					if(refresh) this.calendars.splice(0, 1, DateTools.getCalendar(date, this.procCalendar));
+					this.calendars.splice(1, 1, DateTools.getCalendar(after, this.procCalendar));
+					this.calendars.splice(2, 1, DateTools.getCalendar(before, this.procCalendar));
+				} else if (this.calendarIndex == 1) {
+					this.calendars.splice(0, 1, DateTools.getCalendar(before, this.procCalendar));
+					if(refresh) this.calendars.splice(1, 1, DateTools.getCalendar(date, this.procCalendar));
+					this.calendars.splice(2, 1, DateTools.getCalendar(after, this.procCalendar));
+				} else if (this.calendarIndex == 2) {
+					this.calendars.splice(0, 1, DateTools.getCalendar(after, this.procCalendar));
+					this.calendars.splice(1, 1, DateTools.getCalendar(before, this.procCalendar));
+					if(refresh) this.calendars.splice(2, 1, DateTools.getCalendar(date, this.procCalendar));
+				}
+				this.title = DateTools.format(this.date, 'yyyy年mm月');
+			},
+			//滑块切换
+			onSwiperChange(e) {
+				this.calendarIndex = e.detail.current;
+				let calendar = this.calendars[this.calendarIndex];
+				this.date = new Date(calendar[22].dateObj); //取中间一天,保证是当前的月份
+				this.refreshCalendars();
+			},
+			//选中日期
+			onSelectDate(date) {
+				if (~this.type.indexOf('range') && this.checkeds.length == 2) this.checkeds = [];
+				else if (!(~this.type.indexOf('range')) && this.checkeds.length) this.checkeds = [];
+				this.checkeds.push(new Date(date.dateObj));
+				this.checkeds.sort((a, b) => a - b); //从小到大排序
+				this.calendars.forEach(calendar => {
+					calendar.forEach(this.procCalendar); //重新处理
+				});
+			},
+			//时间选择取消
+			onCancelTime() {
+				this.showTimePicker = false;
+				this.type == 'time' && this.onCancel();
+			},
+			//时间选择确定
+			onConfirmTime() {
+				if (this.timeType == 'begin') this.beginTime = this.timeValue;
+				else this.endTime = this.timeValue;
+				this.showTimePicker = false;
+				this.type == 'time' && this.onConfirm();
+			},
+			//取消
+			onCancel() {
+				this.$emit('cancel', false);
+			},
+			//确定
+			onConfirm() {
+				let result = {
+					value: null,
+					date: null
+				};
+				//定义默认格式
+				let defaultFormat = {
+					'date': 'yyyy/mm/dd',
+					'time': 'hh:ii' + (this.showSeconds ? ':ss' : ''),
+					'datetime': ''
+				};
+				defaultFormat['datetime'] = defaultFormat.date + ' ' + defaultFormat.time;
+				let fillTime = (date, timeArr) => {
+					date.setHours(timeArr[0], timeArr[1]);
+					if (this.showSeconds) date.setSeconds(timeArr[2]);
+				};
+				if (this.type == 'time') {
+					let date = new Date();
+					fillTime(date, this.beginTime);
+					result.value = DateTools.format(date, this.format ? this.format : defaultFormat.time);
+					result.date = date;
+				} else {
+					if (this.isMultiSelect) {
+						let values = [],
+							dates = [];
+						if (this.checkeds.length < 2) return uni.showToast({
+							icon: 'none',
+							title: '请选择两个日期'
+						});
+						this.checkeds.forEach((date, index) => {
+							let newDate = new Date(date);
+							if (this.isContainTime) {
+								let time = [this.beginTime, this.endTime];
+								fillTime(newDate, time[index]);
+							}
+							values.push(DateTools.format(newDate, this.format ? this.format : defaultFormat[this.isContainTime ?
+								'datetime' : 'date']));
+							dates.push(newDate);
+						});
+						result.value = values;
+						result.date = dates;
+					} else {
+						let newDate = new Date(this.checkeds[0]);
+						if (this.isContainTime) {
+							newDate.setHours(this.beginTime[0], this.beginTime[1]);
+							if (this.showSeconds) newDate.setSeconds(this.beginTime[2]);
+						}
+						result.value = DateTools.format(newDate, this.format ? this.format : defaultFormat[this.isContainTime ?
+							'datetime' : 'date']);
+						result.date = newDate;
+					}
+				}
+				this.$emit('confirm', result);
+			}
+		},
+		computed: {
+			BeginTitle() {
+				let value = '未选择';
+				if (this.checkeds.length) value = DateTools.format(this.checkeds[0], 'yy/mm/dd');
+				return value;
+			},
+			EndTitle() {
+				let value = '未选择';
+				if (this.checkeds.length == 2) value = DateTools.format(this.checkeds[1], 'yy/mm/dd');
+				return value;
+			},
+			PickerTimeTitle() {
+				return DateTools.formatTimeArray(this.timeValue, this.showSeconds);
+			},
+			BeginTimeTitle() {
+				return this.BeginTitle != '未选择' ? DateTools.formatTimeArray(this.beginTime, this.showSeconds) : '';
+			},
+			EndTimeTitle() {
+				return this.EndTitle != '未选择' ? DateTools.formatTimeArray(this.endTime, this.showSeconds) : '';
+			}
+		},
+		watch: {
+			show(newValue, oldValue) {
+				newValue && this.setValue(this.value);
+				this.isShow = newValue;
+			},
+			value(newValue, oldValue) {
+				setTimeout(()=>{
+					this.setValue(newValue);
+				}, 0);
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	$z-index: 100;
+	$cell-spacing: 20upx;
+	$calendar-size: 630upx;
+	$calendar-item-size: 90upx;
+
+	.picker {
+		position: fixed;
+		z-index: $z-index;
+		background: rgba(255, 255, 255, 0);
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100%;
+		font-size: 28upx;
+
+		&-btn {
+			padding: $cell-spacing*0.5 $cell-spacing;
+			border-radius: 12upx;
+			color: #666;
+
+			&-active {
+				background: rgba(0, 0, 0, .1);
+			}
+		}
+
+		&-display {
+			color: #666;
+
+			&-text {
+				color: #000;
+				margin: 0 $cell-spacing*0.5;
+			}
+
+			&-link {
+				display: inline-block;
+
+				&-active {
+					background: rgba(0, 0, 0, .1);
+				}
+			}
+		}
+
+		&-time {
+			width: $calendar-size - 80upx !important;
+			left: ((750upx - $calendar-size) / 2 + 40upx) !important;
+		}
+
+		&-modal {
+			background: #fff;
+			position: absolute;
+			top: 50%;
+			left: (750upx - $calendar-size) / 2;
+			width: $calendar-size;
+			transform: translateY(-50%);
+			box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.1);
+			border-radius: 12upx;
+			z-index: 999999;
+			&-header {
+				text-align: center;
+				line-height: 80upx;
+				font-size: 32upx;
+
+				&-title {
+					display: inline-block;
+					width: 40%;
+				}
+
+				.picker-icon {
+					display: inline-block;
+					line-height: 50upx;
+					width: 50upx;
+					height: 50upx;
+					border-radius: 50upx;
+					text-align: center;
+					margin: 10upx;
+					background: #fff;
+					font-size: 36upx;
+
+					&-active {
+						background: rgba(0, 0, 0, .1);
+					}
+				}
+			}
+
+			&-body {
+				width: $calendar-size !important;
+				height: $calendar-size !important;
+				position: relative;
+			}
+
+			&-time {
+				width: 100%;
+				height: 180upx;
+				text-align: center;
+				line-height: 60upx;
+			}
+
+			&-footer {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				padding: $cell-spacing;
+
+				&-info {
+					flex-grow: 1;
+				}
+
+				&-btn {
+					flex-shrink: 0;
+					display: flex;
+				}
+			}
+		}
+
+		&-calendar {
+			position: absolute;
+			left: 0;
+			top: 0;
+			width: 100%;
+			height: 100%;
+			display: flex;
+			align-items: center;
+			flex-wrap: wrap;
+
+			&-view {
+				position: relative;
+				width: $calendar-item-size;
+				height: $calendar-item-size;
+				text-align: center;
+
+				&-bgbegin,
+				&-bg,
+				&-bgend,
+				&-item,
+				&-dot,
+				&-tips {
+					position: absolute;
+					transition: .2s;
+				}
+
+				&-bgbegin,
+				&-bg,
+				&-bgend {
+					opacity: .15;
+					height: 80%;
+				}
+
+				&-bg {
+					left: 0;
+					top: 10%;
+					width: 100%;
+				}
+
+				&-bgbegin {
+					border-radius: $calendar-item-size 0 0 $calendar-item-size;
+					top: 10%;
+					left: 10%;
+					width: 90%;
+				}
+
+				&-bgend {
+					border-radius: 0 $calendar-item-size $calendar-item-size 0;
+					top: 10%;
+					left: 0%;
+					width: 90%;
+				}
+
+				&-item {
+					left: 5%;
+					top: 5%;
+					width: 90%;
+					height: 90%;
+					border-radius: $calendar-item-size;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+
+				&-dot {
+					right: 10%;
+					top: 10%;
+					width: 12upx;
+					height: 12upx;
+					border-radius: 12upx;
+				}
+
+				&-tips {
+					bottom: 100%;
+					left: 50%;
+					transform: translateX(-50%);
+					background: #4E4B46;
+					color: #fff;
+					border-radius: 12upx;
+					padding: 10upx 20upx;
+					font-size: 24upx;
+					width: max-content;
+					margin-bottom: 5px;
+					pointer-events: none;
+
+					&:after {
+						content: "";
+						position: absolute;
+						top: 100%;
+						left: 50%;
+						transform: translateX(-50%);
+						width: 0;
+						height: 0;
+						border-style: solid;
+						border-width: 5px 5px 0 5px;
+						border-color: #4E4B46 transparent transparent transparent;
+					}
+				}
+			}
+		}
+	}
+
+	@font-face {
+		font-family: "mxdatepickericon";
+		src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAMYAAsAAAAACBgAAALMAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDIgqDRIJiATYCJAMUCwwABCAFhG0HSRvfBsg+QCa3noNAyAQ9w6GDvbwpNp2vloCyn8bD/x+y+/5qDhtj+T4eRVEcbsCoKMFASzCgLdDkmqYDwgxkWQ6YH5L/YnppOlLEjlnter43YRjU7M6vJ3iGADVAgJn5kqjv/wEii23T86UsAQT+04fV+o97VTMx4PPZt4DlorLXwIQiGMA5uhaVrBWqGHfQXcTEiE+PE+g2SUlxWlLVBHwUYFMgrgwSB3wstTKSGzqF1nOyiGeeOtNjV4An/vvxR58PSc3AzrMViyDvPo/7dVEUzn5GROfIWAcU4rLXfMFdhte56y4We9gGNEVIezkBOOaQXUrbTf/hJVkhGpDdCw7dSOEzByMEn3kIic98hMxnAfeFPKWCbjRcA148/HxhCEkaA94eGWFaGolsblpaWz8/Po2WVuNHh1fmBpZHIpqal9fOjizhTteY+RZ9rv02I/pq0W6QVH3pSncBz3m55r9ZIPycHfmenvxe4uyutIgfT5u4bgkDusl9gcF0rnfnz+b2NpSaQWBFeu8GIL1xQj5AH/6FAsEr/50F28e/gA9ny6KjLrxIp0TE+UucmQOl5AFNLXkzZufWamWHYEI39PEP2If97CMdm51N6DSmIekwAVmneXTBr0PVYx+aTgfQbU3p+R4jKHdRurBq0oEw6AKSfm+QDbpGF/w3VOP+oBnMHbqdx409FjP4RRHHkAj5IWgQiBUjHfMTuQ1Icpg5avI4sQVRu8EHdWptM1aKrIjuscfeL+kZwxBTYoElztOQ2UygjRIjEphaZsyWodHgvm9SC8QC/JygEA6DiCDeEMhAQFhhOpvxa/18A0TiYMahIy0L2hYIZWeYH9JR085Al4qts1re5St2/SR6DINBGEVYQCWOETHDMAHZ+pcZIQJGTV4RtMmg8UbhuWL1+VLLA2RFHYC71kiRo0SNpjwQh8pj2EFU3oTNmS1WqgIA') format('woff2');
+	}
+
+	.picker-icon {
+		font-family: "mxdatepickericon" !important;
+	}
+
+	.picker-icon-you:before {
+		content: "\e63e";
+	}
+
+	.picker-icon-zuo:before {
+		content: "\e640";
+	}
+
+	.picker-icon-zuozuo:before {
+		content: "\e641";
+	}
+
+	.picker-icon-youyou:before {
+		content: "\e642";
+	}
+</style>

+ 6 - 0
pages.json

@@ -106,6 +106,12 @@
 		    	"navigationBarTitleText": "预览"
 		    }
 		},
+		{
+		    "path" : "pages/shopTourDetails/shopTourDetails",  //  现场巡店-巡店详情
+		    "style" : {
+				"navigationBarTitleText": "巡店详情"
+			}
+		},
 		{
 		    "path" : "pages/spotCheckConfigure/spotCheckList",
 		    "style": {

+ 344 - 74
pages/myShopTour/myShopTour.vue

@@ -8,7 +8,7 @@
 				</view>
 				<view class="left-icon">我的巡店</view>
 				<view class="right-icon">
-					<u-icon name="more-dot-fill" color="#fff" size="28"></u-icon>
+					<u-icon name="more-dot-fill" color="#fff" size="28" @click="openScreen=true"></u-icon>
 				</view>
 			</view>
 		</u-navbar>
@@ -19,8 +19,42 @@
 				<swiper-item class="swiper-item" v-for="(tabs, index) in tabList" :key="index">
 					<scroll-view scroll-y class="scroll-con" @scrolltolower="onreachBottom">
 						<view class="record-con">
-							<view class="record-item">
-								<view class="item-head"></view>
+							<view v-show="searchForm.creatTime.length != 0" class="alert-tips">{{searchForm.creatTime[0]}} ~ {{searchForm.creatTime[1]}}</view>
+							<view class="record-item" v-for="(item,index) in list" :key="index">
+								<view class="item-head">
+									<text class="item-c-tit">{{item.name}}</text>
+									<u-tag class="item-c-type" :text="item.orderStatus" type="primary" />
+								</view>
+								<view class="item-main">
+									<text class="item-tit">创建时间:</text>
+									<text class="item-val">{{item.creatTime}}</text>
+								</view>
+								<view class="item-main">
+									<text class="item-tit">完成时间:</text>
+									<text class="item-val">{{item.completionTime}}</text>
+								</view>
+								<view class="item-main">
+									<text class="item-tit">巡店耗时:</text>
+									<text class="item-val">{{item.timeConsuming}}</text>
+								</view>
+								<u-grid class="item-grid" :col="4" hover-class="none">
+									<u-grid-item>
+										<text class="grid-num text-blue">18</text>
+										<text class="grid-text">检查项</text>
+									</u-grid-item>
+									<u-grid-item>
+										<text class="grid-num text-green">13</text>
+										<text class="grid-text">合格</text>
+									</u-grid-item>
+									<u-grid-item>
+										<text class="grid-num text-red">3</text>
+										<text class="grid-text">不合格</text>
+									</u-grid-item>
+									<u-grid-item>
+										<text class="grid-num text-yellow">2</text>
+										<text class="grid-text">不适用</text>
+									</u-grid-item>
+								</u-grid>
 							</view>
 						</view>
 						<u-empty text="暂无数据" img-width="120" v-if="list.length == 0 && status != 'loading'" mode="list"></u-empty>
@@ -29,85 +63,205 @@
 				</swiper-item>
 			</swiper>
 		</view>
+		<!-- 筛选弹框 -->
+		<u-popup v-model="openScreen" mode="right" length="60%" class="screenModel-wrap">
+			<!-- 条件项 -->
+			<view class="condition-con">
+				<view class="condition-item">
+					<text class="condition-tit">创建时间</text>
+					<view class="condition-val">
+						<text @click="onShowDatePicker('range')">{{range[0] ? range[0] : '请选择'}} ~ {{range[1] ? range[1] : '请选择'}}</text>
+						<u-icon v-show="range.length != 0" name="close-circle" color="#999" size="28" class="close-circle" @click="range=[]"></u-icon>
+					</view>
+				</view>
+				<view class="condition-item">
+					<text class="condition-tit">门店</text>
+					<view class="condition-val">
+						<text @click="openStore=!openStore">{{storeName ? storeName : '全部'}}</text>
+						<u-icon v-show="storeName" name="close-circle" color="#999" size="28" class="close-circle" @click="clearStore"></u-icon>
+					</view>
+				</view>
+			</view>
+			<!-- 按钮 -->
+			<view class="btns">
+				<u-button type="warning" shape="circle" size="mini" class="btn reset-btn" @click="resetF">重置</u-button>
+				<u-button type="error" shape="circle" size="mini" class="btn ok-btn" @click="submitF">确定</u-button>
+			</view>
+		</u-popup>
+		<!-- 选择创建时间 -->
+		<mx-date-picker class="choose-date-wrap" :show="showPicker" :type="type" :value="searchForm.creatTime" :show-tips="true" :begin-text="'开始'" :end-text="'结束'" :show-seconds="true" @confirm="onSelected" @cancel="onSelected" />
+		<!-- 选择门店 -->
+		<u-select v-model="openStore" :default-value="defaultStoreValue" :list="storeList" @confirm="confirmStore" class="choose-store-wrap"></u-select>
 	</view>
 </template>
 
 <script>
-export default {
-	data() {
-		return {
-			background: {
-				// 渐变色
-				backgroundImage: 'linear-gradient(45deg, rgb(85, 170, 255), rgb(21, 102, 223))'
-			},
-			tabList: [  //  tab切换  类型
-				{ dispName: '全部', code:'' },
-				{ dispName: '进行中', code:'1' },
-				{ dispName: '已完成', code:'2' },
-				{ dispName: '已过期', code:'3' }
-			],
-			current: 0,  //  tabs组件的current值,表示当前活动的tab选项
-			swiperCurrent: 0,  //  swiper组件的current值,表示当前那个swiper-item是活动的
-			pageNo: 1,  //  当前页码
-			pageSize: 15,  //  一页多少条
-			total: 0,  //  总条数
-			// status: 'loading',  //  加载状态
-			status: 'loadmore',  //  加载状态
-			noDataText: '暂无数据',  //  列表数据为空时提示文字
-			list: [],  //  数据列表
-		}
-	},
-	onLoad() {
-		this.pageInit()
-	},
-	methods: {
-		//  返回
-		goBack() {
-			uni.navigateBack({
-				delta: 1
-			});
-		},
-		pageInit(){
-			this.total = 0
-			this.pageNo = 1
-		},
-		// tabs通知swiper切换
-		tabsChange(index) {
-			this.swiperCurrent = index
-			this.list = []
-			this.status = "loading"
-		},
-		swiperChange(event){
-			this.list = []
-			this.status = "loading"
-		},
-		// swiper-item左右移动,通知tabs的滑块跟随移动
-		transition(e) {
-			let dx = e.detail.dx;
-			this.$refs.uTabs.setDx(dx);
-		},
-		// 由于swiper的内部机制问题,快速切换swiper不会触发dx的连续变化,需要在结束时重置状态
-		// swiper滑动结束,分别设置tabs和swiper的状态
-		animationfinish(e) {
-			let current = e.detail.current
-			if(current != this.current){
-				this.$refs.uTabs.setFinishCurrent(current)
-				this.swiperCurrent = current
-				this.current = current
-				this.pageInit()
+	import MxDatePicker from "@/components/mx-datepicker/mx-datepicker.vue"
+	export default {
+		components: { MxDatePicker },
+		data() {
+			return {
+				background: {
+					// 渐变色
+					backgroundImage: 'linear-gradient(45deg, rgb(85, 170, 255), rgb(21, 102, 223))'
+				},
+				tabList: [  //  tab切换  类型
+					{ dispName: '全部', code:'' },
+					{ dispName: '进行中', code:'1' },
+					{ dispName: '已完成', code:'2' },
+					{ dispName: '已过期', code:'3' }
+				],
+				current: 0,  //  tabs组件的current值,表示当前活动的tab选项
+				swiperCurrent: 0,  //  swiper组件的current值,表示当前那个swiper-item是活动的
+				pageNo: 1,  //  当前页码
+				pageSize: 15,  //  一页多少条
+				total: 0,  //  总条数
+				// status: 'loading',  //  加载状态
+				status: 'loadmore',  //  加载状态
+				noDataText: '暂无数据',  //  列表数据为空时提示文字
+				list: [  //  数据列表
+					{ name: '常青二店', creatTime: '2020-09-08 09:16', orderStatus: 'haveInHand', completionTime: '2020-09-08 09:16', timeConsuming: '5小时18分钟', inspectionItems: 18, qualified: 14, unqualified: 2, notApplicable: 2 },
+					{ name: '常青二店', creatTime: '2020-09-08 09:16', orderStatus: 'invalid', completionTime: '2020-09-08 09:16', timeConsuming: '5小时18分钟', inspectionItems: 18, qualified: 14, unqualified: 2, notApplicable: 2 },
+					{ name: '常青二店', creatTime: '2020-09-08 09:16', orderStatus: 'haveInHand', completionTime: '2020-09-08 09:16', timeConsuming: '5小时18分钟', inspectionItems: 18, qualified: 14, unqualified: 2, notApplicable: 2 },
+					{ name: '常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店常青二店', creatTime: '2020-09-08 09:16', orderStatus: 'completed', completionTime: '2020-09-08 09:16', timeConsuming: '5小时18分钟', inspectionItems: 18, qualified: 14, unqualified: 2, notApplicable: 2 },
+					{ name: '常青二店', creatTime: '2020-09-08 09:16', orderStatus: 'completed', completionTime: '2020-09-08 09:16', timeConsuming: '5小时18分钟', inspectionItems: 18, qualified: 14, unqualified: 2, notApplicable: 2 },
+				],
+				openScreen: false,  //  是否打开筛选
+				dateMode: 'range',  //  date单个日期  range日期范围
+				searchForm: {  //  查询条件
+					creatTime: [],  //  创建时间默认筛选近7天
+					store: ''
+				},
+				openStore: false,  // 选择门店
+				storeList: [
+					{ value: '1', label: '江' },
+					{ value: '2', label: '河' }
+				],
+				showPicker: false,  //  是否选择创建时间
+				range: [],  //  筛选创建时间的默认值
+				type: 'range',  //  日期时间类型
+				storeName: '',  //  筛选门店名称
+				defaultStoreValue: [],  //  门店默认选中下标
 			}
 		},
-		// scroll-view到底部加载更多
-		onreachBottom() {
-			if(this.list.length < this.total){
-				this.pageNo += 1
-				this.pageInit()
-			}else{
-				this.status = "nomore"
-			}
+		onLoad() {
+			this.pageInit()
 		},
+		methods: {
+			//  返回
+			goBack() {
+				uni.navigateBack({
+					delta: 1
+				});
+			},
+			pageInit(){
+				this.range = [ this.get7day(-6), this.get7day(0) ]
+				this.searchForm.creatTime = [ this.get7day(-6), this.get7day(0) ]
+				this.total = 0
+				this.pageNo = 1
+			},
+			// tabs通知swiper切换
+			tabsChange(index) {
+				this.swiperCurrent = index
+				this.list = []
+				this.status = "loading"
+			},
+			swiperChange(event){
+				this.list = []
+				this.status = "loading"
+			},
+			// swiper-item左右移动,通知tabs的滑块跟随移动
+			transition(e) {
+				let dx = e.detail.dx;
+				this.$refs.uTabs.setDx(dx);
+			},
+			// 由于swiper的内部机制问题,快速切换swiper不会触发dx的连续变化,需要在结束时重置状态
+			// swiper滑动结束,分别设置tabs和swiper的状态
+			animationfinish(e) {
+				let current = e.detail.current
+				if(current != this.current){
+					this.$refs.uTabs.setFinishCurrent(current)
+					this.swiperCurrent = current
+					this.current = current
+					this.pageInit()
+				}
+			},
+			// scroll-view到底部加载更多
+			onreachBottom() {
+				if(this.list.length < this.total){
+					this.pageNo += 1
+					this.pageInit()
+				}else{
+					this.status = "nomore"
+				}
+			},
+			//  显示日期选择
+			onShowDatePicker(type){
+				this.type = type
+				this.showPicker = true
+				this.searchForm.creatTime = this[type]
+			},
+			//  日期选择
+			onSelected(e) {
+				this.showPicker = false
+				if(e) {
+					this[this.type] = e.value
+				}
+			},
+			//  获取近几天的数据
+			get7day(day){
+				let today = new Date()
+				let targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day
+				today.setTime(targetday_milliseconds)  //注意,这行是关键代码
+				let tYear = today.getFullYear()
+				let tMonth = today.getMonth()
+				let tDate = today.getDate()
+				tMonth = this.doHandleMonth(tMonth + 1)
+				tDate = this.doHandleMonth(tDate)
+				return tYear + "-" + tMonth + "-" + tDate
+			},
+			//  月份
+			doHandleMonth(month){
+			    let m = month
+			    if(month.toString().length == 1){
+					m = "0" + month
+			    }
+			    return m
+			},
+			//  选择门店
+			confirmStore(e){
+				this.storeName = e[0].label
+				this.defaultStoreValue = [this.storeList.findIndex(item => item.value == e[0].value)]
+			},
+			//  情空  筛选门店
+			clearStore(){
+				this.storeName = ''
+				this.defaultStoreValue = []
+			},
+			//  重置筛选条件
+			resetF(){
+				this.range = this.searchForm.creatTime
+				let ind = [this.storeList.findIndex(item => item.value == this.searchForm.store)]
+				if(ind == -1){
+					this.defaultStoreValue = []
+					this.storeName = ''
+				}else{
+					this.defaultStoreValue = [ind]
+					this.storeName = this.storeList[ind].label
+				}
+			},
+			//  确定筛选
+			submitF(){
+				this.searchForm.creatTime = this.range
+				if(this.storeName){
+					this.searchForm.store = this.storeList[this.defaultStoreValue[0]].value
+				}else{
+					this.searchForm.store = ''
+				}
+				this.openScreen = false
+			},
+		}
 	}
-};
 </script>
 
 <style lang="scss" scoped>
@@ -147,6 +301,76 @@ page {
 			.swiper-item{
 				.scroll-con{
 					height: 100%;
+					// 列表
+					.record-con{
+						.alert-tips{
+							font-size: 24upx;
+							padding: 4upx 10upx;
+							margin: 20upx 30upx 10upx;
+							border: 1upx solid #fcbd71;
+							background-color: #fdf6ec;
+							border-radius: 6upx;
+						}
+						.record-item{
+							background-color: #fff;
+							margin: 20upx 30upx 20upx;
+							padding: 14upx 30upx 20upx;
+							border-radius: 12upx;
+							.item-head{
+								display: flex;
+								justify-content: space-between;
+								align-items: center;
+								padding: 10upx 0;
+								.item-c-tit{
+									flex-grow: 1;
+									padding-right: 18upx;
+									font-weight: bold;
+								}
+								.item-c-type{
+									flex-shrink: 0;
+								}
+							}
+							.item-main{
+								font-size: 26upx;
+								line-height: 48upx;
+								padding: 6upx 0;
+								position: relative;
+								.item-tit{
+									display: inline-block;
+									position: absolute;
+									left: 0;
+									top: 10upx;
+								}
+								.item-val{
+									display: inline-block;
+									padding-left: 150upx;
+								}
+							}
+							.item-grid{
+								margin-top: 10upx;
+								.text-blue{
+									color: #2979ff;
+								}
+								.text-green{
+									color: #19be6b;
+								}
+								.text-red{
+									color: #fa3534;
+								}
+								.text-yellow{
+									color: #ff9900;
+								}
+								.grid-num{
+									font-weight: bold;
+								}
+								.grid-text{
+									font-size: 26upx;
+									padding-top: 10upx;
+									color: #666;
+								}
+							}
+						}
+					}
 					.loadmore{
 						padding: 30upx;
 					}
@@ -154,5 +378,51 @@ page {
 			}
 		}
 	}
+	.screenModel-wrap{
+		padding-bottom: 80upx;
+		.condition-con{
+			padding: 20upx 30upx;
+			.condition-item{
+				.condition-tit{
+					display: block;
+					font-size: 26upx;
+					margin: 20upx 0;
+				}
+				.condition-val{
+					display: block;
+					font-size: 24upx;
+					background-color: #f4f4f4;
+					border-radius: 12upx;
+					padding: 10upx 14upx;
+					margin: 10upx 0;
+					text-align: center;
+					text{
+						display: inline-block;
+						width: 85%;
+					}
+					.close-circle{
+						display: inline-block;
+						padding-left: 3%;
+						vertical-align: bottom;
+					}
+				}
+			}
+		}
+		.btns{
+			position: fixed;
+			bottom: 0;
+			left: 0;
+			width: 100%;
+			background-color: rgba(0,0,0,.025);
+			.btn{
+				width: 40%;
+				margin: 20upx 5%;
+				padding: 30upx 0;
+			}
+		}
+	}
+	.choose-date-wrap{
+		z-index: 999999;
+	}
 }
 </style>

+ 9 - 2
pages/shopTourCompleted/shopTourCompleted.vue

@@ -24,7 +24,7 @@
 				</view>
 			</view>
 			<view class="inspection-items">
-				<u-grid :col="4" :hover-class="none">
+				<u-grid :col="4" hover-class="none">
 					<u-grid-item>
 						<text class="grid-num text-blue">18</text>
 						<text class="grid-text">检查项</text>
@@ -45,7 +45,7 @@
 			</view>
 		</view>
 		<view class="btn-con">
-			<u-button type="primary" shape="circle" class="btn">查看明细</u-button>
+			<u-button type="primary" shape="circle" class="btn" @click="goShopTourDetails">查看明细</u-button>
 			<u-button shape="circle" class="btn" @click="goMyShopTour">我的巡店记录</u-button>
 		</view>
 	</view>
@@ -59,10 +59,17 @@
 			}
 		},
 		methods: {
+			//  我的巡店记录
 			goMyShopTour(){
 				uni.navigateTo({
 					url: '/pages/myShopTour/myShopTour'
 				})
+			},
+			// 查看明细
+			goShopTourDetails(){
+				uni.navigateTo({
+					url: '/pages/shopTourDetails/shopTourDetails'
+				})
 			}
 		}
 	}

+ 50 - 0
pages/shopTourDetails/shopTourDetails.vue

@@ -0,0 +1,50 @@
+<template>
+	<view class="shopTourDetails-wrap">
+		<scroll-view scroll-y class="scroll-con-l">
+			432
+		</scroll-view>
+		<scroll-view scroll-y class="scroll-con-r" @scrolltolower="onreachBottom">
+			24
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	export default{
+		data(){
+			return{
+				
+			}
+		},
+		methods: {
+			// scroll-view到底部加载更多
+			onreachBottom() {
+				// if(this.list.length < this.total){
+				// 	this.pageNo += 1
+				// 	this.pageInit()
+				// }else{
+				// 	this.status = "nomore"
+				// }
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	page {
+		height: calc(100vh - 56px);
+	}
+	.shopTourDetails-wrap{
+		height: 100%;
+		.scroll-con-l{
+			display: inline-block;
+			width: 30%;
+			height: 100%;
+		}
+		.scroll-con-r{
+			display: inline-block;
+			width: 70%;
+			height: 100%;
+		}
+	}
+</style>