416 lines
7.9 KiB
Markdown
416 lines
7.9 KiB
Markdown
|
|
# 🔍 日历与订单同步问题分析
|
||
|
|
|
||
|
|
**日期**: 2026-01-24
|
||
|
|
**问题**: 创建订单后日历没有和订单进行同步
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📋 问题描述
|
||
|
|
|
||
|
|
### 用户反馈:
|
||
|
|
> "创建订单后日历没有和订单进行同步"
|
||
|
|
|
||
|
|
### 具体表现:
|
||
|
|
1. 用户在预约页面创建了新订单
|
||
|
|
2. 订单创建成功
|
||
|
|
3. 跳转到日历页面
|
||
|
|
4. ❌ 日历上没有显示新创建的订单
|
||
|
|
5. 需要手动刷新页面才能看到
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔍 问题原因分析
|
||
|
|
|
||
|
|
### 可能的原因:
|
||
|
|
|
||
|
|
#### 1. 页面生命周期问题
|
||
|
|
```javascript
|
||
|
|
// 日历页面只在 onLoad 时加载数据
|
||
|
|
onLoad() {
|
||
|
|
this.loadScheduleData()
|
||
|
|
}
|
||
|
|
|
||
|
|
// 但是从其他页面返回时,不会触发 onLoad
|
||
|
|
// 只会触发 onShow
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 2. 缓存问题
|
||
|
|
- 前端缓存了旧的日历数据
|
||
|
|
- 没有在返回时重新加载
|
||
|
|
|
||
|
|
#### 3. 数据查询时机问题
|
||
|
|
- 订单刚创建,数据库可能还没有完全写入
|
||
|
|
- 立即查询可能查不到新数据
|
||
|
|
|
||
|
|
#### 4. 状态筛选问题
|
||
|
|
- 新创建的订单状态可能不在日历显示的状态范围内
|
||
|
|
- 例如: 待支付(status=0)的订单可能不显示在日历上
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ✅ 解决方案
|
||
|
|
|
||
|
|
### 方案1: 在onShow中重新加载数据 (推荐)
|
||
|
|
|
||
|
|
**优点**:
|
||
|
|
- 简单直接
|
||
|
|
- 每次显示页面都会刷新数据
|
||
|
|
- 确保数据最新
|
||
|
|
|
||
|
|
**实现**:
|
||
|
|
```javascript
|
||
|
|
// 日历页面
|
||
|
|
onShow() {
|
||
|
|
// 每次显示页面时重新加载数据
|
||
|
|
this.loadScheduleData()
|
||
|
|
this.loadStatistics()
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 方案2: 使用事件总线通知刷新
|
||
|
|
|
||
|
|
**优点**:
|
||
|
|
- 精确控制刷新时机
|
||
|
|
- 避免不必要的刷新
|
||
|
|
|
||
|
|
**实现**:
|
||
|
|
```javascript
|
||
|
|
// 1. 创建事件总线 (utils/eventBus.js)
|
||
|
|
const eventBus = {
|
||
|
|
events: {},
|
||
|
|
on(event, callback) {
|
||
|
|
if (!this.events[event]) {
|
||
|
|
this.events[event] = []
|
||
|
|
}
|
||
|
|
this.events[event].push(callback)
|
||
|
|
},
|
||
|
|
emit(event, data) {
|
||
|
|
if (this.events[event]) {
|
||
|
|
this.events[event].forEach(callback => callback(data))
|
||
|
|
}
|
||
|
|
},
|
||
|
|
off(event, callback) {
|
||
|
|
if (this.events[event]) {
|
||
|
|
this.events[event] = this.events[event].filter(cb => cb !== callback)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export default eventBus
|
||
|
|
|
||
|
|
// 2. 日历页面监听事件
|
||
|
|
import eventBus from '@/utils/eventBus'
|
||
|
|
|
||
|
|
onLoad() {
|
||
|
|
this.loadScheduleData()
|
||
|
|
|
||
|
|
// 监听订单创建事件
|
||
|
|
eventBus.on('orderCreated', this.handleOrderCreated)
|
||
|
|
}
|
||
|
|
|
||
|
|
onUnload() {
|
||
|
|
// 移除监听
|
||
|
|
eventBus.off('orderCreated', this.handleOrderCreated)
|
||
|
|
}
|
||
|
|
|
||
|
|
methods: {
|
||
|
|
handleOrderCreated(orderData) {
|
||
|
|
console.log('收到订单创建通知:', orderData)
|
||
|
|
// 重新加载日历数据
|
||
|
|
this.loadScheduleData()
|
||
|
|
this.loadStatistics()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. 创建订单页面发送事件
|
||
|
|
import eventBus from '@/utils/eventBus'
|
||
|
|
|
||
|
|
async createOrder() {
|
||
|
|
// ... 创建订单逻辑
|
||
|
|
|
||
|
|
// 发送订单创建事件
|
||
|
|
eventBus.emit('orderCreated', {
|
||
|
|
orderId: result.id,
|
||
|
|
serviceDate: this.serviceDate
|
||
|
|
})
|
||
|
|
|
||
|
|
// 跳转到日历
|
||
|
|
uni.navigateTo({
|
||
|
|
url: '/user-package/pages/calendar/index'
|
||
|
|
})
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 方案3: 使用URL参数触发刷新
|
||
|
|
|
||
|
|
**优点**:
|
||
|
|
- 不需要额外的事件系统
|
||
|
|
- 通过URL参数传递信息
|
||
|
|
|
||
|
|
**实现**:
|
||
|
|
```javascript
|
||
|
|
// 1. 创建订单后跳转时带参数
|
||
|
|
uni.navigateTo({
|
||
|
|
url: '/user-package/pages/calendar/index?refresh=true&date=2026-01-25'
|
||
|
|
})
|
||
|
|
|
||
|
|
// 2. 日历页面接收参数
|
||
|
|
onLoad(options) {
|
||
|
|
if (options.refresh === 'true') {
|
||
|
|
// 需要刷新
|
||
|
|
this.loadScheduleData()
|
||
|
|
}
|
||
|
|
|
||
|
|
if (options.date) {
|
||
|
|
// 定位到指定日期
|
||
|
|
this.selectedDate = options.date
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 方案4: 使用全局状态管理 (Vuex)
|
||
|
|
|
||
|
|
**优点**:
|
||
|
|
- 统一管理订单数据
|
||
|
|
- 多个页面可以共享状态
|
||
|
|
|
||
|
|
**实现**:
|
||
|
|
```javascript
|
||
|
|
// 1. 创建 store/calendar.js
|
||
|
|
export default {
|
||
|
|
state: {
|
||
|
|
needRefresh: false,
|
||
|
|
latestOrderDate: null
|
||
|
|
},
|
||
|
|
mutations: {
|
||
|
|
setNeedRefresh(state, value) {
|
||
|
|
state.needRefresh = value
|
||
|
|
},
|
||
|
|
setLatestOrderDate(state, date) {
|
||
|
|
state.latestOrderDate = date
|
||
|
|
}
|
||
|
|
},
|
||
|
|
actions: {
|
||
|
|
orderCreated({ commit }, orderData) {
|
||
|
|
commit('setNeedRefresh', true)
|
||
|
|
commit('setLatestOrderDate', orderData.serviceDate)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. 日历页面
|
||
|
|
onShow() {
|
||
|
|
if (this.$store.state.calendar.needRefresh) {
|
||
|
|
this.loadScheduleData()
|
||
|
|
this.$store.commit('setNeedRefresh', false)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. 创建订单页面
|
||
|
|
async createOrder() {
|
||
|
|
// ... 创建订单
|
||
|
|
|
||
|
|
// 通知需要刷新
|
||
|
|
this.$store.dispatch('orderCreated', {
|
||
|
|
serviceDate: this.serviceDate
|
||
|
|
})
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎯 推荐实施方案
|
||
|
|
|
||
|
|
### 最简单有效的方案: 方案1 + 方案3 组合
|
||
|
|
|
||
|
|
#### 1. 在日历页面添加onShow刷新
|
||
|
|
```javascript
|
||
|
|
// user-package/pages/calendar/index.vue
|
||
|
|
|
||
|
|
onShow() {
|
||
|
|
// 每次显示页面时重新加载数据
|
||
|
|
console.log('[日历] onShow - 重新加载数据')
|
||
|
|
this.loadScheduleData()
|
||
|
|
this.loadStatistics()
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 2. 创建订单后跳转时带参数
|
||
|
|
```javascript
|
||
|
|
// 创建订单成功后
|
||
|
|
uni.showToast({
|
||
|
|
title: '预约成功',
|
||
|
|
icon: 'success',
|
||
|
|
duration: 1500
|
||
|
|
})
|
||
|
|
|
||
|
|
setTimeout(() => {
|
||
|
|
uni.navigateTo({
|
||
|
|
url: `/user-package/pages/calendar/index?refresh=true&date=${this.serviceDate}`
|
||
|
|
})
|
||
|
|
}, 1500)
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 3. 日历页面处理参数
|
||
|
|
```javascript
|
||
|
|
onLoad(options) {
|
||
|
|
const today = new Date()
|
||
|
|
this.currentYear = today.getFullYear()
|
||
|
|
this.currentMonth = today.getMonth() + 1
|
||
|
|
|
||
|
|
// 如果有指定日期,定位到该日期
|
||
|
|
if (options.date) {
|
||
|
|
this.selectedDate = options.date
|
||
|
|
const date = new Date(options.date)
|
||
|
|
this.currentYear = date.getFullYear()
|
||
|
|
this.currentMonth = date.getMonth() + 1
|
||
|
|
}
|
||
|
|
|
||
|
|
this.loadScheduleData()
|
||
|
|
this.loadStatistics()
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔍 需要检查的其他问题
|
||
|
|
|
||
|
|
### 1. 订单状态是否正确
|
||
|
|
```javascript
|
||
|
|
// 确认新创建的订单状态
|
||
|
|
// 日历查询条件:
|
||
|
|
.in("status", Arrays.asList(1, 2, 3, 4))
|
||
|
|
|
||
|
|
// 如果新订单是 status=0 (待支付),则不会显示在日历上
|
||
|
|
// 需要确认业务逻辑:
|
||
|
|
// - 待支付的订单是否应该显示在日历上?
|
||
|
|
// - 还是只显示已支付的订单?
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. 用户ID是否正确
|
||
|
|
```javascript
|
||
|
|
// 确认查询时使用的用户ID正确
|
||
|
|
// CalendarController.getCurrentUserId()
|
||
|
|
// 是否返回了正确的用户ID
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. 日期格式是否正确
|
||
|
|
```javascript
|
||
|
|
// 确认订单的 service_date 字段格式正确
|
||
|
|
// 应该是: 2026-01-25 (YYYY-MM-DD)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📝 实施步骤
|
||
|
|
|
||
|
|
### 步骤1: 修改日历页面
|
||
|
|
```
|
||
|
|
文件: peidu/uniapp/src/user-package/pages/calendar/index.vue
|
||
|
|
添加: onShow() 方法
|
||
|
|
```
|
||
|
|
|
||
|
|
### 步骤2: 修改创建订单页面
|
||
|
|
```
|
||
|
|
文件: 找到创建订单的页面
|
||
|
|
修改: 跳转日历时带上参数
|
||
|
|
```
|
||
|
|
|
||
|
|
### 步骤3: 测试验证
|
||
|
|
```
|
||
|
|
1. 创建新订单
|
||
|
|
2. 查看是否自动跳转到日历
|
||
|
|
3. 确认日历上显示新订单
|
||
|
|
4. 确认日期定位正确
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🧪 测试场景
|
||
|
|
|
||
|
|
### 场景1: 创建订单后立即查看
|
||
|
|
```
|
||
|
|
操作: 创建订单 → 自动跳转日历
|
||
|
|
预期: 日历上显示新订单
|
||
|
|
```
|
||
|
|
|
||
|
|
### 场景2: 从其他页面返回日历
|
||
|
|
```
|
||
|
|
操作: 日历 → 其他页面 → 返回日历
|
||
|
|
预期: 日历数据是最新的
|
||
|
|
```
|
||
|
|
|
||
|
|
### 场景3: 切换月份后返回
|
||
|
|
```
|
||
|
|
操作: 查看1月 → 切换到2月 → 返回1月
|
||
|
|
预期: 数据正确显示
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 💡 额外优化建议
|
||
|
|
|
||
|
|
### 1. 添加加载状态提示
|
||
|
|
```javascript
|
||
|
|
async loadScheduleData() {
|
||
|
|
this.loading = true
|
||
|
|
try {
|
||
|
|
// ... 加载数据
|
||
|
|
} finally {
|
||
|
|
this.loading = false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. 添加下拉刷新
|
||
|
|
```vue
|
||
|
|
<scroll-view
|
||
|
|
scroll-y
|
||
|
|
@refresherrefresh="onRefresh"
|
||
|
|
refresher-enabled
|
||
|
|
:refresher-triggered="refreshing"
|
||
|
|
>
|
||
|
|
<!-- 内容 -->
|
||
|
|
</scroll-view>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. 添加错误重试
|
||
|
|
```javascript
|
||
|
|
async loadScheduleData() {
|
||
|
|
try {
|
||
|
|
// ... 加载数据
|
||
|
|
} catch (error) {
|
||
|
|
uni.showModal({
|
||
|
|
title: '加载失败',
|
||
|
|
content: '是否重试?',
|
||
|
|
success: (res) => {
|
||
|
|
if (res.confirm) {
|
||
|
|
this.loadScheduleData()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ✅ 总结
|
||
|
|
|
||
|
|
问题的根本原因是:
|
||
|
|
- 日历页面只在`onLoad`时加载数据
|
||
|
|
- 从其他页面返回时不会自动刷新
|
||
|
|
|
||
|
|
解决方案:
|
||
|
|
- ✅ 在`onShow`中重新加载数据
|
||
|
|
- ✅ 创建订单后跳转时带上刷新参数
|
||
|
|
- ✅ 确保订单状态在日历显示范围内
|
||
|
|
|
||
|
|
这样就能确保日历始终显示最新的订单数据!
|