peixue-dev/Archive/peidu-temp-files/docs/🔍日历与订单同步问题分析-2026-01-24.md

7.9 KiB

🔍 日历与订单同步问题分析

日期: 2026-01-24
问题: 创建订单后日历没有和订单进行同步


📋 问题描述

用户反馈:

"创建订单后日历没有和订单进行同步"

具体表现:

  1. 用户在预约页面创建了新订单
  2. 订单创建成功
  3. 跳转到日历页面
  4. 日历上没有显示新创建的订单
  5. 需要手动刷新页面才能看到

🔍 问题原因分析

可能的原因:

1. 页面生命周期问题

// 日历页面只在 onLoad 时加载数据
onLoad() {
  this.loadScheduleData()
}

// 但是从其他页面返回时,不会触发 onLoad
// 只会触发 onShow

2. 缓存问题

  • 前端缓存了旧的日历数据
  • 没有在返回时重新加载

3. 数据查询时机问题

  • 订单刚创建,数据库可能还没有完全写入
  • 立即查询可能查不到新数据

4. 状态筛选问题

  • 新创建的订单状态可能不在日历显示的状态范围内
  • 例如: 待支付(status=0)的订单可能不显示在日历上

解决方案

方案1: 在onShow中重新加载数据 (推荐)

优点:

  • 简单直接
  • 每次显示页面都会刷新数据
  • 确保数据最新

实现:

// 日历页面
onShow() {
  // 每次显示页面时重新加载数据
  this.loadScheduleData()
  this.loadStatistics()
}

方案2: 使用事件总线通知刷新

优点:

  • 精确控制刷新时机
  • 避免不必要的刷新

实现:

// 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参数传递信息

实现:

// 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)

优点:

  • 统一管理订单数据
  • 多个页面可以共享状态

实现:

// 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刷新

// user-package/pages/calendar/index.vue

onShow() {
  // 每次显示页面时重新加载数据
  console.log('[日历] onShow - 重新加载数据')
  this.loadScheduleData()
  this.loadStatistics()
}

2. 创建订单后跳转时带参数

// 创建订单成功后
uni.showToast({
  title: '预约成功',
  icon: 'success',
  duration: 1500
})

setTimeout(() => {
  uni.navigateTo({
    url: `/user-package/pages/calendar/index?refresh=true&date=${this.serviceDate}`
  })
}, 1500)

3. 日历页面处理参数

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. 订单状态是否正确

// 确认新创建的订单状态
// 日历查询条件:
.in("status", Arrays.asList(1, 2, 3, 4))

// 如果新订单是 status=0 (待支付),则不会显示在日历上
// 需要确认业务逻辑:
// - 待支付的订单是否应该显示在日历上?
// - 还是只显示已支付的订单?

2. 用户ID是否正确

// 确认查询时使用的用户ID正确
// CalendarController.getCurrentUserId() 
// 是否返回了正确的用户ID

3. 日期格式是否正确

// 确认订单的 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. 添加加载状态提示

async loadScheduleData() {
  this.loading = true
  try {
    // ... 加载数据
  } finally {
    this.loading = false
  }
}

2. 添加下拉刷新

<scroll-view 
  scroll-y 
  @refresherrefresh="onRefresh"
  refresher-enabled
  :refresher-triggered="refreshing"
>
  <!-- 内容 -->
</scroll-view>

3. 添加错误重试

async loadScheduleData() {
  try {
    // ... 加载数据
  } catch (error) {
    uni.showModal({
      title: '加载失败',
      content: '是否重试?',
      success: (res) => {
        if (res.confirm) {
          this.loadScheduleData()
        }
      }
    })
  }
}

总结

问题的根本原因是:

  • 日历页面只在onLoad时加载数据
  • 从其他页面返回时不会自动刷新

解决方案:

  • onShow中重新加载数据
  • 创建订单后跳转时带上刷新参数
  • 确保订单状态在日历显示范围内

这样就能确保日历始终显示最新的订单数据!