sunshibo пре 1 месец
родитељ
комит
c1b535f3fb
6 измењених фајлова са 134 додато и 22 уклоњено
  1. 42 0
      App.vue
  2. 3 2
      components/Modal/BasicModal.vue
  3. 2 3
      components/TabBar.vue
  4. 8 0
      pages.json
  5. 68 0
      pages/launch/index.vue
  6. 11 17
      pages/numberOfDiners/index.vue

+ 42 - 0
App.vue

@@ -2,6 +2,8 @@
 import initConfig from '@/initConfig.js';
 // #ifdef MP-WEIXIN
 import { SCAN_QR_CACHE } from '@/settings/enums.js';
+import * as diningApi from '@/api/dining.js';
+import { useUserStore } from '@/store/user.js';
 // #endif
 
 /** 从 scene 或 query 中解析:二维码 s=店铺id,t=桌号id */
@@ -24,6 +26,44 @@ function parseSceneToStoreTable(sceneStr) {
 	return { storeId, tableId };
 }
 
+/**
+ * 查询桌位就餐状态,若 inDining 为 true 则跳转点餐页或选择人数页(未登录时)
+ * @param {Object} opts - { fromTabBar: boolean } 来自 TabBar 扫码时,inDining 为 false 需 switchTab 到 numberOfDiners
+ */
+async function checkTableDiningStatus(opts = {}) {
+	const tableid = uni.getStorageSync('currentTableId') || '';
+
+	try {
+		const res = await diningApi.GetTableDiningStatus(tableid);
+		const raw = (res && typeof res === 'object') ? res : {};
+		const inDining =
+			raw?.inDining === true ||
+			raw?.inDining === 'true' ||
+			raw?.data?.inDining === true ||
+			raw?.data?.inDining === 'true';
+		const dinerCount =
+			raw?.dinerCount ?? raw?.diner ?? raw?.data?.dinerCount ?? raw?.data?.diner ?? uni.getStorageSync('currentDiners') ?? 1;
+		if (!inDining) {
+			if (opts.fromTabBar) uni.switchTab({ url: '/pages/numberOfDiners/index' });
+			return;
+		}
+		uni.setStorageSync('currentDiners', dinerCount);
+		const userStore = useUserStore();
+		if (!userStore.getToken) {
+			uni.reLaunch({
+				url: `/pages/numberOfDiners/index?inDining=1&tableid=${encodeURIComponent(tableid)}&diners=${encodeURIComponent(dinerCount)}`
+			});
+			return;
+		}
+		uni.reLaunch({
+			url: `/pages/orderFood/index?tableid=${encodeURIComponent(tableid)}&diners=${encodeURIComponent(dinerCount)}`
+		});
+	} catch (err) {
+		console.warn('查询桌位就餐状态失败', err);
+		if (opts.fromTabBar) uni.switchTab({ url: '/pages/numberOfDiners/index' });
+	}
+}
+
 export default {
 	onLaunch: function (e) {
 		// 只有小程序执行
@@ -46,6 +86,8 @@ export default {
 		} catch (err) {
 			console.warn('缓存二维码启动参数失败', err);
 		}
+		// 冷启动时由 pages/launch/index 根据接口结果跳转;TabBar 扫码后由 App 统一调用接口并跳转
+		uni.$on('checkTableDiningStatus', () => checkTableDiningStatus({ fromTabBar: true }));
 		// #endif
 	},
 	onShow: function (res) {

+ 3 - 2
components/Modal/BasicModal.vue

@@ -19,8 +19,9 @@
 	})
 	
 	watch(getOpen, (v) => {
-		v && unref(popup).open()
-		!v && unref(popup).close()
+		const p = unref(popup);
+		if (!p) return;
+		v ? p.open() : p.close();
 	})
 	
 	function handleChange({ show }){

+ 2 - 3
components/TabBar.vue

@@ -77,9 +77,8 @@ function handleScanOrder() {
 			uni.setStorageSync(SCAN_QR_CACHE, JSON.stringify(payload));
 			if (storeId) uni.setStorageSync('currentStoreId', storeId);
 			if (tableId) uni.setStorageSync('currentTableId', tableId);
-			if (unref(getPath) !== menus[1].link) {
-				uni.switchTab({ url: menus[1].link });
-			}
+			// 由 App.vue 统一调用 table-dining-status 接口,根据结果跳转点餐页或选择人数页
+			uni.$emit('checkTableDiningStatus');
 		},
 		fail: (err) => {
 			if (err?.errMsg && !String(err.errMsg).includes('cancel')) {

+ 8 - 0
pages.json

@@ -1,6 +1,14 @@
 {
+	"entryPagePath": "pages/launch/index",
 	"pages": [
 		{
+			"path": "pages/launch/index",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom"
+			}
+		},
+		{
 			"path": "pages/index/index",
 			"style": {
 				"navigationBarTitleText": "首页",

+ 68 - 0
pages/launch/index.vue

@@ -0,0 +1,68 @@
+<template>
+  <!-- 启动页:根据 table-dining-status 接口结果跳转,避免先展示错误页面 -->
+  <view class="launch-wrap">
+    <view class="launch-loading">正在加载...</view>
+  </view>
+</template>
+
+<script setup>
+import { onLoad } from '@dcloudio/uni-app';
+import * as diningApi from '@/api/dining.js';
+import { useUserStore } from '@/store/user.js';
+
+const userStore = useUserStore();
+
+async function doRedirect() {
+  const tableid = uni.getStorageSync('currentTableId') || '';
+  if (!tableid) {
+    uni.reLaunch({ url: '/pages/index/index' });
+    return;
+  }
+  try {
+    const res = await diningApi.GetTableDiningStatus(tableid);
+    const raw = (res && typeof res === 'object') ? res : {};
+    const inDining =
+      raw?.inDining === true ||
+      raw?.inDining === 'true' ||
+      raw?.data?.inDining === true ||
+      raw?.data?.inDining === 'true';
+    const dinerCount =
+      raw?.dinerCount ?? raw?.diner ?? raw?.data?.dinerCount ?? raw?.data?.diner ?? uni.getStorageSync('currentDiners') ?? 1;
+    if (inDining) {
+      uni.setStorageSync('currentDiners', dinerCount);
+      if (!userStore.getToken) {
+        uni.reLaunch({
+          url: `/pages/numberOfDiners/index?inDining=1&tableid=${encodeURIComponent(tableid)}&diners=${encodeURIComponent(dinerCount)}`
+        });
+        return;
+      }
+      uni.reLaunch({
+        url: `/pages/orderFood/index?tableid=${encodeURIComponent(tableid)}&diners=${encodeURIComponent(dinerCount)}`
+      });
+      return;
+    }
+    uni.reLaunch({ url: '/pages/numberOfDiners/index' });
+  } catch (err) {
+    console.warn('查询桌位就餐状态失败,进入选择人数页', err);
+    uni.reLaunch({ url: '/pages/numberOfDiners/index' });
+  }
+}
+
+onLoad(() => {
+  doRedirect();
+});
+</script>
+
+<style scoped lang="scss">
+.launch-wrap {
+  min-height: 100vh;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: #f7f9fa;
+}
+.launch-loading {
+  font-size: 28rpx;
+  color: #999;
+}
+</style>

+ 11 - 17
pages/numberOfDiners/index.vue

@@ -32,6 +32,7 @@ const userStore = useUserStore();
 const diners = ref(12);
 const currentDiners = ref(1);
 const showLoginModal = ref(false);
+const checking = ref(false); // 是否正在查询桌位就餐状态
 // 登录成功后要跳转的点餐页参数(手机号授权完成后再跳转)
 const pendingNavigate = ref(null);
 
@@ -74,23 +75,16 @@ uni.reLaunch({
 });
 }
 
-onLoad(async (e) => {
-  const tableid = uni.getStorageSync('currentTableId') || '';
-  if (!tableid) return;
-  try {
-    const res = await diningApi.GetTableDiningStatus(tableid);
-    const raw = (res && typeof res === 'object') ? res : {};
-    const inDining = raw?.inDining === true;
-    const dinerCount = raw?.dinerCount ?? raw?.diner ?? uni.getStorageSync('currentDiners') ?? 1;
-    if (inDining) {
-      uni.setStorageSync('currentDiners', dinerCount);
-      uni.reLaunch({
-        url: `/pages/orderFood/index?tableid=${encodeURIComponent(tableid)}&diners=${encodeURIComponent(dinerCount)}`
-      });
-      return;
-    }
-  } catch (err) {
-    console.warn('查询桌位就餐状态失败,按正常流程', err);
+// 接口由 App.vue 统一调用;App.vue 在 inDining 为 true 且未登录时会重定向到本页并带 inDining=1,此时需弹出登录
+onLoad((options) => {
+  const inDining = options?.inDining === '1' || options?.inDining === 1;
+  const tableid = options?.tableid || uni.getStorageSync('currentTableId') || '';
+  const dinersVal = options?.diners || uni.getStorageSync('currentDiners') || 1;
+  if (inDining && tableid && !userStore.getToken) {
+    uni.setStorageSync('currentTableId', tableid);
+    uni.setStorageSync('currentDiners', dinersVal);
+    pendingNavigate.value = { tableid, dinersVal };
+    showLoginModal.value = true;
   }
 });
 </script>