# cxc-szcx-dateRangeSelect
# # 紧凑型日期时间选择器组件说明书

## 一、组件概述
`compact-datetime-picker` 是一个基于 Vue 开发的紧凑型日期时间选择器组件，用于在页面中选择日期范围。组件提供了自然周期和相对周期两种选择模式，并且支持快捷选择本周、本月、本季、本年、近一周、近一月、近一季、近一年等常见时间范围。

## 二、组件依赖
- **Vue**：组件基于 Vue 框架开发。
- **uni-popup**：来自 `uni-app` 的弹窗组件，用于显示日期选择器的弹出层。

## 三、组件使用方法

### 1. 引入组件
在需要使用该组件的 Vue 文件中，引入 `compact-datetime-picker` 组件。
```vue
<template>
  <view>
    <compact-datetime-picker v-model="dateRange" />
  </view>
</template>

<script>
import CompactDateTimePicker from '@/components/compact-datetime-picker.vue';

export default {
  components: {
    CompactDateTimePicker
  },
  data() {
    return {
      dateRange: [null, null]
    };
  }
};
</script>
```

### 2. 组件属性
| 属性名 | 类型 | 默认值 | 描述 |
| ---- | ---- | ---- | ---- |
| `modelValue` | `Array` | `[null, null]` | 双向绑定的日期范围数组，第一个元素为开始日期，第二个元素为结束日期。 |

## 四、组件内部实现

### 1. 模板部分
- **输入框区域**：显示开始日期和结束日期的输入框，点击输入框可打开日期选择弹窗。
- **日期选择弹窗**：
  - **快捷按钮区域**：包含自然周期和相对周期的切换按钮，以及不同模式下的快捷操作按钮。
  - **日历选择区域**：显示当前月份的日历，可选择日期。
  - **操作按钮**：包含取消和确定按钮，用于关闭弹窗和确认选择的日期范围。

### 2. 脚本部分

#### 2.1 数据属性
```javascript
data() {
  return {
    isNatural: true, // 是否为自然周期模式
    activeType: 'start', // 当前活跃的日期选择类型（开始或结束）
    currentMonth: new Date(), // 当前显示的月份
    tempStart: null, // 临时开始日期
    tempEnd: null, // 临时结束日期
    weekDays: ['日', '一', '二', '三', '四', '五', '六'], // 星期几的显示文本
    quickButtonszr: [
      { label: '本周', type: 'week' },
      { label: '本月', type: 'month' },
      { label: '本季', type: 'quarter' },
      { label: '本年', type: 'year' }
    ], // 自然周期模式下的快捷按钮
    quickButtonsxd: [
      { label: '近一周', type: 'week' },
      { label: '近一月', type: 'month' },
      { label: '近一季', type: 'quarter' },
      { label: '近一年', type: 'year' }
    ] // 相对周期模式下的快捷按钮
  };
}
```

#### 2.2 计算属性
- `formattedStart`：格式化后的开始日期。
- `formattedEnd`：格式化后的结束日期。
- `calendarDays`：生成当前月份的日历数据。
- `monthText`：当前月份的显示文本。

#### 2.3 监听属性
```javascript
watch: {
  modelValue: {
    immediate: true,
    handler(newVal) {
      this.tempStart = newVal[0];
      this.tempEnd = newVal[1];
    }
  }
}
```
监听 `modelValue` 的变化，初始化临时日期。

#### 2.4 方法
- **打开弹窗并初始化临时值**：`openPicker(type)`，打开日期选择弹窗，并根据活跃类型初始化临时日期。
- **日期点击处理**：`handleDayClick(day)`，处理日期点击事件，更新临时开始或结束日期。
- **确认选择**：`confirmSelection()`，确认选择的日期范围，触发 `update:modelValue` 事件并关闭弹窗。
- **关闭弹窗**：`closePicker()`，关闭日期选择弹窗，并重置临时日期。
- **重置临时日期**：`resetTempDates()`，将临时日期重置为当前的 `modelValue`。
- **生成日历数据**：`generateCalendar(date)`，根据给定的月份生成日历数据。
- **日期选择处理**：`selectDate(date)`，处理日期选择，更新 `modelValue`。
- **切换月份**：`changeMonth(offset)`，切换当前显示的月份。
- **判断日期状态**：
  - `isSelected(date)`：判断日期是否被选中。
  - `isEnd(date)`：判断日期是否为结束日期。
  - `isToday(date)`：判断日期是否为今天。
  - `isStart(date)`：判断日期是否为开始日期。
  - `isInRange(date)`：判断日期是否在选择的范围内。
  - `isSameDay(d1, d2)`：判断两个日期是否为同一天。
- **快捷范围设置**：`setQuickRange(type)`，根据快捷按钮的类型设置日期范围，并关闭弹窗。
- **自然周期计算**：`calcNaturalRange(type, currentDate)`，计算自然周期模式下的日期范围。
- **相对周期计算**：`calcRelativeRange(type, currentDate)`，计算相对周期模式下的日期范围。
- **周计算（周一为起点）**：
  - `getWeekStart(date)`：获取一周的开始日期。
  - `getWeekEnd(startDate)`：获取一周的结束日期。
- **月末处理**：`lastDayOfMonth(date)`，获取给定月份的最后一天。
- **月末日调整**：`adjustMonthEnd(start, end)`，调整开始日期到合适的月末日期。
- **闰年判断**：`isLeapYear(year)`，判断给定年份是否为闰年。
- **模式切换**：`toggleMode(isNatural)`，切换自然周期和相对周期模式。
- **日期格式化**：`formatDate(date)`，将日期格式化为 `YYYY-MM-DD` 的字符串。

### 3. 样式部分
- **输入框区域**：设置输入框的样式，包括边框、背景色、字体大小等。
- **紧凑弹窗**：设置弹窗的整体样式，包括背景色、边框半径等。
- **紧凑头部**：设置月份标题和导航箭头的样式。
- **紧凑日期网格**：设置星期几和日期的显示样式，以及不同状态下的日期背景色和字体颜色。
- **快捷按钮区域**：设置模式切换按钮和快捷操作按钮的样式。
- **底部操作**：设置取消和确定按钮的样式。

## 五、注意事项
- 组件使用了 `uni-popup` 组件，确保项目中已正确引入和配置。
- 日期范围的选择逻辑较为复杂，特别是在自然周期和相对周期的切换以及快捷范围设置时，需注意日期的计算和显示。
- 组件的样式是基于 `scoped` 作用域的，可根据项目需求进行调整和扩展。 