diff --git a/components/Calender/README.md b/components/Calender/README.md
new file mode 100644
index 0000000..d341d7c
--- /dev/null
+++ b/components/Calender/README.md
@@ -0,0 +1,548 @@
+# 日历组件 (Calendar Component)
+
+## 功能需求分析
+
+基于设计图片分析,该日历组件是一个酒店预订场景的低价日历弹窗,支持通过日期图标点击触发显示,需要实现以下细分功能:
+
+## 交互使用方式
+
+### 基础用法
+通过点击日期图标打开日历组件:
+
+```vue
+
+
+
+ 选择日期
+ {{ selectedDate }}
+ 请点击日期图标选择
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 演示文件
+- `year-demo.vue` - 全年日历演示(推荐)
+- `demo.vue` - 完整的交互演示页面
+- `example.vue` - 详细的使用示例,包含单选和范围选择
+
+### 跨年日历
+组件支持显示从当前月份到明年同月份的13个月日历,用户可以连续选择入住和离店日期:
+1. 点击第一个日期设置入住日期
+2. 点击第二个日期设置离店日期
+3. 自动显示"入住"和"离店"标签
+4. 支持滚动浏览跨年日期范围
+
+### 1. 弹窗容器结构
+#### 1.1 弹窗基础框架
+- [ ] 实现遮罩层背景(半透明黑色)
+- [ ] 弹窗居中显示,支持垂直居中
+- [ ] 弹窗圆角设计(建议12px)
+- [ ] 弹窗阴影效果
+- [ ] 弹窗动画效果(淡入淡出)
+
+#### 1.2 弹窗头部区域
+- [ ] 标题文字:"低价日历"
+- [ ] 副标题文字:"以下价格为单晚参考价"
+- [ ] 右上角关闭按钮(X图标)
+- [ ] 关闭按钮点击交互
+- [ ] 头部区域背景色和分割线
+
+### 2. 日历主体结构
+#### 2.1 周标题行
+- [ ] 显示周几标题:一、二、三、四、五、六、日
+- [ ] 周标题居中对齐
+- [ ] 周标题字体样式(灰色、小字号)
+
+#### 2.2 月份导航
+- [ ] 月份标题显示:"2024年5月"、"2024年6月"
+- [ ] 月份标题居中显示
+- [ ] 月份标题字体加粗
+- [ ] 支持上下滑动切换月份(可选)
+
+### 3. 日期网格系统
+#### 3.1 日期格子基础
+- [ ] 7列网格布局(对应周一到周日)
+- [ ] 每个格子固定宽高比
+- [ ] 格子间距设计
+- [ ] 格子圆角设计
+
+#### 3.2 日期内容显示
+- [ ] 日期数字显示(居中对齐)
+- [ ] 价格信息显示(¥449格式)
+- [ ] 日期数字字体大小和颜色
+- [ ] 价格字体大小和颜色(较小、灰色)
+
+#### 3.3 日期状态管理
+- [ ] 普通可选日期(白色背景)
+- [ ] 当前选中日期(蓝色背景,白色文字)
+- [ ] 入住日期标记("入住"标签)
+- [ ] 离店日期标记("离店"标签)
+- [ ] 选择范围内日期(浅蓝色背景)
+- [ ] 不可选日期(灰色背景,禁用状态)
+
+### 4. 交互功能实现
+#### 4.1 日期选择逻辑
+- [ ] 单击日期选择功能
+- [ ] 日期范围选择(入住-离店)
+- [ ] 选择状态视觉反馈
+- [ ] 选择完成后的回调事件
+
+#### 4.2 用户体验优化
+- [ ] 点击动画效果
+- [ ] 触摸反馈
+- [ ] 防止快速重复点击
+- [ ] 选择范围的视觉连接线(可选)
+
+### 5. 数据处理功能
+#### 5.1 价格数据管理
+- [ ] 价格数据结构设计
+- [ ] 价格数据绑定到日期
+- [ ] 价格格式化显示
+- [ ] 无价格数据的处理
+
+#### 5.2 日期计算功能
+- [ ] 月份天数计算
+- [ ] 月份第一天星期几计算
+- [ ] 跨月份日期处理
+- [ ] 日期有效性验证
+
+### 6. 响应式适配
+#### 6.1 移动端适配
+- [ ] 触摸屏操作优化
+- [ ] 不同屏幕尺寸适配
+- [ ] 横竖屏切换适配
+- [ ] 安全区域适配(刘海屏等)
+
+#### 6.2 字体和尺寸适配
+- [ ] 字体大小响应式调整
+- [ ] 格子尺寸响应式调整
+- [ ] 间距响应式调整
+
+## 技术实现细节
+
+### 组件接口设计
+
+#### Props 属性
+```javascript
+props: {
+ // 弹窗显示控制
+ visible: {
+ type: Boolean,
+ default: false,
+ required: true
+ },
+
+ // 价格数据对象
+ priceData: {
+ type: Object,
+ default: () => ({}),
+ // 格式: { '2024-05-17': 449, '2024-05-18': 399 }
+ },
+
+ // 默认选中日期
+ defaultValue: {
+ type: [String, Array],
+ default: '',
+ // 单选: '2024-05-17'
+ // 范围选择: ['2024-05-17', '2024-05-19']
+ },
+
+ // 选择模式
+ mode: {
+ type: String,
+ default: 'single',
+ validator: (value) => ['single', 'range'].includes(value)
+ },
+
+ // 最小可选日期
+ minDate: {
+ type: String,
+ default: () => new Date().toISOString().split('T')[0]
+ },
+
+ // 最大可选日期
+ maxDate: {
+ type: String,
+ default: ''
+ },
+
+ // 禁用日期数组
+ disabledDates: {
+ type: Array,
+ default: () => []
+ },
+
+ // 自定义标签
+ customLabels: {
+ type: Object,
+ default: () => ({})
+ // 格式: { '2024-05-17': '入住', '2024-05-19': '离店' }
+ }
+}
+```
+
+#### Events 事件
+```javascript
+// 日期选择事件
+this.$emit('select', {
+ date: '2024-05-17',
+ price: 449,
+ mode: 'single'
+})
+
+// 范围选择事件
+this.$emit('range-select', {
+ startDate: '2024-05-17',
+ endDate: '2024-05-19',
+ startPrice: 449,
+ endPrice: 399,
+ totalDays: 2
+})
+
+// 弹窗关闭事件
+this.$emit('close')
+
+// 月份切换事件
+this.$emit('month-change', {
+ year: 2024,
+ month: 5,
+ direction: 'next' // 'prev' | 'next'
+})
+
+// 日期点击事件(包含所有点击)
+this.$emit('date-click', {
+ date: '2024-05-17',
+ price: 449,
+ disabled: false,
+ selected: true
+})
+```
+
+### 核心算法实现
+
+#### 日期计算工具函数
+```javascript
+// 获取月份天数
+getDaysInMonth(year, month) {
+ return new Date(year, month, 0).getDate()
+}
+
+// 获取月份第一天是星期几
+getFirstDayOfMonth(year, month) {
+ return new Date(year, month - 1, 1).getDay()
+}
+
+// 生成日期网格数据
+generateCalendarGrid(year, month) {
+ const daysInMonth = this.getDaysInMonth(year, month)
+ const firstDay = this.getFirstDayOfMonth(year, month)
+ const grid = []
+
+ // 填充空白格子
+ for (let i = 0; i < firstDay; i++) {
+ grid.push(null)
+ }
+
+ // 填充日期
+ for (let day = 1; day <= daysInMonth; day++) {
+ const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
+ grid.push({
+ date: dateStr,
+ day: day,
+ price: this.priceData[dateStr] || null,
+ disabled: this.isDateDisabled(dateStr),
+ selected: this.isDateSelected(dateStr),
+ inRange: this.isDateInRange(dateStr),
+ label: this.customLabels[dateStr] || ''
+ })
+ }
+
+ return grid
+}
+```
+
+#### 选择状态管理
+```javascript
+data() {
+ return {
+ selectedDates: [],
+ currentMonth: new Date().getMonth() + 1,
+ currentYear: new Date().getFullYear(),
+ isRangeSelecting: false,
+ rangeStart: null,
+ rangeEnd: null
+ }
+},
+
+methods: {
+ handleDateClick(dateInfo) {
+ if (dateInfo.disabled) return
+
+ if (this.mode === 'single') {
+ this.selectedDates = [dateInfo.date]
+ this.$emit('select', dateInfo)
+ } else if (this.mode === 'range') {
+ this.handleRangeSelection(dateInfo)
+ }
+ },
+
+ handleRangeSelection(dateInfo) {
+ if (!this.rangeStart || (this.rangeStart && this.rangeEnd)) {
+ // 开始新的范围选择
+ this.rangeStart = dateInfo.date
+ this.rangeEnd = null
+ this.isRangeSelecting = true
+ } else {
+ // 完成范围选择
+ this.rangeEnd = dateInfo.date
+ this.isRangeSelecting = false
+
+ // 确保开始日期小于结束日期
+ if (new Date(this.rangeStart) > new Date(this.rangeEnd)) {
+ [this.rangeStart, this.rangeEnd] = [this.rangeEnd, this.rangeStart]
+ }
+
+ this.$emit('range-select', {
+ startDate: this.rangeStart,
+ endDate: this.rangeEnd,
+ startPrice: this.priceData[this.rangeStart],
+ endPrice: this.priceData[this.rangeEnd],
+ totalDays: this.calculateDaysBetween(this.rangeStart, this.rangeEnd)
+ })
+ }
+ }
+}
+```
+
+### 样式设计规范
+
+#### 颜色系统
+```scss
+// 主色调
+$primary-color: #1890ff;
+$primary-light: #e6f7ff;
+$primary-dark: #0050b3;
+
+// 中性色
+$text-primary: #262626;
+$text-secondary: #8c8c8c;
+$text-disabled: #bfbfbf;
+$background-white: #ffffff;
+$background-gray: #f5f5f5;
+$border-color: #d9d9d9;
+
+// 状态色
+$success-color: #52c41a;
+$warning-color: #faad14;
+$error-color: #ff4d4f;
+```
+
+#### 尺寸规范
+```scss
+// 弹窗尺寸
+$modal-width: 350px;
+$modal-max-height: 80vh;
+$modal-border-radius: 12px;
+$modal-padding: 20px;
+
+// 日期格子尺寸
+$date-cell-size: 44px;
+$date-cell-gap: 2px;
+$date-cell-border-radius: 6px;
+
+// 字体大小
+$font-size-title: 18px;
+$font-size-subtitle: 14px;
+$font-size-date: 16px;
+$font-size-price: 12px;
+$font-size-label: 10px;
+```
+
+## 开发实施计划
+
+### 第一阶段:基础框架(1-2天)
+- [ ] 创建组件基础结构
+- [ ] 实现弹窗容器和遮罩
+- [ ] 添加头部区域和关闭功能
+- [ ] 建立基础样式系统
+
+### 第二阶段:日历核心(2-3天)
+- [ ] 实现日期计算算法
+- [ ] 构建日期网格布局
+- [ ] 添加周标题和月份显示
+- [ ] 实现基础日期显示
+
+### 第三阶段:交互功能(2-3天)
+- [ ] 实现日期选择逻辑
+- [ ] 添加范围选择功能
+- [ ] 实现状态管理和视觉反馈
+- [ ] 添加价格数据绑定
+
+### 第四阶段:优化完善(1-2天)
+- [ ] 添加动画效果
+- [ ] 优化移动端体验
+- [ ] 完善边界情况处理
+- [ ] 性能优化和测试
+
+## 使用示例
+
+### 基础用法
+```vue
+
+
+
+
+
+
+
+
+
+```
+
+### 高级用法
+```vue
+
+
+
+
+
+```
+
+## 测试用例
+
+### 单元测试
+- [ ] 日期计算函数测试
+- [ ] 选择逻辑测试
+- [ ] 价格数据绑定测试
+- [ ] 边界条件测试
+
+### 集成测试
+- [ ] 用户交互流程测试
+- [ ] 不同设备适配测试
+- [ ] 性能压力测试
+
+### 可访问性测试
+- [ ] 键盘导航测试
+- [ ] 屏幕阅读器兼容性
+- [ ] 色彩对比度检查
\ No newline at end of file
diff --git a/components/Calender/demo.vue b/components/Calender/demo.vue
new file mode 100644
index 0000000..809c4a5
--- /dev/null
+++ b/components/Calender/demo.vue
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+
+
+
+ 选择日期
+ {{ formatDate(selectedDate) }}
+ 请点击日期图标选择
+
+
+
+
+
+
+
+
+
+
+ 已选择日期
+ {{ formatDate(selectedDate) }}
+ 价格:¥{{ selectedPrice }}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/Calender/example.vue b/components/Calender/example.vue
new file mode 100644
index 0000000..d120867
--- /dev/null
+++ b/components/Calender/example.vue
@@ -0,0 +1,253 @@
+
+
+
+
+
+
+
+
+
+ 选择日期
+ {{ selectedDate }}
+ 请选择日期
+
+
+
+
+
+
+
+ 选择日期范围
+
+ {{ selectedRange.start }} 至 {{ selectedRange.end }}
+
+ 请选择日期范围
+
+
+
+
+
+
+
+ 选择结果:
+
+ 单选日期:
+ {{ selectedDate }}
+
+
+ 日期范围:
+ {{ selectedRange.start }} 至 {{ selectedRange.end }}
+ (共{{ rangeDays }}天)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/Calender/images/日期-价格弹窗.png b/components/Calender/images/日期-价格弹窗.png
new file mode 100644
index 0000000..543d484
Binary files /dev/null and b/components/Calender/images/日期-价格弹窗.png differ
diff --git a/components/Calender/index.vue b/components/Calender/index.vue
new file mode 100644
index 0000000..b95225c
--- /dev/null
+++ b/components/Calender/index.vue
@@ -0,0 +1,423 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/Calender/styles/index.scss b/components/Calender/styles/index.scss
new file mode 100644
index 0000000..bba01e7
--- /dev/null
+++ b/components/Calender/styles/index.scss
@@ -0,0 +1,265 @@
+// 颜色系统
+$primary-color: #1890ff;
+$primary-light: #e6f7ff;
+$primary-dark: #0050b3;
+
+// 中性色
+$text-primary: #262626;
+$text-secondary: #8c8c8c;
+$text-disabled: #bfbfbf;
+$background-white: #ffffff;
+$background-gray: #f5f5f5;
+$border-color: #d9d9d9;
+
+// 状态色
+$success-color: #52c41a;
+$warning-color: #faad14;
+$error-color: #ff4d4f;
+
+// 尺寸规范
+$modal-max-height: 80vh;
+$modal-border-radius: 12px;
+$modal-padding: 12px;
+
+// 日期格子尺寸
+$date-cell-size: 40px;
+$date-cell-gap: 4px;
+$date-cell-border-radius: 6px;
+
+// 字体大小
+$font-size-title: 18px;
+$font-size-subtitle: 14px;
+$font-size-date: 16px;
+$font-size-price: 12px;
+$font-size-label: 10px;
+
+// uni-popup会自动处理遮罩层和定位,这里移除相关样式
+
+// 弹窗主体
+.calendar-popup {
+ position: relative;
+ width: 100%;
+ background-color: $background-white;
+ border-radius: $modal-border-radius;
+ overflow: hidden;
+}
+
+// 头部区域
+.calendar-header {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ padding: $modal-padding;
+ border-bottom: 1px solid $border-color;
+ background-color: $background-white;
+}
+
+.header-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.header-title {
+ font-size: $font-size-title;
+ font-weight: 600;
+ color: $text-primary;
+ line-height: 1.4;
+}
+
+.header-subtitle {
+ font-size: $font-size-subtitle;
+ color: $text-secondary;
+ line-height: 1.4;
+}
+
+.header-close {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ transition: background-color 0.2s;
+
+ &:active {
+ background-color: $background-gray;
+ }
+}
+
+// 周标题行 - 固定显示
+.week-header {
+ display: flex;
+ padding: 16px $modal-padding 8px;
+ background-color: $background-white;
+ border-bottom: 1px solid #eeeeee;
+}
+
+// 日历主体区域
+.calendar-body {
+ padding: 8px $modal-padding $modal-padding;
+ max-height: calc(#{$modal-max-height} - 140px);
+ overflow-y: auto;
+ -webkit-overflow-scrolling: touch;
+
+ &::-webkit-scrollbar {
+ display: none;
+ }
+}
+
+.week-day {
+ flex: 1;
+ text-align: center;
+ font-size: $font-size-subtitle;
+ color: $text-secondary;
+ font-weight: 500;
+ line-height: 1.4;
+}
+
+// 全年容器
+.year-container {
+ display: flex;
+ flex-direction: column;
+ gap: 32px;
+}
+
+// 月份区域
+.month-section {
+ display: flex;
+ flex-direction: column;
+}
+
+.month-title {
+ font-size: $font-size-title;
+ font-weight: 600;
+ color: $text-primary;
+ text-align: center;
+ margin-bottom: 16px;
+ margin-top: 8px;
+ line-height: 1.4;
+}
+
+// 日期网格
+.date-grid {
+ display: grid;
+ grid-template-columns: repeat(7, 1fr);
+ gap: $date-cell-gap;
+}
+
+// 日期格子基础样式
+.date-cell {
+ position: relative;
+ width: $date-cell-size;
+ height: $date-cell-size;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: space-between;
+ padding: 2px;
+ border-radius: $date-cell-border-radius;
+ transition: all 0.2s ease;
+ cursor: pointer;
+}
+
+// 空白格子
+.date-cell-empty {
+ background-color: transparent;
+ cursor: default;
+}
+
+// 有内容的格子
+.date-cell-content {
+ background-color: $background-white;
+ border: 1px solid transparent;
+
+ &:hover {
+ background-color: $background-gray;
+ }
+
+ &:active {
+ transform: scale(0.95);
+ }
+}
+
+// 禁用状态
+.date-cell-disabled {
+ background-color: $background-gray !important;
+ color: $text-disabled !important;
+ cursor: not-allowed !important;
+
+ .date-number,
+ .date-price {
+ color: $text-disabled !important;
+ }
+
+ &:hover {
+ background-color: $background-gray !important;
+ transform: none !important;
+ }
+}
+
+// 选中状态
+.date-cell-selected {
+ background-color: $primary-color !important;
+ border-color: $primary-color !important;
+
+ .date-number,
+ .date-price,
+ .date-label {
+ color: $background-white !important;
+ }
+
+ &:hover {
+ background-color: $primary-dark !important;
+ }
+}
+
+// 范围内状态
+.date-cell-in-range {
+ background-color: $primary-light !important;
+ border-color: $primary-light !important;
+
+ .date-number {
+ color: $primary-color !important;
+ }
+
+ .date-price {
+ color: $primary-dark !important;
+ }
+}
+
+// 日期数字
+.date-number {
+ font-size: $font-size-date;
+ font-weight: 500;
+ color: $text-primary;
+ line-height: 1;
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+// 价格文字
+.date-price {
+ font-size: $font-size-price;
+ color: $text-secondary;
+ line-height: 1;
+ font-weight: 400;
+ text-align: center;
+ min-height: 14px;
+}
+
+// 自定义标签
+.date-label {
+ font-size: $font-size-label;
+ color: $primary-color;
+ padding: 1px 4px;
+ border-radius: 2px;
+ line-height: 1;
+ white-space: nowrap;
+ font-weight: 500;
+ text-align: center;
+ min-height: 12px;
+}
diff --git a/components/Calender/year-demo.vue b/components/Calender/year-demo.vue
new file mode 100644
index 0000000..ccdaf02
--- /dev/null
+++ b/components/Calender/year-demo.vue
@@ -0,0 +1,269 @@
+
+
+
+
+
+
+
+
+ 📅
+
+
+ 选择入住和离店日期
+
+
+ {{ formatDateRange() }}
+
+
+
+
+
+
+
+ 选择结果:
+
+ 入住日期:
+ {{ formatDate(selectedRange.start) }}
+
+
+ 离店日期:
+ {{ formatDate(selectedRange.end) }}
+
+
+ 住宿天数:
+ {{ calculateDays() }}晚
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/order/components/OrderInfo/index.vue b/pages/order/components/OrderInfo/index.vue
index 56f820b..dfa1165 100644
--- a/pages/order/components/OrderInfo/index.vue
+++ b/pages/order/components/OrderInfo/index.vue
@@ -23,8 +23,13 @@
{{ formattedAmount }}
-