diff --git a/package.json b/package.json index ed1915c..967d273 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "build:quickapp-webview": "uni build -p quickapp-webview", "build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei", "build:quickapp-webview-union": "uni build -p quickapp-webview-union", - "type-check": "vue-tsc --noEmit" + "type-check": "vue-tsc --noEmit", + "check:api-prefix": "bash scripts/check-api-prefix.sh" }, "dependencies": { "@dcloudio/uni-app": "3.0.0-alpha-5010320260611001", diff --git a/scripts/check-api-prefix.sh b/scripts/check-api-prefix.sh new file mode 100644 index 0000000..f994426 --- /dev/null +++ b/scripts/check-api-prefix.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# xuchao: 防止页面调用写死 /mp-api 前缀(request.ts 的 API_BASE 已含该前缀,重复会形成双前缀, +# 依赖 chaos 路由全局剥离才能工作,属错误写法)。命中即失败。 +set -e +if grep -rn --include='*.vue' --include='*.ts' -e "('/mp-api/" -e '("/mp-api/' src; then + echo "❌ 发现页面写死 /mp-api 前缀,请去掉(API_BASE 会自动拼接)" + exit 1 +fi +echo "✅ api 前缀检查通过" diff --git a/src/packages/content/pages/faq.vue b/src/packages/content/pages/faq.vue index 85d2228..df36571 100644 --- a/src/packages/content/pages/faq.vue +++ b/src/packages/content/pages/faq.vue @@ -49,7 +49,7 @@ const loading = ref(true) onMounted(async () => { try { - const data = await post('/mp-api/mpContent/queryList', { channel: 'pingxiang', type: 'FAQ' }) + const data = await post('/mpContent/queryList', { channel: 'pingxiang', type: 'FAQ' }) faqList.value = (data || []).map(n => ({ id: n.id, title: n.title, diff --git a/src/packages/content/pages/notice-list.vue b/src/packages/content/pages/notice-list.vue index 4442d4e..eb22162 100644 --- a/src/packages/content/pages/notice-list.vue +++ b/src/packages/content/pages/notice-list.vue @@ -41,7 +41,7 @@ const notices = ref([]) onMounted(async () => { try { - const data = await post('/mp-api/mpContent/queryList', { channel: 'pingxiang', type: 'NOTICE' }) + const data = await post('/mpContent/queryList', { channel: 'pingxiang', type: 'NOTICE' }) notices.value = (data || []).map(n => ({ id: n.id, title: n.title, diff --git a/src/packages/content/pages/scenic-detail.vue b/src/packages/content/pages/scenic-detail.vue index e3687a5..ddc9861 100644 --- a/src/packages/content/pages/scenic-detail.vue +++ b/src/packages/content/pages/scenic-detail.vue @@ -243,7 +243,7 @@ onLoad((options) => { async function fetchShopNotice(shopId: string) { try { - const res = await post('/mp-api/mpShopNotice/queryShopNoticePage', { + const res = await post('/mpShopNotice/queryShopNoticePage', { shopId, pageNo: 1, pageSize: 5, @@ -265,7 +265,7 @@ async function fetchDetail(shopId: string) { const phone = uni.getStorageSync('phone') as string if (phone) params.phone = phone - const res = await post('/mp-api/mpScenic/getScenicDetail', params) + const res = await post('/mpScenic/getScenicDetail', params) if (res) { scenic.value = { id: res.id || res.scenicId || shopId, diff --git a/src/packages/content/pages/scenic-list.vue b/src/packages/content/pages/scenic-list.vue index b91c865..b611c58 100644 --- a/src/packages/content/pages/scenic-list.vue +++ b/src/packages/content/pages/scenic-list.vue @@ -294,7 +294,7 @@ async function fetchScenicList(resetPage = true) { phone: uni.getStorageSync('phone') || '', } - const res = await post('/mp-api/mpScenic/queryScenicList', params) + const res = await post('/mpScenic/queryScenicList', params) const list = res?.list || res?.rows || res?.records || res || [] const totalCount = res?.total || res?.totalCount || 0 total.value = totalCount @@ -344,7 +344,7 @@ onLoad((query: any) => { }) onMounted(async () => { - const filterRes = await post('/mp-api/mpScenic/queryFilterOptions', { channel: 'pingxiang' }).catch(() => null) + const filterRes = await post('/mpScenic/queryFilterOptions', { channel: 'pingxiang' }).catch(() => null) if (filterRes) { const levels = filterRes.levels || filterRes.levelList || [] diff --git a/src/packages/content/pages/usage-guide.vue b/src/packages/content/pages/usage-guide.vue index a9d8191..0f6f36f 100644 --- a/src/packages/content/pages/usage-guide.vue +++ b/src/packages/content/pages/usage-guide.vue @@ -17,7 +17,7 @@ const loading = ref(true) onMounted(async () => { try { - const data = await post('/mp-api/mpContent/queryList', { channel: 'pingxiang', type: 'GUIDE' }) + const data = await post('/mpContent/queryList', { channel: 'pingxiang', type: 'GUIDE' }) if (data && data.length > 0) { imageUrl.value = data[0].imageUrl || '' } diff --git a/src/packages/user/api/douyin.ts b/src/packages/user/api/douyin.ts index 98a519b..13f98c9 100644 --- a/src/packages/user/api/douyin.ts +++ b/src/packages/user/api/douyin.ts @@ -82,7 +82,7 @@ export async function queryVoucherList(params: QueryVoucherListParams): Promise< await delay(300) return MOCK_VOUCHERS.map((v) => ({ ...v, mobile: params.mobile })) } - return post('/mp-api/douyin/voucherList', params) + return post('/douyin/voucherList', params) } /** @@ -94,5 +94,5 @@ export async function activateAndBind(params: ActivateAndBindParams): Promise('/mp-api/douyin/activateAndBind', params) + await post('/douyin/activateAndBind', params) } diff --git a/src/packages/user/pages/buy.vue b/src/packages/user/pages/buy.vue index e56f2bf..be75c93 100644 --- a/src/packages/user/pages/buy.vue +++ b/src/packages/user/pages/buy.vue @@ -85,7 +85,7 @@ const noticeHtml = computed(() => fixRichHtml(noticeContent.value)) /** 获取购卡须知富文本(type = CARD_PURCHASE_NOTICE) */ async function fetchPurchaseNotice() { try { - const res = await post('/mp-api/mpContent/queryList', { + const res = await post('/mpContent/queryList', { channel: 'pingxiang', type: 'CARD_PURCHASE_NOTICE', }) diff --git a/src/packages/user/pages/card-notice.vue b/src/packages/user/pages/card-notice.vue index 9824384..fec61ac 100644 --- a/src/packages/user/pages/card-notice.vue +++ b/src/packages/user/pages/card-notice.vue @@ -23,7 +23,7 @@ const loading = ref(true) onMounted(async () => { try { - const list = await post('/mp-api/mpContent/queryList', { channel: 'pingxiang', type: 'CARD_NOTICE' }) + const list = await post('/mpContent/queryList', { channel: 'pingxiang', type: 'CARD_NOTICE' }) content.value = list?.[0]?.content || '' } catch { showToast('加载失败') diff --git a/src/packages/user/pages/douyin-verify.vue b/src/packages/user/pages/douyin-verify.vue index e65b4b4..5e5db9c 100644 --- a/src/packages/user/pages/douyin-verify.vue +++ b/src/packages/user/pages/douyin-verify.vue @@ -310,7 +310,7 @@ const noticeHtml = computed(() => fixRichHtml(noticeContent.value)) /** 获取购卡须知富文本(type = CARD_PURCHASE_NOTICE) */ async function fetchPurchaseNotice() { try { - const res = await post('/mp-api/mpContent/queryList', { + const res = await post('/mpContent/queryList', { channel: 'pingxiang', type: 'CARD_PURCHASE_NOTICE', }) diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue index fade8a2..665195f 100644 --- a/src/pages/index/index.vue +++ b/src/pages/index/index.vue @@ -192,8 +192,8 @@ onMounted(() => { async function fetchBannersAndNotices() { try { const [bannerData, noticeData] = await Promise.all([ - post('/mp-api/mpContent/queryList', { channel: 'pingxiang', type: 'BANNER' }), - post('/mp-api/mpContent/queryList', { channel: 'pingxiang', type: 'NOTICE' }), + post('/mpContent/queryList', { channel: 'pingxiang', type: 'BANNER' }), + post('/mpContent/queryList', { channel: 'pingxiang', type: 'NOTICE' }), ]) banners.value = bannerData || [] announcements.value = (noticeData || []).map(n => ({ @@ -208,7 +208,7 @@ async function fetchBannersAndNotices() { /** 获取热门景点(独立加载,不阻塞 banner/公告渲染) */ async function fetchSpots() { try { - const spotsData = await post('/mp-api/mpScenic/queryScenicList', { channel: 'pingxiang', pageNo: 1, pageSize: 8, phone: uni.getStorageSync('phone') || '' }) + const spotsData = await post('/mpScenic/queryScenicList', { channel: 'pingxiang', pageNo: 1, pageSize: 8, phone: uni.getStorageSync('phone') || '' }) const list = spotsData?.list || spotsData || [] hotSpots.value = (Array.isArray(list) ? list : []).slice(0, 8).map((s: any) => ({ id: s.id || s.scenicId, diff --git a/src/pages/login/agreement.vue b/src/pages/login/agreement.vue index 07c7ddd..73b6b58 100644 --- a/src/pages/login/agreement.vue +++ b/src/pages/login/agreement.vue @@ -23,7 +23,7 @@ const loading = ref(true) onMounted(async () => { try { - const list = await post('/mp-api/mpContent/queryList', { channel: 'pingxiang', type: 'TERMS' }) + const list = await post('/mpContent/queryList', { channel: 'pingxiang', type: 'TERMS' }) content.value = list?.[0]?.content || '' } catch { showToast('加载失败') diff --git a/src/pages/login/privacy.vue b/src/pages/login/privacy.vue index 891a8d8..f3081e5 100644 --- a/src/pages/login/privacy.vue +++ b/src/pages/login/privacy.vue @@ -23,7 +23,7 @@ const loading = ref(true) onMounted(async () => { try { - const list = await post('/mp-api/mpContent/queryList', { channel: 'pingxiang', type: 'PRIVACY' }) + const list = await post('/mpContent/queryList', { channel: 'pingxiang', type: 'PRIVACY' }) content.value = list?.[0]?.content || '' } catch { showToast('加载失败') diff --git a/src/pages/qrcode/index.vue b/src/pages/qrcode/index.vue index 3a75711..dac9e26 100644 --- a/src/pages/qrcode/index.vue +++ b/src/pages/qrcode/index.vue @@ -233,7 +233,7 @@ async function fetchCards() { async function fetchEntryNotice() { if (entryNoticeLoaded.value) return try { - const list = await post('/mp-api/mpContent/queryList', { channel: 'pingxiang', type: 'ENTRY_NOTICE' }) + const list = await post('/mpContent/queryList', { channel: 'pingxiang', type: 'ENTRY_NOTICE' }) entryNotice.value = list?.[0]?.content || '' } catch { entryNotice.value = '' @@ -386,7 +386,7 @@ function onFeatureClick(item: { label: string }) { uni.showToast({ title: '请先选择一张旅游卡', icon: 'none' }) return } - post('/mp-api/mpCard/checkFaceBind', { cardModelId: card.cardModelId, cardNumber: card.cardNo }) + post('/mpCard/checkFaceBind', { cardModelId: card.cardModelId, cardNumber: card.cardNo }) .then((res) => { if (res?.needBindFace) { showFaceModal.value = true