|
@@ -0,0 +1,458 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="time-filter">
|
|
|
|
+ <div class="filter-top">
|
|
|
|
+ <div class="all-button-box">
|
|
|
|
+ <button
|
|
|
|
+ v-for="(item, i) in time"
|
|
|
|
+ :key="i" @click="selecteTime(item)"
|
|
|
|
+ class="j-button j-button-select"
|
|
|
|
+ :class="item.selected ? 'active' : ''"
|
|
|
|
+ >{{ item.name }}</button>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="time-box">
|
|
|
|
+ <div class="time" :class="accurateTimeSelected ? 'active' : ''" @click="accurateTimeSelected = true">
|
|
|
|
+ <div class="start-time">
|
|
|
|
+ <div><input class="moneyiptval" type="text"><span style="margin-right:10px">万元</span></div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="end-time">
|
|
|
|
+ <div><input class="moneyiptval" type="text"><span style="margin-right:10px">万元</span></div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="j-button-group bottom-btns">
|
|
|
|
+ <button class="j-button-cancel" @click="resetTime">重置</button>
|
|
|
|
+ <button class="j-button-confirm" @click="onConfirm">确认</button>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 设置起始时间 -->
|
|
|
|
+ <van-popup
|
|
|
|
+ v-model="startTimeOptions.show" round
|
|
|
|
+ get-container="body"
|
|
|
|
+ position="bottom"
|
|
|
|
+ class="date-time-picker-popup">
|
|
|
|
+ <div class="pop-header r-c-box">
|
|
|
|
+ <span class="title-span">{{ startTimeOptions.title }}</span>
|
|
|
|
+ <span class="j-icon icon-del-grey" @click.stop="startTimeOptions.show = false"></span>
|
|
|
|
+ </div>
|
|
|
|
+ <van-datetime-picker
|
|
|
|
+ v-model="startTimeOptions.value"
|
|
|
|
+ ref="startDatePicker"
|
|
|
|
+ type="date"
|
|
|
|
+ :show-toolbar="false"
|
|
|
|
+ :formatter="formatterYMD"
|
|
|
|
+ :min-date="startTimeOptions.minDate"
|
|
|
|
+ :max-date="startTimeOptions.maxDate"
|
|
|
|
+ swipe-duration="60"
|
|
|
|
+ @change="pickerChange($event, 'start')" />
|
|
|
|
+ <div class="pop-footer j-button-group">
|
|
|
|
+ <button class="j-button-cancel" @click.stop="pickerReset('start')">重置</button>
|
|
|
|
+ <button class="j-button-confirm" @click.stop="pickerConfirm('start')">确定</button>
|
|
|
|
+ </div>
|
|
|
|
+ </van-popup>
|
|
|
|
+ <!-- 设置结束时间 -->
|
|
|
|
+ <van-popup
|
|
|
|
+ v-model="endTimeOptions.show" round
|
|
|
|
+ get-container="body"
|
|
|
|
+ position="bottom"
|
|
|
|
+ class="date-time-picker-popup">
|
|
|
|
+ <div class="pop-header r-c-box">
|
|
|
|
+ <span class="title-span">{{ endTimeOptions.title }}</span>
|
|
|
|
+ <span class="j-icon icon-del-grey" @click.stop="endTimeOptions.show = false"></span>
|
|
|
|
+ </div>
|
|
|
|
+ <van-datetime-picker
|
|
|
|
+ v-model="endTimeOptions.value"
|
|
|
|
+ ref="startDatePicker"
|
|
|
|
+ type="date"
|
|
|
|
+ :show-toolbar="false"
|
|
|
|
+ :formatter="formatterYMD"
|
|
|
|
+ :min-date="endTimeOptions.minDate"
|
|
|
|
+ :max-date="endTimeOptions.maxDate"
|
|
|
|
+ swipe-duration="60"
|
|
|
|
+ @change="pickerChange($event, 'end')" />
|
|
|
|
+ <div class="pop-footer j-button-group">
|
|
|
|
+ <button class="j-button-cancel" @click.stop="pickerReset('end')">重置</button>
|
|
|
|
+ <button class="j-button-confirm" @click.stop="pickerConfirm('end')">确定</button>
|
|
|
|
+ </div>
|
|
|
|
+ </van-popup>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script lang="ts">
|
|
|
|
+import { Component, Vue, Watch, Prop } from 'vue-property-decorator'
|
|
|
|
+import { DatetimePicker, Popup } from 'vant'
|
|
|
|
+
|
|
|
|
+// @ is an alias to /src
|
|
|
|
+@Component({
|
|
|
|
+ name: 'date-filter',
|
|
|
|
+ components: {
|
|
|
|
+ [DatetimePicker.name]: DatetimePicker,
|
|
|
|
+ [Popup.name]: Popup
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+export default class TimeFilterPicker extends Vue {
|
|
|
|
+ @Prop() recover: any | undefined;
|
|
|
|
+
|
|
|
|
+ accurateTimeSelected = false
|
|
|
|
+ startTime: any = 0
|
|
|
|
+ endTime: any = 0
|
|
|
|
+
|
|
|
|
+ startTimeOptions = {
|
|
|
|
+ value: new Date(),
|
|
|
|
+ show: false,
|
|
|
|
+ title: '选择起始时间',
|
|
|
|
+ // 10年前
|
|
|
|
+ minDate: new Date('2015-01-01'),
|
|
|
|
+ // 2年后
|
|
|
|
+ maxDate: new Date(+new Date() + 61633290485)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ endTimeOptions = {
|
|
|
|
+ value: new Date(),
|
|
|
|
+ show: false,
|
|
|
|
+ title: '选择结束时间',
|
|
|
|
+ minDate: new Date('2015-01-01'),
|
|
|
|
+ maxDate: new Date(+new Date() + 61633290485)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ time = [
|
|
|
|
+ { name: '全部', value: '', selected: true }
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ @Watch('accurateTimeSelected')
|
|
|
|
+ onAccurateTimeSelectedChange (newVal) {
|
|
|
|
+ if (newVal) {
|
|
|
|
+ this.time.forEach(item => {
|
|
|
|
+ item.selected = false
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ created () {
|
|
|
|
+ this.recoverTime()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ selecteTime (item) {
|
|
|
|
+ // 点击的时候如果是被选中的,则让全部选中
|
|
|
|
+ if (item.selected) {
|
|
|
|
+ this.time.forEach(item => {
|
|
|
|
+ if (item.name === '全部') {
|
|
|
|
+ item.selected = true
|
|
|
|
+ } else {
|
|
|
|
+ item.selected = false
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ } else {
|
|
|
|
+ this.time.forEach(item => {
|
|
|
|
+ item.selected = false
|
|
|
|
+ })
|
|
|
|
+ item.selected = true
|
|
|
|
+ }
|
|
|
|
+ this.accurateTimeSelected = false
|
|
|
|
+ this.onChange()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ formatterYMD (type, value) {
|
|
|
|
+ if (type === 'year') {
|
|
|
|
+ return `${value}年`
|
|
|
|
+ } else if (type === 'month') {
|
|
|
|
+ return `${value}月`
|
|
|
|
+ } else if (type === 'day') {
|
|
|
|
+ return `${value}日`
|
|
|
|
+ }
|
|
|
|
+ return value
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ showTimePicker (which) {
|
|
|
|
+ this.accurateTimeSelected = true
|
|
|
|
+ if (which === 'start') {
|
|
|
|
+ this.startTimeOptions.show = true
|
|
|
|
+ } else if (which === 'end') {
|
|
|
|
+ this.endTimeOptions.show = true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pickerChange (picker, which) {
|
|
|
|
+ if (which === 'start') {
|
|
|
|
+ // this.startTimeOptions.show = true
|
|
|
|
+ } else if (which === 'end') {
|
|
|
|
+ // this.endTimeOptions.show = true
|
|
|
|
+ }
|
|
|
|
+ // console.log(picker.getValues())
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pickerReset (which) {
|
|
|
|
+ if (which === 'start') {
|
|
|
|
+ this.startTimeOptions.show = false
|
|
|
|
+ this.startTime = 0
|
|
|
|
+ } else if (which === 'end') {
|
|
|
|
+ this.endTimeOptions.show = false
|
|
|
|
+ this.endTime = 0
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pickerConfirm (which) {
|
|
|
|
+ // 判断是哪个picker提交的
|
|
|
|
+ if (which === 'start') {
|
|
|
|
+ // 动态设置endPicker的起始范围
|
|
|
|
+ this.startTime = this.startTimeOptions.value
|
|
|
|
+ this.endTimeOptions.minDate = (this.startTime) as any
|
|
|
|
+ this.startTimeOptions.show = false
|
|
|
|
+ } else if (which === 'end') {
|
|
|
|
+ this.endTime = this.endTimeOptions.value
|
|
|
|
+ this.startTimeOptions.maxDate = (this.endTime) as any
|
|
|
|
+ this.endTimeOptions.show = false
|
|
|
|
+ }
|
|
|
|
+ this.onChange()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 重置所有时间
|
|
|
|
+ resetTime () {
|
|
|
|
+ this.time.forEach(item => {
|
|
|
|
+ item.selected = false
|
|
|
|
+ })
|
|
|
|
+ this.accurateTimeSelected = false
|
|
|
|
+ this.time[0].selected = true
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ onConfirm () {
|
|
|
|
+ // 整理并获取时间
|
|
|
|
+ this.$emit('onConfirm', this.getResult())
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ onChange () {
|
|
|
|
+ // 整理并获取时间
|
|
|
|
+ this.$emit('onChange', this.getResult())
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 将ms级时间戳转为m级时间戳
|
|
|
|
+ getSecondsStamp (stamp) {
|
|
|
|
+ return stamp.toString().substr(0, 10) - 0
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getResult () {
|
|
|
|
+ if (this.accurateTimeSelected) {
|
|
|
|
+ return {
|
|
|
|
+ startTime: this.startTime === 0 ? this.startTime : +new Date(this.startTime) / 1000,
|
|
|
|
+ endTime: this.endTime === 0 ? this.endTime : +new Date(this.endTime) / 1000 + (24 * 60 * 60 - 1),
|
|
|
|
+ accurate: true,
|
|
|
|
+ options: {
|
|
|
|
+ start: this.optionsDataToJSON(this.startTimeOptions),
|
|
|
|
+ end: this.optionsDataToJSON(this.endTimeOptions)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ const current = this.time.filter(function (item) {
|
|
|
|
+ return item.selected
|
|
|
|
+ })[0]
|
|
|
|
+
|
|
|
|
+ const temp = {
|
|
|
|
+ value: current,
|
|
|
|
+ accurate: false,
|
|
|
|
+ options: {
|
|
|
|
+ start: this.optionsDataToJSON(this.startTimeOptions),
|
|
|
|
+ end: this.optionsDataToJSON(this.endTimeOptions)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (current.duration) {
|
|
|
|
+ if (current.duration === -1) {
|
|
|
|
+ // 最近7天和最近30天
|
|
|
|
+ // 先获取当前时间的年份
|
|
|
|
+ const thisYear = new Date().getFullYear()
|
|
|
|
+ ;(temp as any).startTime = this.getSecondsStamp(+new Date(`${thisYear - 1}/01/01`))
|
|
|
|
+ ;(temp as any).endTime = this.getSecondsStamp(+new Date(`${thisYear}/01/01`))
|
|
|
|
+ } else {
|
|
|
|
+ ;(temp as any).startTime = this.getSecondsStamp(+new Date() - current.duration)
|
|
|
|
+ ;(temp as any).endTime = this.getSecondsStamp(+new Date())
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return temp
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ optionsDataToJSON (d: any) {
|
|
|
|
+ const temp = {
|
|
|
|
+ value: new Date(),
|
|
|
|
+ show: false,
|
|
|
|
+ title: '选择时间',
|
|
|
|
+ minDate: new Date('2015-01-01'),
|
|
|
|
+ maxDate: new Date()
|
|
|
|
+ }
|
|
|
|
+ temp.value = d.value.getTime()
|
|
|
|
+ temp.show = d.show
|
|
|
|
+ temp.title = d.title
|
|
|
|
+ temp.minDate = d.minDate.getTime()
|
|
|
|
+ temp.maxDate = d.maxDate.getTime()
|
|
|
|
+ return temp
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ optionsJSONToData (j: any) {
|
|
|
|
+ const temp = {
|
|
|
|
+ value: new Date(),
|
|
|
|
+ show: false,
|
|
|
|
+ title: '选择时间',
|
|
|
|
+ minDate: new Date('2015-01-01'),
|
|
|
|
+ maxDate: new Date()
|
|
|
|
+ }
|
|
|
|
+ temp.value = new Date(j.value)
|
|
|
|
+ temp.show = j.show
|
|
|
|
+ temp.title = j.title
|
|
|
|
+ temp.minDate = new Date(j.minDate)
|
|
|
|
+ temp.maxDate = new Date(j.maxDate)
|
|
|
|
+ return temp
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ recoverTime () {
|
|
|
|
+ const r = this.recover
|
|
|
|
+ if (!r) return
|
|
|
|
+ if (Object.keys(r).length === 0) return
|
|
|
|
+ if (r.accurate) {
|
|
|
|
+ this.accurateTimeSelected = true
|
|
|
|
+ this.setPickerTime(r)
|
|
|
|
+ } else {
|
|
|
|
+ this.accurateTimeSelected = false
|
|
|
|
+ this.time.forEach((item: any) => {
|
|
|
|
+ if (r.value.name === item.name) {
|
|
|
|
+ item.selected = true
|
|
|
|
+ } else {
|
|
|
|
+ item.selected = false
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ setPickerTime (r: any) {
|
|
|
|
+ console.log(r)
|
|
|
|
+ // 恢复视图
|
|
|
|
+ this.startTime = r.startTime === 0 ? 0 : new Date(r.startTime * 1000)
|
|
|
|
+ this.endTime = r.endTime === 0 ? 0 : new Date(r.endTime * 1000)
|
|
|
|
+
|
|
|
|
+ // 恢复pickerOptions
|
|
|
|
+ this.startTimeOptions = this.optionsJSONToData(r.options.start)
|
|
|
|
+ this.endTimeOptions = this.optionsJSONToData(r.options.end)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.time-filter {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ padding: 0 15px;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ min-height: 45vh;
|
|
|
|
+ .all-button-box {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ height: 68px;
|
|
|
|
+ }
|
|
|
|
+ .time-box {
|
|
|
|
+ .time-title {
|
|
|
|
+ margin-bottom: 5px;
|
|
|
|
+ color: #686868;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ }
|
|
|
|
+ .time {
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ position: relative;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ padding: 8px;
|
|
|
|
+ height: 52px;
|
|
|
|
+ background-color: #F4F4F9;
|
|
|
|
+ &::before {
|
|
|
|
+ content: '';
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 50%;
|
|
|
|
+ left: 50%;
|
|
|
|
+ width: 13px;
|
|
|
|
+ height: 1px; /* no */
|
|
|
|
+ background-color: #727273;
|
|
|
|
+ transform: translate(-50%,-50%);
|
|
|
|
+ }
|
|
|
|
+ .start-time,
|
|
|
|
+ .end-time {
|
|
|
|
+ position: relative;
|
|
|
|
+ width: 50%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ div {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ width: 90%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ border-radius: 4px;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ .moneyiptval{
|
|
|
|
+ width: 100%;
|
|
|
|
+ flex: 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .end-time {
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: flex-end;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .bottom-btns {
|
|
|
|
+ padding-left: 0;
|
|
|
|
+ padding-right: 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.date-time-picker-popup {
|
|
|
|
+ .pop-header {
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ padding: 0 16px;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ height: 64px;
|
|
|
|
+ .title-span {
|
|
|
|
+ min-width: 80px;
|
|
|
|
+ }
|
|
|
|
+ i {
|
|
|
|
+ text-align: right;
|
|
|
|
+ color: #C0C4CC;
|
|
|
|
+ &::before {
|
|
|
|
+ background: #C0C4CC;
|
|
|
|
+ color: white;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .hight-span {
|
|
|
|
+ flex: 1;
|
|
|
|
+ color: #2ABED1;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ }
|
|
|
|
+ .title-span {
|
|
|
|
+ color: #171826;
|
|
|
|
+ font-size: 20px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .pop-footer {}
|
|
|
|
+ .r-c-box {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: row;
|
|
|
|
+ align-items: center;
|
|
|
|
+ }
|
|
|
|
+ .van-picker__frame {
|
|
|
|
+ background: rgba(42, 190, 209, 0.05);
|
|
|
|
+ &::after, &::before {
|
|
|
|
+ border: none;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .van-picker-column__item--selected {
|
|
|
|
+ color: #2ABED1;
|
|
|
|
+ font-size: 20px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|