WebApp【公共组件库】@前端(For Git Submodule)
coder77
2025-04-10 f58da404d459a3387f78d9bf6fe8933010f137bf
forms/datePicker/CDateRangeAction.vue
@@ -5,54 +5,61 @@
<template>
    <view class="c-date-range-action">
        <view
            class="c-date-range-slot"
            @tap="evt => handleOpen()"
        >
        <view class="c-date-range-slot" @tap="evt => handleOpen()">
            <slot />
        </view>
        <view
            class="c-data-range-float"
            ref="floadLayer"
        >
            <AtDrawer
        <view class="c-data-range-float" ref="floadLayer">
            <CDrawer
                class="c-data-range-drawer"
                ref="floatDrawer"
                mask
                direction="top"
                :show="drawerShow"
                :onClose="evt => drawerShow=false"
                :onClose="evt => handleClose()"
            >
                <view class="title">
                    <view v-if="placeholder">{{placeholder}}</view>
                    <view v-if="placeholder">{{ placeholder }}</view>
                    <view v-else>请选择日期</view>
                </view>
                <view class="date">
                    <picker
                        mode="date"
                        :start="pickerStart"
                        :end="pickerEnd"
                        :value="startDate"
                        @change="evt => handleStartDateChange(evt.detail.value)"
                    >
                        <view class="item">
                            <view class="label">开始日期</view>
                            <view :class="startDate?'filled':'empty'">
                                {{ startDate?startDate:'请选择开始日期' }}
                            <view :class="startDate ? 'filled' : 'empty'">
                                {{ startDate ? startDate : '请选择开始日期' }}
                            </view>
                            <view class="at-icon at-icon-chevron-right" />
                        </view>
                    </picker>
                    <picker
                        mode="date"
                        :start="pickerStart"
                        :end="pickerEnd"
                        :value="endDate"
                        @change="evt => handleEndDateChange(evt.detail.value)"
                    >
                        <view class="item">
                            <view class="label">结束日期</view>
                            <view :class="endDate?'filled':'empty'">
                                {{ endDate?endDate:'请选择结束日期' }}
                            <view :class="endDate ? 'filled' : 'empty'">
                                {{ endDate ? endDate : '请选择结束日期' }}
                            </view>
                            <view class="at-icon at-icon-chevron-right" />
                        </view>
                    </picker>
                </view>
                <view class="quick-select">
                    <view
                        class="quick-select-item"
                        v-for="(item, index) in quickSelect"
                        :key="index"
                        @tap="evt => handleQuickSelect(item)"
                    >
                        <view class="quick-select-item-label">{{ item.label }}</view>
                    </view>
                </view>
                <AtButton
                    class="btn"
@@ -60,16 +67,19 @@
                    full
                    :circle="false"
                    :onClick="evt => handleFinish()"
                >确定</AtButton>
            </AtDrawer>
                    >确定</AtButton
                >
            </CDrawer>
        </view>
    </view>
</template>
<script>
import Taro from '@tarojs/taro';
import moment from 'moment';
import { $ } from '@tarojs/extend';
import { AtDrawer, AtButton } from 'taro-ui-vue';
import { CDrawer } from '@components/layout/drawer';
import './cDateRangeAction.scss';
export default {
@@ -77,6 +87,7 @@
    components: {
        AtDrawer,
        AtButton,
        CDrawer,
    },
    props: {
        // 项值
@@ -85,21 +96,298 @@
        onChange: Function,
        // 占位提示
        placeholder: String,
        // 选择器类型,选日期、选周、选月
        picker: {
            type: String,
            default: 'date', // date, week, month
        },
        // 预设类型
        rangeTypes: Array,
    },
    data() {
        const year = new Date().getFullYear();
        return {
            drawerShow: false,
            startDate: '',
            endDate: '',
            pickerStart: year - 30 + '-01-01',
            pickerEnd: year + 30 + '-12-31',
            quickSelect: [],
        };
    },
    computed: {},
    methods: {
        _createRanges(ranges) {
            const result = [];
            for (let typeName of ranges) {
                switch (typeName) {
                    case 'today':
                        result.push({
                            label: '今天',
                            value: [
                                moment().format('YYYY-MM-DD'),
                                moment().format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'yesterday':
                        result.push({
                            label: '昨天',
                            value: [
                                moment().subtract(1, 'day').format('YYYY-MM-DD'),
                                moment().subtract(1, 'day').format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'curWeek':
                        if (this.limitDays && this.limitDays < 7) {
                            break;
                        }
                        result.push({
                            label: '本周',
                            value: [
                                moment().startOf('week').format('YYYY-MM-DD'),
                                moment().endOf('week').format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'lastWeek':
                        if (this.limitDays && this.limitDays < 7) {
                            break;
                        }
                        result.push({
                            label: '上周',
                            value: [
                                moment()
                                    .subtract(1, 'week')
                                    .startOf('week')
                                    .format('YYYY-MM-DD'),
                                moment()
                                    .subtract(1, 'week')
                                    .endOf('week')
                                    .format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'curMonth':
                        if (this.limitDays && this.limitDays < 30) {
                            break;
                        }
                        result.push({
                            label: '本月',
                            value: [
                                moment().startOf('month').format('YYYY-MM-DD'),
                                moment().endOf('month').format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'lastMonth':
                        if (this.limitDays && this.limitDays < 30) {
                            break;
                        }
                        result.push({
                            label: '上月',
                            value: [
                                moment()
                                    .subtract(1, 'months')
                                    .startOf('month')
                                    .format('YYYY-MM-DD'),
                                moment()
                                    .subtract(1, 'months')
                                    .endOf('month')
                                    .format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'curQuarter':
                        if (this.limitDays && this.limitDays < 90) {
                            break;
                        }
                        result.push({
                            label: '本季',
                            value: [
                                moment().startOf('quarter').format('YYYY-MM-DD'),
                                moment().endOf('quarter').format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'lastQuarter':
                        if (this.limitDays && this.limitDays < 90) {
                            break;
                        }
                        result.push({
                            label: '上季',
                            value: [
                                moment()
                                    .subtract(1, 'quarter')
                                    .startOf('quarter')
                                    .format('YYYY-MM-DD'),
                                moment()
                                    .subtract(1, 'quarter')
                                    .endOf('quarter')
                                    .format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly3':
                        if (this.limitDays && this.limitDays < 3) {
                            break;
                        }
                        result.push({
                            label: '最近3天',
                            value: [
                                moment().subtract(2, 'days').format('YYYY-MM-DD'),
                                moment().format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly7':
                        if (this.limitDays && this.limitDays < 7) {
                            break;
                        }
                        result.push({
                            label: '最近7天',
                            value: [
                                moment().subtract(6, 'days').format('YYYY-MM-DD'),
                                moment().format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly10':
                        if (this.limitDays && this.limitDays < 10) {
                            break;
                        }
                        result.push({
                            label: '最近10天',
                            value: [
                                moment().subtract(9, 'days').format('YYYY-MM-DD'),
                                moment().format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly15':
                        if (this.limitDays && this.limitDays < 15) {
                            break;
                        }
                        result.push({
                            label: '最近15天',
                            value: [
                                moment().subtract(14, 'days').format('YYYY-MM-DD'),
                                moment().format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly30':
                        if (this.limitDays && this.limitDays < 30) {
                            break;
                        }
                        result.push({
                            label: '最近30天',
                            value: [
                                moment().subtract(29, 'days').format('YYYY-MM-DD'),
                                moment().format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly60':
                        if (this.limitDays && this.limitDays < 60) {
                            break;
                        }
                        result.push({
                            label: '最近60天',
                            value: [
                                moment().subtract(59, 'days').format('YYYY-MM-DD'),
                                moment().format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly90':
                        if (this.limitDays && this.limitDays < 90) {
                            break;
                        }
                        result.push({
                            label: '最近90天',
                            value: [
                                moment().subtract(89, 'days').format('YYYY-MM-DD'),
                                moment().format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly4W':
                        if (this.limitDays && this.limitDays < 28) {
                            break;
                        }
                        result.push({
                            label: '最近4周',
                            value: [
                                moment()
                                    .subtract(3, 'week')
                                    .startOf('week')
                                    .format('YYYY-MM-DD'),
                                moment().endOf('week').format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly12W':
                        if (this.limitDays && this.limitDays < 84) {
                            break;
                        }
                        result.push({
                            label: '最近12周',
                            value: [
                                moment()
                                    .subtract(11, 'week')
                                    .startOf('week')
                                    .format('YYYY-MM-DD'),
                                moment().endOf('week').format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    case 'nearly3M':
                        if (this.limitDays && this.limitDays < 90) {
                            break;
                        }
                        result.push({
                            label: '最近3个月',
                            value: [
                                moment()
                                    .subtract(2, 'months')
                                    .startOf('month')
                                    .format('YYYY-MM-DD'),
                                moment().endOf('month').format('YYYY-MM-DD'),
                            ],
                        });
                        break;
                    default:
                        break;
                }
            }
            return result;
        },
        _initQuickSelect() {
            const defaultRangeTypes = {
                date: ['today', 'curWeek', 'nearly3', 'nearly7'],
                week: ['curWeek', 'lastWeek', 'nearly4W', 'nearly12W'],
                month: ['curMonth', 'lastMonth', 'curQuarter', 'lastQuarter', 'nearly3M'],
            };
            this.quickSelect = this.rangeTypes
                ? this._createRanges(this.rangeTypes)
                : this._createRanges(defaultRangeTypes[this.picker]);
        },
        handleQuickSelect(item) {
            this.startDate = item.value[0];
            this.endDate = item.value[1];
        },
        handleOpen() {
            this.drawerShow = true;
            const curDates = (this.value || ',').split(',');
            this.startDate = curDates[0];
            this.endDate = curDates[1];
        },
        handleClose() {
            this.drawerShow = false;
        },
        handleStartDateChange(date) {
            if (date && this.endDate) {
@@ -146,8 +434,9 @@
        const $cFilter = $(this.$refs.floadLayer).parents('.c-filter');
        if ($cFilter.length > 0) {
            $cFilter.eq(0).after(this.$refs.floadLayer);
            $cFilter.parent().css('transform', 'translate(0,0)');
        }
        this._initQuickSelect();
    },
};
</script>