feat(store): 新增门店新订单提醒功能

- 新增 useNewOrderDetector Hook,实现30秒轮询检测新订单
- 订单管理页集成该 Hook,新增订单时震动+Toast提醒
- “全部”Tab 显示新订单红点,切换Tab清空未读计数
- 门店中心页增加待处理订单角标,统一待审核和待处理显示逻辑
- 底部新增“接收新订单提醒”订阅消息授权入口,调用微信接口申请授权
- 文档中补充订阅消息模板ID及字段说明,待后端配合公众号推送消息
This commit is contained in:
2026-07-04 12:10:02 +08:00
parent 994695c405
commit 5c8acfd19c
6 changed files with 286 additions and 14 deletions

View File

@@ -4,6 +4,7 @@ import Taro, {useDidShow} from '@tarojs/taro'
import {pageShopOrder, updateShopOrder, removeShopOrder} from '@/api/shop/shopOrder'
import type {ShopOrder, ShopOrderParam} from '@/api/shop/shopOrder/model'
import {TenantId} from '@/config/app'
import {useNewOrderDetector} from '@/hooks/useNewOrderDetector'
definePageConfig({
navigationBarTitleText: '订单管理',
@@ -141,6 +142,25 @@ export default function StoreOrdersPage() {
const pageSize = 10
const loadingRef = useRef(false)
// ─── 新订单轮询检测 ──────────────────────────────────────────
const { newOrderCount, clearUnread } = useNewOrderDetector({
interval: 30000, // 30 秒轮询一次
fetchLatestOrders: useCallback(
() => pageShopOrder({ page: 1, limit: 5 }).then(r => r?.list || []),
[],
),
onNewOrders: useCallback((count) => {
// 震动提醒
Taro.vibrateShort({ type: 'medium' })
// Toast 提醒
Taro.showToast({
title: `您有 ${count} 条新订单`,
icon: 'none',
duration: 2500,
})
}, []),
})
/** 加载订单列表(待处理 Tab 会合并多个 statusFilter 的结果) */
const loadOrders = useCallback(async (tab: TabKey, pageNo: number = 1, append = false) => {
if (loadingRef.current) return
@@ -442,15 +462,26 @@ export default function StoreOrdersPage() {
{TABS.map(tab => (
<View
key={tab.key}
className={`flex-1 text-center py-3 border-b-2 ${
className={`flex-1 text-center py-3 border-b-2 relative ${
activeTab === tab.key ? 'border-green-500' : 'border-transparent'
}`}
onClick={() => setActiveTab(tab.key)}
onClick={() => {
setActiveTab(tab.key)
clearUnread()
}}
>
<Text
className={`text-sm ${activeTab === tab.key ? 'text-green-500 font-medium' : 'text-gray-500'}`}>
{tab.label}
</Text>
{/* 新订单角标:在"全部"Tab 上显示 */}
{tab.key === 'all' && newOrderCount > 0 && (
<View className='absolute -top-0.5 right-2 min-w-[18px] h-[18px] rounded-full bg-red-500 flex items-center justify-center px-1'>
<Text className='text-white text-[10px] font-bold'>
{newOrderCount > 99 ? '99+' : newOrderCount}
</Text>
</View>
)}
</View>
))}
</View>