fix(order-list): add immersive custom navigation bar and return button with dual-theme adaptation
这个提交包含在:
@@ -1,21 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="order-list-container" :class="{ 'theme-warm': currentThemeKey === 'warm' }" :style="navStyle">
|
<view class="order-list-container" :class="{ 'theme-warm': currentThemeKey === 'warm' }" :style="navStyle">
|
||||||
<!-- 顶部状态分类 Tab -->
|
<!-- 顶部沉浸式自定义导航栏 -->
|
||||||
<view class="tab-header">
|
<view class="custom-nav-bar">
|
||||||
<view
|
<view class="nav-content">
|
||||||
v-for="tab in tabs"
|
<view class="btn-nav-back btn-active" @click="handleBack">
|
||||||
:key="tab.key"
|
<image class="nav-back-icon" :src="ICONS.chevronLeft" mode="aspectFit" />
|
||||||
class="tab-item btn-active"
|
</view>
|
||||||
:class="{ active: currentTab === tab.key }"
|
<view class="nav-title-wrap">
|
||||||
@click="switchTab(tab.key)"
|
<text class="nav-title">我的订单</text>
|
||||||
>
|
</view>
|
||||||
<text class="tab-text">{{ tab.name }}</text>
|
<!-- 胶囊右侧对称避让占位 -->
|
||||||
<view class="tab-indicator" v-if="currentTab === tab.key"></view>
|
<view class="nav-capsule-placeholder"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 订单列表 -->
|
<!-- 主体内容区域 -->
|
||||||
<view class="orders-wrap">
|
<view class="order-content-body">
|
||||||
|
<!-- 顶部状态分类 Tab -->
|
||||||
|
<view class="tab-header">
|
||||||
|
<view
|
||||||
|
v-for="tab in tabs"
|
||||||
|
:key="tab.key"
|
||||||
|
class="tab-item btn-active"
|
||||||
|
:class="{ active: currentTab === tab.key }"
|
||||||
|
@click="switchTab(tab.key)"
|
||||||
|
>
|
||||||
|
<text class="tab-text">{{ tab.name }}</text>
|
||||||
|
<view class="tab-indicator" v-if="currentTab === tab.key"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单列表 -->
|
||||||
|
<view class="orders-wrap">
|
||||||
<view
|
<view
|
||||||
v-for="order in filteredOrders"
|
v-for="order in filteredOrders"
|
||||||
:key="order.id"
|
:key="order.id"
|
||||||
@@ -91,6 +107,7 @@
|
|||||||
<button class="empty-btn btn-active" @click="goToExplore">前往发现大厅寻找大神</button>
|
<button class="empty-btn btn-active" @click="goToExplore">前往发现大厅寻找大神</button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 评价大神服务体验交互弹窗 -->
|
<!-- 评价大神服务体验交互弹窗 -->
|
||||||
<view class="review-modal-mask" v-if="reviewModalVisible" @click.self="closeReviewModal">
|
<view class="review-modal-mask" v-if="reviewModalVisible" @click.self="closeReviewModal">
|
||||||
@@ -350,10 +367,23 @@ let countdownTimer = null;
|
|||||||
|
|
||||||
const navStyle = computed(() => {
|
const navStyle = computed(() => {
|
||||||
return {
|
return {
|
||||||
'--safe-header-gap': `${navInfo.value.totalHeaderHeight}px`
|
'--safe-header-gap': `${navInfo.value.safeHeaderGap}px`,
|
||||||
|
'--capsule-right-space': `${navInfo.value.capsuleRightSpace}px`,
|
||||||
|
'--capsule-height': `${navInfo.value.capsuleHeight}px`
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
if (pages && pages.length > 1) {
|
||||||
|
uni.navigateBack();
|
||||||
|
} else {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/index/index'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const onThemeChanged = (key) => {
|
const onThemeChanged = (key) => {
|
||||||
currentThemeKey.value = key;
|
currentThemeKey.value = key;
|
||||||
applyThemeToNativeUI(key);
|
applyThemeToNativeUI(key);
|
||||||
@@ -806,7 +836,70 @@ const submitReview = async () => {
|
|||||||
.order-list-container {
|
.order-list-container {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: #0A0F1D;
|
background-color: #0A0F1D;
|
||||||
padding: var(--safe-header-gap, 36rpx) 32rpx calc(160rpx + env(safe-area-inset-bottom));
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 顶部沉浸式自定义顶栏 */
|
||||||
|
.custom-nav-bar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
padding-top: var(--safe-header-gap, 44px);
|
||||||
|
background: rgba(10, 15, 29, 0.92);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
-webkit-backdrop-filter: blur(20px);
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
|
||||||
|
.nav-content {
|
||||||
|
position: relative;
|
||||||
|
height: var(--capsule-height, 44px);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 24rpx;
|
||||||
|
|
||||||
|
.btn-nav-back {
|
||||||
|
width: 64rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||||
|
|
||||||
|
.nav-back-icon {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-title-wrap {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.nav-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #F8FAFC;
|
||||||
|
letter-spacing: 1rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-capsule-placeholder {
|
||||||
|
width: var(--capsule-right-space, 96px);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-content-body {
|
||||||
|
padding: 24rpx 32rpx calc(160rpx + env(safe-area-inset-bottom));
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-header {
|
.tab-header {
|
||||||
@@ -1133,6 +1226,22 @@ const submitReview = async () => {
|
|||||||
.order-list-container.theme-warm {
|
.order-list-container.theme-warm {
|
||||||
background-color: #FDFBF7;
|
background-color: #FDFBF7;
|
||||||
|
|
||||||
|
.custom-nav-bar {
|
||||||
|
background: rgba(255, 253, 249, 0.95);
|
||||||
|
border-bottom: 1px solid rgba(234, 88, 12, 0.1);
|
||||||
|
|
||||||
|
.nav-content {
|
||||||
|
.btn-nav-back {
|
||||||
|
background: #FFF7ED;
|
||||||
|
border-color: #FED7AA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-title-wrap .nav-title {
|
||||||
|
color: #1C1917;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tab-header {
|
.tab-header {
|
||||||
background-color: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
border-color: #F0ECE4;
|
border-color: #F0ECE4;
|
||||||
|
|||||||
@@ -836,6 +836,42 @@ describe('ContentSecurityService & Compliance Architecture (TDD 微信内容安
|
|||||||
expect(emojiRegex.test(fs.readFileSync(serverIndexPath, 'utf-8'))).toBe(false);
|
expect(emojiRegex.test(fs.readFileSync(serverIndexPath, 'utf-8'))).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('19. 订单列表页面沉浸式导航栏与返回按钮规范验证 (pages/order/list.vue)', () => {
|
||||||
|
const orderListPath = path.join(rootDir, 'pwuniapp', 'pages', 'order', 'list.vue');
|
||||||
|
|
||||||
|
it('订单列表页面必须包含 custom-nav-bar 沉浸式导航栏与返回上一级按钮', () => {
|
||||||
|
expect(fs.existsSync(orderListPath)).toBe(true);
|
||||||
|
const content = fs.readFileSync(orderListPath, 'utf-8');
|
||||||
|
expect(content).toContain('custom-nav-bar');
|
||||||
|
expect(content).toContain('btn-nav-back');
|
||||||
|
expect(content).toContain('handleBack');
|
||||||
|
expect(content).toContain('nav-title');
|
||||||
|
expect(content).toContain('我的订单');
|
||||||
|
expect(content).toContain('nav-capsule-placeholder');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('必须包含智能返回上一级与首页兜底路由控制逻辑', () => {
|
||||||
|
const content = fs.readFileSync(orderListPath, 'utf-8');
|
||||||
|
expect(content).toContain('getCurrentPages()');
|
||||||
|
expect(content).toContain('uni.navigateBack()');
|
||||||
|
expect(content).toContain('uni.switchTab');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('必须适配微信小程序胶囊安全避让变量与冷暖双主题', () => {
|
||||||
|
const content = fs.readFileSync(orderListPath, 'utf-8');
|
||||||
|
expect(content).toContain('--safe-header-gap');
|
||||||
|
expect(content).toContain('--capsule-right-space');
|
||||||
|
expect(content).toContain('--capsule-height');
|
||||||
|
expect(content).toContain('.order-list-container.theme-warm');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('订单列表页面源码与测试严禁包含任何系统 Emoji 违规字符', () => {
|
||||||
|
const content = fs.readFileSync(orderListPath, 'utf-8');
|
||||||
|
const emojiRegex = /(?:\p{Extended_Pictographic}|\p{Emoji_Presentation}|[\u2600-\u27BF])/u;
|
||||||
|
expect(emojiRegex.test(content)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户