--- 项目名称: 91pron H5 客户端 # 与 DMP 或内部命名一致时请自行替换 一级部门: 北斗 # 请填写一级部门名称 二级部门: 瑞升 # 请填写二级部门名称,无则留空 DMP编码: JHA-204 # 无则留空 项目类型: H5 # 可选值: # H5 / APP / PC / 服务 / 组件 / 工具 / AI / 中间件 开发语言: Node # 可选值: # GO / Java / PHP / Node 项目负责人: DN4929,DN4868 # 员工编号,多个用逗号隔开,这里的负责是这套代码的负责人 运维负责人: DN9460,DN9651,DN4792 # 负责部署、监控、K8S、发布、证书等 产品负责人: YY1145,YY1208 # 项目产品经理 项目成员: DN4929,DN4868 项目状态: 开发中 # 可选值: # 开发中 / 维护中 / 已停止 / 已归档 项目级别: 中 # 可选值: # 高 / 中 / 低 核心分支: main 代码仓库: - https://bd-git.jsyyds.com/ruisheng/jha-204-91pron/frontend/91porn-landpage-client.git 最后审计人: 最后审计时间: 告警群: 备注: - `package.json` 中 `name` 为 `landpage`,仓库/目录名为 `91pron-landpage-client`。 - 业务 `appId` 为 **204**(见 `src/views/land/index.vue`),埋点 `appId` 为 **JHA-204**(见 `public/index.html` 与 `src/utils/eventTracker.js`)。 - 接口路径前缀为 **`/plm`**,开发环境由 `vue.config.js` 代理;选线候选域名见各环境 `.env.*` 中的 `VUE_APP_BASE_HOSTS`(JSON 数组),勿将含密钥、内网地址的未脱敏内容对外发布。 --- # 1. 项目说明 本仓库为面向 **移动端 H5 浏览器**(含 PC 落地页展示)的 **Vue 2 + Vue CLI 4** 单页应用,语言为 **JavaScript**(无 TypeScript)。UI 同时使用 **Vant 2** 与 **Element UI 2**,状态管理为 **Vuex 3**(当前 store 为空壳,业务数据主要在页面组件内维护),路由为 **Vue Router 3**,模式为 **`history`(HTML5 History)**(见 `src/router/index.js`)。入口为 `src/main.js`,挂载 Router、Vuex、Vant、Element、剪贴板、Swiper、Google Analytics(`vue-analytics`)等。 **业务定位:** 91pron **App 下载落地页**(Landing Page),单路由 `/` 对应 `src/views/land/index.vue`。根据设备类型(`userAgent`)与模板版本(`version`: `A` / `B`)切换子组件: | 场景 | 组件 | |------|------| | 移动端 + 版本 A | `mobile1.vue` | | 移动端 + 版本 B | `mobile2.vue` | | PC 端 | `pc.vue`(A/B 共用) | | 特定 PC URL | `tips.vue` | | 接口失败选线 | `selectLinePopup.vue` | 子组件通过 props 接收 `os`、`configs`、`switchData` 等,通过 `$emit` 向上传递 `getApkInfo`、`recordClick` 等事件。 **启动流程(`land/index.vue`):** 1. 解析 URL 查询参数(`dc`、`ch`、`pc` 等)并写入 sessionStorage。 2. 调用 `getTemplate`(`/plm/okn/ijb/nuS0EDXSczKgf3Xh`)拉取按钮/下载配置(`switchData`、`configs`、各平台下载链接)。 3. 上报落地页展示埋点 `landingPageView`(`eventTracker.js` → `window.tracker` / LandingSDK)。 4. 用户点击下载时:`recordClick` 上报点击并调用 `getApkInfo`;`handleGetApkInfo` 根据终端类型跳转 iOS/Android 下载链接。 5. 接口失败时弹出 **选线弹窗**,用户选择后切换 `axios.defaults.baseURL` 并重试。 **技术栈要点:** - 构建:**Vue CLI 4**(`vue.config.js`),生产使用 **compression-webpack-plugin** 生成 **gzip** 产物。 - 样式:**Sass/SCSS**(`node-sass` + `sass-loader`),`element-variables.scss` 定制 Element 主题。 - 适配:**lib-flexible** + **postcss-plugin-px2rem**(`rootValue: 37.5`,设计稿基准 375px);带 **`pcm`** 选择器前缀的样式不转 rem(PC 端)。 - 网络:**axios** 封装于 `src/utils/request.js`,默认 `baseURL: '/'`,业务码 `200` 视为成功。 - 埋点:`public/index.html` 异步加载 **`/sdk/landing-sdk-v1.1.1.js`**(LandingSDK),`src/utils/eventTracker.js` 封装 `landing_page_view` / `landing_page_click` 事件及设备信息解析。 - 其他:**qrcode** 生成 PC 扫码图、**vue-clipboard2** 复制渠道参数、**moment**、**swiper**、**vue-analytics**(UA-165940626-2)、**register-service-worker**(PWA 配置于 `vue.config.js`)。 **Node 版本:** 仓库 `README.md` 建议使用 **12.18.1**。 **常用脚本(`package.json`):** | 命令 | 说明 | |------|------| | `npm run dev` | 本地开发(`vue-cli-service serve`) | | `npm run build` | 生产构建 | | `npm run test-build` | 测试环境构建(`--mode test`) | | `npm run lint` | ESLint(`src` 下 `.js` / `.vue`,带 `--fix`) | | `npm run test:unit` | Jest 单元测试 | **开发环境代理(`vue.config.js`):** | 路径 | 说明 | |------|------| | `/plm` | 业务接口代理(`target` 以文件内配置为准) | | `/dcserv` | 代理至 `https://api.shuifeng.cc`(调试用途) | **项目目录结构(核心):** ``` 91pron-landpage-client/ ├── public/ │ ├── index.html # 入口 HTML,含 LandingSDK 与 SEO meta │ └── sdk/landing-sdk-v1.1.1.js ├── src/ │ ├── main.js # 入口:Router、Vuex、Vant、Element、Analytics 等 │ ├── App.vue │ ├── router/ │ │ └── index.js # 单路由 History 模式 │ ├── store/ │ │ └── index.js # Vuex(当前无业务 state) │ ├── views/land/ │ │ ├── index.vue # 落地页主入口:设备判断、选线、下载逻辑 │ │ └── components/ # mobile1 / mobile2 / pc / pc2 / tips / selectLinePopup │ ├── api/ # getApkInfo、getTemplate、getIp、getCustomerServiceUrl │ ├── utils/ # request、eventTracker、userAgent 等 │ ├── plugins/ # flexible、element、scale_no │ └── assets/ # 样式、各模板图片(mobile1/mobile2/pc/pc2) ├── vue.config.js ├── .env.development / .env.production ├── build.sh # 正式环境打包发布脚本(示例) ├── test_build.sh # 测试环境打包发布脚本(示例) └── project.md # 本文件 ``` **接口与选线:** - 业务接口统一走 **`/plm/okn/ijb/...`** 路径(见 `src/api/`),由网关或 devServer 反代。 - **`VUE_APP_BASE_HOSTS`**:各环境 `.env.*` 中为 **JSON 数组字符串**,供选线弹窗展示候选 API 域名;用户选择后写入 `axios.defaults.baseURL` 并重试 `getTemplate`。 - 生产部署需由 **Nginx / 网关** 将 **`/plm`** 转发至实际业务后端;History 模式需配置 **单页回退**(`try_files` → `index.html`)。 --- # 2. 基础设施与中间件 本仓库为 **纯前端工程**,不内置后端;运行时依赖: - **业务 API**:`/plm` 路径下的配置与下载上报接口;静态部署时需保证 **`/plm` 反代** 与 HTTPS 证书策略一致。 - **选线域名**:`VUE_APP_BASE_HOSTS` 中的候选域名需可达,否则用户只能通过选线弹窗手动切换。 - **LandingSDK**:`public/sdk/landing-sdk-v1.1.1.js`,用于埋点上报(`window.tracker` / `LandingSDK.init`)。 - **静态资源托管**:`npm run build` 产物在 **`dist/`**,由 CDN 或 Web 服务器提供。 - **第三方**:Google Analytics(`UA-165940626-2`)、可选外网 IP 查询(`api.ipify.org`,`getIp` 中,当前主流程未启用)。 --- # 3. 运维部署 **构建产物:** 执行 `npm run build` 或 `npm run test-build` 后,在 **`dist/`** 生成静态资源;可能同时生成 **`.gz`**(依赖服务器是否启用 `gzip_static` 或等价能力)。 **推荐发布流程(示例):** 1. 使用约定 **Node** 版本(建议 12.18.1)安装依赖:`npm ci` 或 `npm install`。 2. 确认各环境 **`.env.*`** 中 `VUE_APP_BASE_HOSTS`、`VUE_APP_BASE_API` 等与当前发布目标一致。 3. 执行 `npm run build` 或 `npm run test-build`。 4. 将 **`dist/`** 同步至静态服务器;确认 **History 路由回退** 与 **`/plm` 反代**。 5. 仓库内 **`build.sh`**(正式)、**`test_build.sh`**(测试)为示例流程(打包 zip → scp → 远程 `dist.sh`),**主机与路径以实际运维规范为准**,避免泄露账号与内网信息。 **环境变量说明(摘录,完整以 `.env.*` 为准):** | 变量 | 作用 | |------|------| | `ENV` | 环境标识(`development` / `production`) | | `VUE_APP_BASE_API` | API 根路径前缀(生产多为 `/api`) | | `VUE_APP_APP_API` | 应用 API 前缀(开发环境 `/api`) | | `VUE_APP_WEB_API` | Web API 前缀(开发环境可为空) | | `VUE_APP_BASE_HOSTS` | 选线候选 API 域名列表(JSON 数组字符串) | --- # 4. 风险说明 - **强依赖网关反代**:生产若 `/plm` 代理错误,**配置拉取与下载上报将不可用**;History 模式服务器配置错误会导致 **深链 404**。 - **选线失败**:`getTemplate` 请求失败时弹出选线弹窗;若所有候选域名不可用,用户可能无法获取下载配置。 - **埋点依赖 SDK**:`LandingSDK` 未加载完成前,`window.tracker` 使用队列缓冲;SDK 加载失败会导致埋点丢失。 - **渠道参数**:下载与剪贴板逻辑依赖 URL 参数(`dc`、`ch`、`pc`、`tid` 等),参数缺失或格式不符可能影响跳转与统计。 - **配置敏感信息**:`.env`、选线域名、部署脚本中的主机信息 **勿提交到公开仓库**;供应链上锁定 `package-lock.json` 并定期审计依赖。 --- # 5. 历史事故(可选) - 暂无(请运维/研发后续补充) --- # 6. 交接说明(可选) - 落地页主逻辑集中在 **`src/views/land/index.vue`**;新增模板时参考 `mobile1` / `mobile2` / `pc` 组件模式,并在 `index.vue` 中注册与切换。 - 子组件规范见 **`.cursor/rules/vue-component.mdc`**;样式与 px2rem 见 **`.cursor/rules/scss-styling.mdc`**。 - 接口封装在 **`src/api/`**;HTTP 请求统一走 **`src/utils/request.js`**。 - 埋点上报使用 **`src/utils/eventTracker.js`** 的 `landingPageView` / `landingPageClick`,勿绕过 SDK 直接上报。 - Figma 转落地页工作流见 **`.cursor/skills/figma-to-landpage/SKILL.md`**。 - **请勿将含密钥、生产内网地址的 `.env` 或未脱敏部署脚本提交至对外可见仓库**;YAML 头部元数据若与真实组织不一致,请在内部系统中核对后修改。