|
|
@@ -0,0 +1,218 @@
|
|
|
+# mobile-h5 非生产环境首页色条 Implementation Plan
|
|
|
+
|
|
|
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
+
|
|
|
+**Goal:** 当 `APP_ENV` 为 `local` / `test` 时,在 mobile-h5 首页顶部显示醒目色条,避免误上传非生产包;`prod` 不显示。
|
|
|
+
|
|
|
+**Architecture:** 在 `utils/config.js` 抽出纯函数 `buildEnvBanner(appEnv)` 并导出 `ENV_BANNER`;首页 `pages/index/index.vue` 在绿头 Header 之上条件渲染色条。不改其他页面、不做 sticky、不改上传流程。
|
|
|
+
|
|
|
+**Tech Stack:** uni-app Vue(mobile-h5)、Node `assert` 单测(与现有 `utils/*.test.js` 一致)
|
|
|
+
|
|
|
+**Spec:** `docs/superpowers/specs/2026-10-11-mobile-h5-env-banner-design.md`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## File structure
|
|
|
+
|
|
|
+| 文件 | 职责 |
|
|
|
+| --- | --- |
|
|
|
+| `mobile-h5/utils/config.js` | 增加 `buildEnvBanner`、导出 `ENV_BANNER`;保留现有 `APP_ENV` / presets |
|
|
|
+| `mobile-h5/utils/env-banner.test.js` | 覆盖 local / test / prod / 未知值映射 |
|
|
|
+| `mobile-h5/pages/index/index.vue` | 条件渲染色条 + scoped 样式 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 1: `buildEnvBanner` 纯函数与单测
|
|
|
+
|
|
|
+**Files:**
|
|
|
+- Modify: `mobile-h5/utils/config.js`
|
|
|
+- Create: `mobile-h5/utils/env-banner.test.js`
|
|
|
+
|
|
|
+- [ ] **Step 1: 先写失败单测**
|
|
|
+
|
|
|
+创建 `mobile-h5/utils/env-banner.test.js`:
|
|
|
+
|
|
|
+```js
|
|
|
+import assert from 'node:assert/strict'
|
|
|
+import { buildEnvBanner } from './config.js'
|
|
|
+
|
|
|
+assert.deepEqual(buildEnvBanner('local'), {
|
|
|
+ show: true,
|
|
|
+ label: '本地环境',
|
|
|
+ tone: 'local'
|
|
|
+})
|
|
|
+assert.deepEqual(buildEnvBanner('test'), {
|
|
|
+ show: true,
|
|
|
+ label: '测试环境',
|
|
|
+ tone: 'test'
|
|
|
+})
|
|
|
+assert.deepEqual(buildEnvBanner('prod'), {
|
|
|
+ show: false,
|
|
|
+ label: '',
|
|
|
+ tone: ''
|
|
|
+})
|
|
|
+assert.deepEqual(buildEnvBanner('unknown'), {
|
|
|
+ show: false,
|
|
|
+ label: '',
|
|
|
+ tone: ''
|
|
|
+})
|
|
|
+
|
|
|
+console.log('env-banner.test.js: ok')
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 2: 跑测试确认失败**
|
|
|
+
|
|
|
+Run:
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-h5 && node utils/env-banner.test.js
|
|
|
+```
|
|
|
+
|
|
|
+Expected: FAIL(`buildEnvBanner` 未导出 / 未定义)
|
|
|
+
|
|
|
+- [ ] **Step 3: 实现 `buildEnvBanner` 与 `ENV_BANNER`**
|
|
|
+
|
|
|
+在 `mobile-h5/utils/config.js` 末尾(现有导出之后)增加:
|
|
|
+
|
|
|
+```js
|
|
|
+/** 首页非生产环境色条描述(prod / 未知值不展示) */
|
|
|
+export function buildEnvBanner(appEnv) {
|
|
|
+ if (appEnv === 'local') {
|
|
|
+ return { show: true, label: '本地环境', tone: 'local' }
|
|
|
+ }
|
|
|
+ if (appEnv === 'test') {
|
|
|
+ return { show: true, label: '测试环境', tone: 'test' }
|
|
|
+ }
|
|
|
+ return { show: false, label: '', tone: '' }
|
|
|
+}
|
|
|
+
|
|
|
+export const ENV_BANNER = buildEnvBanner(APP_ENV)
|
|
|
+```
|
|
|
+
|
|
|
+不要改动 `ENV_PRESETS` 与现有 URL 导出逻辑。若当前 `APP_ENV` 为本地联调值可保持不动(本任务不强制改回 `prod`)。
|
|
|
+
|
|
|
+- [ ] **Step 4: 跑测试确认通过**
|
|
|
+
|
|
|
+Run:
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-h5 && node utils/env-banner.test.js
|
|
|
+```
|
|
|
+
|
|
|
+Expected: 打印 `env-banner.test.js: ok`,exit code 0
|
|
|
+
|
|
|
+- [ ] **Step 5: Commit**
|
|
|
+
|
|
|
+```bash
|
|
|
+git add mobile-h5/utils/config.js mobile-h5/utils/env-banner.test.js
|
|
|
+git commit -m "$(cat <<'EOF'
|
|
|
+feat(mobile-h5): export ENV_BANNER from APP_ENV
|
|
|
+
|
|
|
+Add buildEnvBanner so the homepage can show a non-prod
|
|
|
+stripe without hardcoding environment labels.
|
|
|
+EOF
|
|
|
+)"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 2: 首页顶部色条 UI
|
|
|
+
|
|
|
+**Files:**
|
|
|
+- Modify: `mobile-h5/pages/index/index.vue`
|
|
|
+
|
|
|
+- [ ] **Step 1: 模板插入色条**
|
|
|
+
|
|
|
+在 `<view class="page-shell">` 内、`<view class="home-header">` **之前**插入:
|
|
|
+
|
|
|
+```html
|
|
|
+ <view
|
|
|
+ v-if="envBanner.show"
|
|
|
+ class="env-banner"
|
|
|
+ :class="'env-banner--' + envBanner.tone"
|
|
|
+ >
|
|
|
+ <text class="env-banner__text">{{ envBanner.label }}</text>
|
|
|
+ </view>
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 2: script 引入并挂到 data/computed**
|
|
|
+
|
|
|
+在 script 顶部增加:
|
|
|
+
|
|
|
+```js
|
|
|
+ import { ENV_BANNER } from '../../utils/config.js'
|
|
|
+```
|
|
|
+
|
|
|
+在 `data()` 中增加(或使用 computed,二选一;推荐 data 常量即可):
|
|
|
+
|
|
|
+```js
|
|
|
+ envBanner: ENV_BANNER,
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 3: scoped 样式**
|
|
|
+
|
|
|
+在现有 `<style lang="scss" scoped>` 中追加:
|
|
|
+
|
|
|
+```scss
|
|
|
+ .env-banner {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 100%;
|
|
|
+ padding: 12rpx 24rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .env-banner__text {
|
|
|
+ font-size: 22rpx;
|
|
|
+ font-weight: 700;
|
|
|
+ letter-spacing: 0.04em;
|
|
|
+ line-height: 1.3;
|
|
|
+ }
|
|
|
+
|
|
|
+ .env-banner--local {
|
|
|
+ background: #f59e0b;
|
|
|
+ color: #451a03;
|
|
|
+ }
|
|
|
+
|
|
|
+ .env-banner--test {
|
|
|
+ background: #3b82f6;
|
|
|
+ color: #eff6ff;
|
|
|
+ }
|
|
|
+```
|
|
|
+
|
|
|
+色条不加 status-bar 额外占位;安全区仍由现有 `.home-header` padding 处理。
|
|
|
+
|
|
|
+- [ ] **Step 4: 手工验收清单**
|
|
|
+
|
|
|
+1. `APP_ENV='local'` → 首页顶栏橙色「本地环境」
|
|
|
+2. `APP_ENV='test'` → 首页顶栏蓝色「测试环境」
|
|
|
+3. `APP_ENV='prod'` → 无色条
|
|
|
+4. 登录页 / OA 列表无色条
|
|
|
+
|
|
|
+- [ ] **Step 5: Commit**
|
|
|
+
|
|
|
+```bash
|
|
|
+git add mobile-h5/pages/index/index.vue
|
|
|
+git commit -m "$(cat <<'EOF'
|
|
|
+feat(mobile-h5): show non-prod env stripe on home
|
|
|
+
|
|
|
+Render a short local/test banner above the green header
|
|
|
+so the active APP_ENV is obvious before WeChat upload.
|
|
|
+EOF
|
|
|
+)"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Spec coverage check
|
|
|
+
|
|
|
+| Spec 要求 | Task |
|
|
|
+| --- | --- |
|
|
|
+| local/test 显示、prod 不显示 | Task 1 + 2 |
|
|
|
+| 仅首页、Header 之上、非 sticky | Task 2 |
|
|
|
+| 文案「本地环境」「测试环境」 | Task 1 |
|
|
|
+| 配色琥珀 / 蓝 | Task 2 |
|
|
|
+| `ENV_BANNER` 导出、页面不硬编码文案 | Task 1 + 2 |
|
|
|
+| 不加 status-bar 双重顶距 | Task 2 样式说明 |
|
|
|
+| 单测映射 | Task 1 |
|