hookehuyr

feat(config): 隐藏联系客服和意见反馈功能

- 添加 contactService 和 feedback 功能开关到 src/config/features.js
- 联系客服功能默认关闭,影响帮助中心页面的联系客服按钮和弹窗
- 意见反馈功能默认关闭,影响我的页面的意见反馈菜单项
- 修复 mine/index.vue 中未使用的 index 变量导致的 ESLint 警告
...@@ -14,6 +14,53 @@ ...@@ -14,6 +14,53 @@
14 14
15 --- 15 ---
16 16
17 +## [2026-02-13] - 功能开关配置
18 +
19 +### 配置
20 +- 添加功能开关到 `src/config/features.js`
21 + - `contactService: false` - 隐藏帮助中心联系客服
22 + - `feedback: false` - 隐藏我的页面意见反馈
23 +- 帮助中心页面 (`src/pages/help-center/index.vue`):
24 + - 导入 `features.js` 配置
25 + - 使用 `v-if="features.contactService"` 控制联系客服显示
26 +- 我的页面 (`src/pages/mine/index.vue`):
27 + - 导入 `features.js` 配置
28 + - 使用计算属性过滤菜单项
29 +- 修改 `v-for` key 为 `item.key` 提高稳定性
30 +
31 +### 修复
32 +- 移除 TypeScript �型的 JSDoc 注释(`@type {boolean}`),修复 eslint 警告
33 +
34 +**详细信息**
35 +- **影响文件**: src/config/features.js, src/pages/help-center/index.vue, src/pages/mine/index.vue
36 +- **技术栈**: Vue 3, Taro 4
37 +- **测试状态**: 已通过 (pnpm lint + pnpm test)
38 +- **备注**: 当功能开放时,只需在 features.js 中将对应开关改为 true 即可
39 +
40 +---
41 +
42 +### 配置
43 +- 添加功能开关到 `src/config/features.js`
44 + - `contactService: false` - 隐藏帮助中心联系客服
45 + - `feedback: false` - 隐藏我的页面意见反馈
46 +- 帮助中心页面 (`src/pages/help-center/index.vue`):
47 + - 导入 `features.js` 配置
48 + - 使用 `v-if="features.contactService"` 控制联系客服显示
49 +- 我的页面 (`src/pages/mine/index.vue`):
50 + - 导入 `features.js` 配置
51 + - 使用计算属性过滤菜单项
52 +- 修改 `v-for` key 为 `item.key` 提高稳定性
53 +
54 +**详细信息**
55 +- **影响文件**: src/config/features.js, src/pages/help-center/index.vue, src/pages/mine/index.vue
56 +- **技术栈**: Vue 3, Taro 4
57 +- **测试状态**: 已通过 (pnpm lint)
58 +- **备注**: 当功能开放时,只需在 features.js 中将对应开关改为 true 即可
59 +
60 +---
61 +
62 +---
63 +
17 ## [2026-02-13] - 首页标题样式调整 64 ## [2026-02-13] - 首页标题样式调整
18 65
19 ### 优化 66 ### 优化
......
...@@ -54,6 +54,20 @@ export const features = { ...@@ -54,6 +54,20 @@ export const features = {
54 * - 当字段为布尔值时:此配置无效 54 * - 当字段为布尔值时:此配置无效
55 */ 55 */
56 tabbarBadgeThreshold: 1 56 tabbarBadgeThreshold: 1
57 + ,
58 + /**
59 + * 联系客服功能
60 + * @description 控制帮助中心页面的联系客服按钮和弹窗显示
61 + * @default false - 默认关闭
62 + */
63 + contactService: false,
64 +
65 + /**
66 + * 意见反馈功能
67 + * @description 控制我的页面的意见反馈菜单项显示
68 + * @default false - 默认关闭
69 + */
70 + feedback: false
57 } 71 }
58 72
59 /** 73 /**
......
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
15 </view> 15 </view>
16 16
17 <!-- Contact Service --> 17 <!-- Contact Service -->
18 + <!-- 通过 features.contactService 控制显示/隐藏 -->
18 <view 19 <view
20 + v-if="features.contactService"
19 class="flex items-center justify-between w-full bg-white rounded-[24rpx] p-[32rpx] mb-[40rpx] shadow-sm relative overflow-hidden" 21 class="flex items-center justify-between w-full bg-white rounded-[24rpx] p-[32rpx] mb-[40rpx] shadow-sm relative overflow-hidden"
20 @tap="showContactPopup = true" 22 @tap="showContactPopup = true"
21 > 23 >
...@@ -129,6 +131,7 @@ import { ref, computed } from 'vue' ...@@ -129,6 +131,7 @@ import { ref, computed } from 'vue'
129 import NavHeader from '@/components/navigation/NavHeader.vue' 131 import NavHeader from '@/components/navigation/NavHeader.vue'
130 import IconFont from '@/components/icons/IconFont.vue' 132 import IconFont from '@/components/icons/IconFont.vue'
131 import SearchBar from '@/components/forms/SearchBar.vue' 133 import SearchBar from '@/components/forms/SearchBar.vue'
134 +import { features } from '@/config/features.js'
132 135
133 // Popup 状态 136 // Popup 状态
134 const showContactPopup = ref(false) 137 const showContactPopup = ref(false)
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
52 <!-- Menu List --> 52 <!-- Menu List -->
53 <!-- Added subtle styling to icons and softened the container --> 53 <!-- Added subtle styling to icons and softened the container -->
54 <view class="bg-white w-full rounded-[32rpx] shadow-sm mb-[40rpx] p-[16rpx]"> 54 <view class="bg-white w-full rounded-[32rpx] shadow-sm mb-[40rpx] p-[16rpx]">
55 - <view v-for="(item, index) in menuItems" :key="index" 55 + <view v-for="item in menuItems" :key="item.key"
56 class="flex items-center justify-between p-[24rpx] rounded-[20rpx] active:bg-gray-50 transition-all duration-200" 56 class="flex items-center justify-between p-[24rpx] rounded-[20rpx] active:bg-gray-50 transition-all duration-200"
57 @tap="handleMenuClick(item)"> 57 @tap="handleMenuClick(item)">
58 <view class="flex items-center"> 58 <view class="flex items-center">
...@@ -98,6 +98,7 @@ import { useUserStore } from '@/stores/user' ...@@ -98,6 +98,7 @@ import { useUserStore } from '@/stores/user'
98 import IconFont from '@/components/icons/IconFont.vue' 98 import IconFont from '@/components/icons/IconFont.vue'
99 import TabBar from '@/components/navigation/TabBar.vue' 99 import TabBar from '@/components/navigation/TabBar.vue'
100 import NavHeader from '@/components/navigation/NavHeader.vue' 100 import NavHeader from '@/components/navigation/NavHeader.vue'
101 +import { features } from '@/config/features.js'
101 import Taro, { useLoad, useDidShow } from '@tarojs/taro' 102 import Taro, { useLoad, useDidShow } from '@tarojs/taro'
102 import defaultAvatar from '@/assets/images/icon/avatar.svg' 103 import defaultAvatar from '@/assets/images/icon/avatar.svg'
103 104
...@@ -137,7 +138,7 @@ useDidShow(() => { ...@@ -137,7 +138,7 @@ useDidShow(() => {
137 138
138 // Modern Professional Palette 139 // Modern Professional Palette
139 // Using subtle background colors for icons to add vitality without being "playful" 140 // Using subtle background colors for icons to add vitality without being "playful"
140 -const menuItems = [ 141 +const rawMenuItems = [
141 { 142 {
142 key: 'plan', 143 key: 'plan',
143 title: '我的计划书', 144 title: '我的计划书',
...@@ -180,6 +181,17 @@ const menuItems = [ ...@@ -180,6 +181,17 @@ const menuItems = [
180 } 181 }
181 ] 182 ]
182 183
184 +// 根据功能配置过滤菜单项
185 +const menuItems = computed(() => {
186 + return rawMenuItems.filter(item => {
187 + // 如果配置了 feedback 关闭,过滤掉意见反馈菜单
188 + if (item.key === 'feedback' && !features.feedback) {
189 + return false
190 + }
191 + return true
192 + })
193 +})
194 +
183 const handleMenuClick = (item) => { 195 const handleMenuClick = (item) => {
184 if (item.path) { 196 if (item.path) {
185 go(item.path) 197 go(item.path)
......