From 56e672219e7f54171efb77e28457c868c24d088e Mon Sep 17 00:00:00 2001 From: xcbyy <2578898740@qq.com> Date: Tue, 13 Oct 2026 16:54:55 +0800 Subject: [PATCH] fix(modal): resolve premature modal closing caused by unsupported click.self in wechat miniprogram --- pwuniapp/pages/activity/create.vue | 10 ++++++++-- pwuniapp/pages/activity/detail.vue | 10 ++++++++-- pwuniapp/pages/community/index.vue | 8 ++++---- pwuniapp/pages/expert/detail.vue | 10 ++++++++-- pwuniapp/pages/expert/workspace.vue | 14 ++++++++++---- pwuniapp/pages/order/create.vue | 10 ++++++++-- pwuniapp/pages/order/list.vue | 18 +++++++++++------ server/tests/content-security.spec.ts | 28 +++++++++++++++++++++++++++ 8 files changed, 86 insertions(+), 22 deletions(-) diff --git a/pwuniapp/pages/activity/create.vue b/pwuniapp/pages/activity/create.vue index b84e543..5ad2292 100644 --- a/pwuniapp/pages/activity/create.vue +++ b/pwuniapp/pages/activity/create.vue @@ -288,8 +288,8 @@ - - + + 同城线下组局安全风控提示 @@ -376,6 +376,12 @@ const calcTotalFee = computed(() => { return Number(form.value.totalFee) || 0; }); +const stopPropagation = (e) => { + if (e && typeof e.stopPropagation === 'function') { + e.stopPropagation(); + } +}; + const riskModalVisible = ref(false); const recommendPublicZones = ref([ '北京市朝阳区三里屯太古里 (AAA公开商圈)', diff --git a/pwuniapp/pages/activity/detail.vue b/pwuniapp/pages/activity/detail.vue index c6b47ad..bde7b28 100644 --- a/pwuniapp/pages/activity/detail.vue +++ b/pwuniapp/pages/activity/detail.vue @@ -194,8 +194,8 @@ - - + + {{ modalMode === 'APPEND' ? '房主追加金额' : '房主手动调整出价' }} @@ -438,6 +438,12 @@ onUnmounted(() => { uni.$off('theme-change', onThemeChanged); }); +const stopPropagation = (e) => { + if (e && typeof e.stopPropagation === 'function') { + e.stopPropagation(); + } +}; + const activity = ref({ id: '', title: '同城生活组局', diff --git a/pwuniapp/pages/community/index.vue b/pwuniapp/pages/community/index.vue index 0a2b985..843c20a 100644 --- a/pwuniapp/pages/community/index.vue +++ b/pwuniapp/pages/community/index.vue @@ -259,8 +259,8 @@ - - + + 动态评论 @@ -317,8 +317,8 @@ - - + + {{ communityNotice.tag || '置顶推荐' }} diff --git a/pwuniapp/pages/expert/detail.vue b/pwuniapp/pages/expert/detail.vue index 14b43fa..3e29f95 100644 --- a/pwuniapp/pages/expert/detail.vue +++ b/pwuniapp/pages/expert/detail.vue @@ -184,8 +184,8 @@ - - + + 举报违规行为 @@ -264,6 +264,12 @@ onUnmounted(() => { uni.$off('theme-change', onThemeChanged); }); +const stopPropagation = (e) => { + if (e && typeof e.stopPropagation === 'function') { + e.stopPropagation(); + } +}; + const isLoading = ref(true); const isFav = ref(false); const expert = ref({ diff --git a/pwuniapp/pages/expert/workspace.vue b/pwuniapp/pages/expert/workspace.vue index a11ba28..ff72785 100644 --- a/pwuniapp/pages/expert/workspace.vue +++ b/pwuniapp/pages/expert/workspace.vue @@ -244,8 +244,8 @@ - - + + 参与人身份核验确认 门票有效 @@ -343,8 +343,8 @@ - - + + 提现记录与审批状态 @@ -420,6 +420,12 @@ const todayIncome = ref('0.00'); const todayOrdersCount = ref(0); const waitingVerifyCount = ref(0); +const stopPropagation = (e) => { + if (e && typeof e.stopPropagation === 'function') { + e.stopPropagation(); + } +}; + // 多维收益统计走势状态 const trendPeriod = ref('daily'); const trendMetric = ref('income'); diff --git a/pwuniapp/pages/order/create.vue b/pwuniapp/pages/order/create.vue index 22b5f00..ca32da7 100644 --- a/pwuniapp/pages/order/create.vue +++ b/pwuniapp/pages/order/create.vue @@ -196,8 +196,8 @@ - - + + 选择优惠券 @@ -269,6 +269,12 @@ onUnmounted(() => { uni.$off('theme-change', onThemeChanged); }); +const stopPropagation = (e) => { + if (e && typeof e.stopPropagation === 'function') { + e.stopPropagation(); + } +}; + const loadUserWallet = async () => { try { const u = await getUserProfile(1001); diff --git a/pwuniapp/pages/order/list.vue b/pwuniapp/pages/order/list.vue index 38516e7..8e78a9b 100644 --- a/pwuniapp/pages/order/list.vue +++ b/pwuniapp/pages/order/list.vue @@ -110,8 +110,8 @@ - - + + 服务体验评价 @@ -184,8 +184,8 @@ - - + + 申请退款与仲裁 @@ -263,8 +263,8 @@ - - + + 举报不良陪玩 @@ -373,6 +373,12 @@ const navStyle = computed(() => { }; }); +const stopPropagation = (e) => { + if (e && typeof e.stopPropagation === 'function') { + e.stopPropagation(); + } +}; + const handleBack = () => { const pages = getCurrentPages(); if (pages && pages.length > 1) { diff --git a/server/tests/content-security.spec.ts b/server/tests/content-security.spec.ts index daf1ab6..d920235 100644 --- a/server/tests/content-security.spec.ts +++ b/server/tests/content-security.spec.ts @@ -1074,6 +1074,34 @@ describe('ContentSecurityService & Compliance Architecture (TDD 微信内容安 expect(content).toContain('ICONS.chevronRight'); }); + it('全端弹窗遮罩层严禁使用微信小程序不兼容的 @click.self 且内部卡片必须使用 stopPropagation 阻断冒泡', () => { + const orderListPath = path.join(rootDir, 'pwuniapp', 'pages', 'order', 'list.vue'); + const orderCreatePath = path.join(rootDir, 'pwuniapp', 'pages', 'order', 'create.vue'); + const expertDetailPath = path.join(rootDir, 'pwuniapp', 'pages', 'expert', 'detail.vue'); + const expertWorkspacePath = path.join(rootDir, 'pwuniapp', 'pages', 'expert', 'workspace.vue'); + const communityPath = path.join(rootDir, 'pwuniapp', 'pages', 'community', 'index.vue'); + + const orderListContent = fs.readFileSync(orderListPath, 'utf-8'); + expect(orderListContent).not.toContain('@click.self'); + expect(orderListContent).toContain('@click.stop="stopPropagation"'); + + const orderCreateContent = fs.readFileSync(orderCreatePath, 'utf-8'); + expect(orderCreateContent).not.toContain('@click.self'); + expect(orderCreateContent).toContain('@click.stop="stopPropagation"'); + + const expertDetailContent = fs.readFileSync(expertDetailPath, 'utf-8'); + expect(expertDetailContent).not.toContain('@click.self'); + expect(expertDetailContent).toContain('@click.stop="stopPropagation"'); + + const expertWorkspaceContent = fs.readFileSync(expertWorkspacePath, 'utf-8'); + expect(expertWorkspaceContent).not.toContain('@click.self'); + expect(expertWorkspaceContent).toContain('@click.stop="stopPropagation"'); + + const communityContent = fs.readFileSync(communityPath, 'utf-8'); + expect(communityContent).not.toContain('@click.self'); + expect(communityContent).toContain('@click.stop="stopPropagation"'); + }); + it('所有状态持久化修复代码与测试严禁包含任何系统 Emoji 违规字符', () => { const actDetailPath = path.join(rootDir, 'pwuniapp', 'pages', 'activity', 'detail.vue'); const ticketPath = path.join(rootDir, 'pwuniapp', 'pages', 'activity', 'my-ticket.vue');