App.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <script>
  2. import initConfig from '@/initConfig.js';
  3. // #ifdef MP-WEIXIN
  4. import { SCAN_QR_CACHE } from '@/settings/enums.js';
  5. import * as diningApi from '@/api/dining.js';
  6. import { useUserStore } from '@/store/user.js';
  7. // #endif
  8. /** 从 scene 或 query 中解析:二维码 s=店铺id,t=桌号id */
  9. function parseSceneToStoreTable(sceneStr) {
  10. const trim = (v) => (v == null ? '' : String(v).trim());
  11. let storeId = '';
  12. let tableId = '';
  13. if (!sceneStr) return { storeId, tableId };
  14. const str = trim(sceneStr);
  15. try {
  16. const parts = str.split('&');
  17. parts.forEach((pair) => {
  18. const [k, v] = pair.split('=').map((s) => (s ? decodeURIComponent(String(s).trim()) : ''));
  19. if (k === 's' || k === 'storeId' || k === 'store_id') storeId = trim(v);
  20. if (k === 't' || k === 'tableId' || k === 'table_id' || k === 'tableid') tableId = trim(v);
  21. });
  22. } catch (err) {
  23. console.warn('parseSceneToStoreTable', err);
  24. }
  25. return { storeId, tableId };
  26. }
  27. /**
  28. * 查询桌位就餐状态,若 inDining 为 true 则跳转点餐页或选择人数页(未登录时)
  29. * @param {Object} opts - { fromTabBar: boolean } 来自 TabBar 扫码时,inDining 为 false 需 switchTab 到 numberOfDiners
  30. */
  31. async function checkTableDiningStatus(opts = {}) {
  32. const tableid = uni.getStorageSync('currentTableId') || '';
  33. try {
  34. const res = await diningApi.GetTableDiningStatus(tableid);
  35. const raw = (res && typeof res === 'object') ? res : {};
  36. const inDining =
  37. raw?.inDining === true ||
  38. raw?.inDining === 'true' ||
  39. raw?.data?.inDining === true ||
  40. raw?.data?.inDining === 'true';
  41. const dinerCount =
  42. raw?.dinerCount ?? raw?.diner ?? raw?.data?.dinerCount ?? raw?.data?.diner ?? uni.getStorageSync('currentDiners') ?? 1;
  43. if (!inDining) {
  44. if (opts.fromTabBar) uni.switchTab({ url: '/pages/numberOfDiners/index' });
  45. return;
  46. }
  47. uni.setStorageSync('currentDiners', dinerCount);
  48. const userStore = useUserStore();
  49. if (!userStore.getToken) {
  50. uni.reLaunch({
  51. url: `/pages/numberOfDiners/index?inDining=1&tableid=${encodeURIComponent(tableid)}&diners=${encodeURIComponent(dinerCount)}`
  52. });
  53. return;
  54. }
  55. uni.reLaunch({
  56. url: `/pages/orderFood/index?tableid=${encodeURIComponent(tableid)}&diners=${encodeURIComponent(dinerCount)}`
  57. });
  58. } catch (err) {
  59. console.warn('查询桌位就餐状态失败', err);
  60. if (opts.fromTabBar) uni.switchTab({ url: '/pages/numberOfDiners/index' });
  61. }
  62. }
  63. export default {
  64. onLaunch: function (e) {
  65. // 只有小程序执行
  66. // #ifdef MP-WEIXIN
  67. initConfig();
  68. // 通过二维码编译/扫码进入:将二维码携带的信息缓存(query.scene 为小程序码参数,query.q 为普通链接二维码)
  69. try {
  70. const sceneEnc = e?.query?.scene;
  71. const qEnc = e?.query?.q;
  72. const scene = sceneEnc != null && sceneEnc !== '' ? decodeURIComponent(String(sceneEnc)) : '';
  73. const q = qEnc != null && qEnc !== '' ? decodeURIComponent(String(qEnc)) : '';
  74. const rawFromQR = scene || q || '';
  75. if (rawFromQR) {
  76. const { storeId, tableId } = parseSceneToStoreTable(rawFromQR);
  77. const payload = { raw: rawFromQR, storeId, tableId };
  78. uni.setStorageSync(SCAN_QR_CACHE, JSON.stringify(payload));
  79. if (storeId) uni.setStorageSync('currentStoreId', storeId);
  80. if (tableId) uni.setStorageSync('currentTableId', tableId);
  81. }
  82. } catch (err) {
  83. console.warn('缓存二维码启动参数失败', err);
  84. }
  85. // 冷启动时由 pages/launch/index 根据接口结果跳转;TabBar 扫码后由 App 统一调用接口并跳转
  86. uni.$on('checkTableDiningStatus', () => checkTableDiningStatus({ fromTabBar: true }));
  87. // #endif
  88. },
  89. onShow: function (res) {
  90. console.log('App Show', res);
  91. // 是否是从被打开的小程序返回
  92. const { appId, extraData } = res.referrerInfo;
  93. if (appId && extraData) {
  94. uni.$emit('listener:ArBack', res.referrerInfo);
  95. }
  96. },
  97. onHide: function () {
  98. console.log('App Hide');
  99. }
  100. };
  101. </script>
  102. <style lang="scss">
  103. view,
  104. image,
  105. label {
  106. box-sizing: border-box;
  107. word-break: break-all;
  108. }
  109. image {
  110. height: auto;
  111. width: auto;
  112. }
  113. /* #ifndef APP-NVUE */
  114. // 设置整个项目的背景色
  115. page {
  116. background-color: #f7f9fa;
  117. }
  118. /* #endif */
  119. // 弹性盒子
  120. .flex {
  121. display: flex;
  122. &-none {
  123. flex: none;
  124. }
  125. &-1 {
  126. flex: 1;
  127. }
  128. &-y {
  129. flex-direction: column;
  130. }
  131. &-top {
  132. align-items: flex-start !important;
  133. }
  134. // 顶部对齐
  135. &-bottom {
  136. align-items: flex-end;
  137. }
  138. // 底部对齐
  139. &-content-end {
  140. justify-content: flex-end;
  141. }
  142. // 水平靠右 || 垂直靠下对齐
  143. &-center {
  144. align-items: center;
  145. }
  146. // 水平居中对齐
  147. &-center-center {
  148. align-items: center;
  149. justify-content: center;
  150. }
  151. // 水平垂直居中
  152. &-between {
  153. justify-content: space-between;
  154. }
  155. // 两端不留间隙对齐
  156. &-around {
  157. justify-content: space-around;
  158. }
  159. // 两端留间隙对齐
  160. &-wrap {
  161. flex-wrap: wrap;
  162. }
  163. // 允许换行
  164. }
  165. .w-0 {
  166. width: 0;
  167. }
  168. .h-0 {
  169. height: 0;
  170. }
  171. // 隐藏显示多少行
  172. .ellipsis {
  173. overflow: hidden;
  174. text-overflow: ellipsis;
  175. display: -webkit-box;
  176. -webkit-box-orient: vertical;
  177. -webkit-line-clamp: 1;
  178. word-break: break-all;
  179. @for $i from 2 through 10 {
  180. &.ellipsis-#{$i} {
  181. -webkit-line-clamp: $i;
  182. }
  183. }
  184. &-no {
  185. display: block;
  186. }
  187. }
  188. // 点击时的透明度
  189. .hover-active {
  190. opacity: 0.8 !important;
  191. }
  192. // 底部安全区
  193. .safe-area {
  194. padding-bottom: constant(safe-area-inset-bottom);
  195. /* 兼容 iOS < 11.2 */
  196. padding-bottom: env(safe-area-inset-bottom);
  197. /* 兼容 iOS >= 11.2 */
  198. }
  199. .ql-editor.ql-blank:before {
  200. color: #999999;
  201. font-size: 28rpx;
  202. font-style: normal;
  203. }
  204. </style>