diff --git a/.workbuddy/memory/2025-07-15.md b/.workbuddy/memory/2025-07-15.md
index f7deb87..9620a5d 100644
--- a/.workbuddy/memory/2025-07-15.md
+++ b/.workbuddy/memory/2025-07-15.md
@@ -9,3 +9,12 @@
- 弹窗宽度从 300px 加宽到 **340px**
- 登录成功后调用 `useUserContext().syncFromStorage()` 同步 React 登录态(`loginBySms` 内部已写入 storage 但不返回数据)
- 弹窗 UI 使用 NutUI `Input` + `Button`,带 60 秒倒计时
+
+## 修复首页铃铛权限漏洞和非门店用户新订单提醒
+- **问题1**:非门店角色用户也能通过铃铛进入订单管理页
+- **问题2**:新订单提醒(红点badge + Toast)对非门店用户也显示
+- **修复**:
+ 1. `src/pages/index/index.tsx`:铃铛 badge 显示条件从 `isLoggedIn` 改为 `isClerk`(红点和计数仅门店角色可见)
+ 2. `src/pages/index/index.tsx`:`onNewOrders` 回调增加 `isClerkRef.current` 检查,非门店角色不弹 Toast/震动
+ 3. `src/pages/store/orders/index.tsx`:订单管理页增加访问控制,`getMyClerk()` 校验非门店角色自动跳回(防御性拦截)
+- `handleMessageClick` 中已有 `isClerk` 判断(店员→订单管理,普通用户→消息通知页),无需修改
diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx
index 8771df3..5eadd3a 100644
--- a/src/pages/index/index.tsx
+++ b/src/pages/index/index.tsx
@@ -85,6 +85,8 @@ const IndexPage: React.FC = () => {
return pageShopOrder({ page: 1, limit: 5 }).then(r => r?.list || [])
}, []),
onNewOrders: useCallback((count) => {
+ // 非门店店员不弹新订单提醒
+ if (!isClerkRef.current) return
Taro.vibrateShort({ type: 'medium' })
Taro.showToast({
title: `您有 ${count} 条新订单`,
@@ -189,14 +191,14 @@ const IndexPage: React.FC = () => {
🔔
- {isLoggedIn && newOrderCount > 0 && (
+ {isClerk && newOrderCount > 0 && (
{newOrderCount > 99 ? '99+' : newOrderCount}
)}
- {isLoggedIn && newOrderCount === 0 && (
+ {isClerk && newOrderCount === 0 && (
)}
diff --git a/src/pages/store/orders/index.tsx b/src/pages/store/orders/index.tsx
index 87a696a..9e24aee 100644
--- a/src/pages/store/orders/index.tsx
+++ b/src/pages/store/orders/index.tsx
@@ -6,6 +6,7 @@ import type {ShopOrder, ShopOrderParam} from '@/api/shop/shopOrder/model'
import {TenantId} from '@/config/app'
import {useNewOrderDetector} from '@/hooks/useNewOrderDetector'
import { getCompressedImageUrl } from '@/utils/image'
+import { getMyClerk } from '@/api/shop/shopStoreUser'
definePageConfig({
navigationBarTitleText: '订单管理',
@@ -156,6 +157,25 @@ export default function StoreOrdersPage() {
const pageSize = 10
const loadingRef = useRef(false)
+ // ─── 访问控制:仅门店店员可访问此页面 ──────────────────────
+ const [accessChecking, setAccessChecking] = useState(true)
+
+ useEffect(() => {
+ getMyClerk()
+ .then(data => {
+ if (!data) {
+ Taro.showToast({ title: '无权访问', icon: 'none', duration: 1500 })
+ setTimeout(() => Taro.navigateBack(), 1500)
+ } else {
+ setAccessChecking(false)
+ }
+ })
+ .catch(() => {
+ Taro.showToast({ title: '无权访问', icon: 'none', duration: 1500 })
+ setTimeout(() => Taro.navigateBack(), 1500)
+ })
+ }, [])
+
// ─── 新订单轮询检测 ──────────────────────────────────────────
const { newOrderCount, clearUnread } = useNewOrderDetector({
interval: 30000, // 30 秒轮询一次
@@ -530,6 +550,11 @@ export default function StoreOrdersPage() {
)
}
+ // 访问校验中或已拒绝:不渲染页面内容
+ if (accessChecking) {
+ return
+ }
+
return (
{/* Tab 栏 */}