# 四、本地环境与项目配置 这一章只处理三件事: 1. 快速看懂 `web-pay` 仓库里每个目录负责什么。 2. 让本机具备后续启动 `web-pay` 和 `saas-starter` 示例项目的基础环境。 3. 在 RDS 中准备 web-pay 支付库和 SaaS 业务库。 ```{important} 🧰 **本章目标很简单:** 先把本地电脑和数据库准备好,不要一上来就纠结业务代码。只要目录能找对、工具能跑、数据库能连,后面第 5 章启动 web-pay 就会顺很多。 ``` ## 4.1 项目目录速读 进入你自己的 `web-pay` 仓库根目录: ```bash cd /你的/web-pay/仓库路径 ``` ```{tip} 🎯 **先建立地图感。** 这一节不是让你背代码结构,而是让你知道“出问题时应该去哪个目录看”。 ``` 教程默认仓库结构如下: ```text web-pay/ env-scripts/ # web-pay 的本地启动、生产构建、上传和配置脚本 zhcpay-ui/ zhcpay-ui-cashier/ # 统一收银台前端 zhcpay-ui-manager/ # 运营平台前端 zhcpay/ zhcpay-payment/ # 支付网关后端 zhcpay-manager/ # 运营平台后端 zhcpay-service/ # 业务数据访问和通用服务 zhcpay-core/ # 核心实体、工具和通用模型 zhcpay-components/ # OSS、MQ 等组件 zhcpay-sdk-java/ # Java SDK docs/sql/ # web-pay 数据库 SQL 资料 saas-starter/ env-scripts/ # SaaS 示例项目的配置、启动、构建脚本 backend/ # SaaS 后端 frontend/ # SaaS 前端 logs/ # SaaS 本地运行日志 ``` 你先记住这 4 个入口就够了: | 入口 | 你需要知道的事 | | --------------- | ------------------------------------ | | `env-scripts/` | 操作 `web-pay` 的脚本都在这里。 | | `zhcpay-ui/` | 两个 web-pay 前端:收银台和运营平台。 | | `zhcpay/` | 两个 web-pay 后端和共享 Java 模块。 | | `saas-starter/` | 本教程默认的业务 SaaS 示例项目。 | ```{note} 📌 **第一次阅读只记入口,不用展开源码。** 真正动手时,你大多数操作都会从脚本入口开始,很少需要手工钻到每个 Java 模块里改配置。 ``` 本地联调时一共有 6 个服务: | 服务 | 路径 | 默认端口 | 作用 | | ------------ | ----------------------------- | -------- | ---------------------------------------- | | 收银台前端 | `zhcpay-ui/zhcpay-ui-cashier` | `8080` | 用户付款时打开的页面 | | 运营平台前端 | `zhcpay-ui/zhcpay-ui-manager` | `8002` | 你管理商户、应用、订单、支付通道的页面 | | 支付网关后端 | `zhcpay/zhcpay-payment` | `9216` | SaaS 下单、支付平台回调都会打到这里 | | 运营平台后端 | `zhcpay/zhcpay-manager` | `9217` | 运营平台前端调用的后台 API | | SaaS 前端 | `saas-starter/frontend` | `5173` | 业务用户看到的 SaaS 页面 | | SaaS 后端 | `saas-starter/backend` | `9220` | 创建业务订单、调用 web-pay、接收支付结果 | ![web-pay 本地目录与服务端口关系](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-01-041-section.png) 本地调用关系可以先理解成: ```text SaaS 前端 :5173 -> SaaS 后端 :9220 -> web-pay 支付网关 :9216 -> web-pay 收银台前端 :8080 web-pay 运营平台前端 :8002 -> web-pay 运营平台后端 :9217 ``` ```{tip} 💡 **排查时按端口找服务。** 页面打不开先看前端端口,接口报错再看后端端口,支付回调问题优先看 `9216` 支付网关。 ``` 后面排查问题时,先看请求卡在哪个端口,再回到上面的表找对应目录。 ## 4.2 本地环境清单 本项目本地联调需要下面这些环境。这里不展开解释每个工具是什么,只列出后续脚本和服务会用到的清单。 ```{note} 🧪 **这一节的目的不是安装教学,而是确认“本机能不能跑”。** 如果缺工具,可以先交给本地 AI 或包管理器安装,最后按检查命令验收即可。 ``` | 类别 | 需要具备 | | ------------ | -------------------------------------------------------------------------------------------- | | 基础命令行 | Bash 或兼容 Shell、`awk`、`sed`、`grep`、`find`、`perl`、`chmod`、`mktemp`、`pkill`、`nohup` | | 代码与构建 | Git、Node.js、npm、JDK 17、Maven | | 远程与网络 | OpenSSH、`scp`、`curl`、`nc`、`lsof` | | 本地回调 | `cloudflared` | | 数据库客户端 | PostgreSQL 客户端 `psql` | | 本地依赖服务 | Redis、ActiveMQ | | 可选文档环境 | Python 3、venv、pip;只在你要本机构建本教程文档时需要 | 建议版本: | 环境 | 建议 | | ----------------- | ----------------------------- | | JDK | 17 | | Node.js | 20 LTS 优先,18 LTS 也可以 | | npm | 跟随 Node.js 安装 | | Maven | 3.8+ | | PostgreSQL 客户端 | 能连接你第 3 章准备的 RDS | | Redis | 本机 `127.0.0.1:6379` 可访问 | | ActiveMQ | 本机 `127.0.0.1:61616` 可访问 | ![本地联调环境清单](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-02-042-section.png) ### 复制给本地 AI 的安装提示词 如果你不想自己逐个安装工具,可以把下面这段提示词直接发送给你电脑上的本地 AI。让它先检查环境,再按你的系统安装缺失项。 ```{warning} 🔐 **复制提示词前先确认:** 下面这段不会要求 AI 读取或输出数据库密码、SSH 密码、支付密钥等敏感信息。安装工具和检查版本不需要这些资料。 ``` ```text 你是我的本地开发环境安装助手。我要在这台电脑上运行 web-pay 和 saas-starter 本地联调项目。 项目根目录: <把我的 web-pay 仓库绝对路径填在这里> 请你完成以下任务: 1. 先识别当前操作系统、CPU 架构、默认 Shell、包管理器和当前用户权限。 2. 检查下面这些环境是否已安装并可用: - Bash 或兼容 Shell - awk、sed、grep、find、perl、chmod、mktemp、pkill、nohup - Git - Node.js 20 LTS 或 18 LTS - npm - JDK 17,并确保 java 和 JAVA_HOME 指向 JDK 17 - Maven 3.8+ - OpenSSH 和 scp - curl、nc、lsof - cloudflared - PostgreSQL 客户端 psql - Redis 服务和 redis-cli,本机 127.0.0.1:6379 可访问 - ActiveMQ 服务,OpenWire 端口 127.0.0.1:61616 可访问 - 可选:Python 3、venv、pip,用于构建 docs 文档 3. 对缺失项制定安装方案: - macOS 优先使用 Homebrew。 - Windows 优先使用 WSL2 或 Git Bash 环境;需要说明我后续应在哪个终端里运行项目脚本。 - Linux 按当前发行版使用 apt、dnf、yum、pacman 或官方安装方式。 4. 安装或修复缺失项。安装前请告诉我将执行哪些命令,不要修改项目源码文件。 5. Redis 安装后请启动本机服务,并确认 redis-cli ping 输出 PONG。 6. ActiveMQ 本机安装,最终必须让 127.0.0.1:61616 可访问;用户名和密码要与项目 application-local.yml 保持一致,默认按 system / manager 检查。 7. 不要读取、打印、上传或保存我的数据库密码、SSH 密码、支付密钥、AppSecret 等敏感信息。 8. 完成后输出一张检查表,逐项给出命令、输出摘要、是否通过、失败时的修复建议。 最后请运行这些检查命令: git --version node -v npm -v java -version mvn -v ssh -V command -v scp curl --version nc -h 或 nc -z 127.0.0.1 61616 lsof -v cloudflared --version psql --version redis-cli ping ``` ### 安装后自己再检查一遍 本地 AI 安装完成后,你自己也在终端运行一次: ```bash git --version node -v npm -v java -version mvn -v ssh -V command -v scp curl --version cloudflared --version psql --version redis-cli ping nc -z 127.0.0.1 61616 ``` 重点看下面几项: | 检查 | 通过标准 | | ----------------------- | ------------------------------------- | | `java -version` | 输出里能看到 17 | | `mvn -v` | 能看到 Maven 版本,并且 Java 版本是 17 | | `redis-cli ping` | 输出 `PONG` | | `nc -z 127.0.0.1 61616` | 命令退出码为 0,说明 ActiveMQ 端口可连 | | `cloudflared --version` | 能正常输出版本 | | `psql --version` | 能正常输出版本 | ```{important} ✅ **这些检查都通过后,本机环境就算准备好了。** 后面启动失败时,就可以把注意力放到配置、端口和数据库连接上,不用反复怀疑工具没装好。 ``` ## 4.3 在 RDS 中新建两个数据库 本地联调仍然使用第 3 章准备好的华为云 PostgreSQL RDS。本章只要求你在同一个 RDS 实例中准备两个数据库: ```{important} 🎯 **这里要准备的是两个库,不是两个 RDS 实例。** 一个 RDS PostgreSQL 实例里放 `pay` 和 SaaS 业务库即可,成本更低,也更方便本地联调。 ``` | 数据库 | 建议名称 | 用途 | | -------------- | ------------------------------------ | ---------------------------------------------------------------------- | | web-pay 支付库 | `pay` | 存放 web-pay 商户、应用、订单、支付通道等数据,即第三章配置的pay数据库 | | SaaS 业务库 | 跟随你的 SaaS 服务名,例如 `saas_starter` | 存放业务用户、业务订单、订阅等数据 | ```{warning} 📌 **两个库的职责不要混。** `pay` 归 web-pay 使用,保存支付平台自己的数据;SaaS 业务库归你的业务系统使用,保存业务用户、套餐、订单等数据。 ``` `pay` 库只需要先创建出来,新用户不需要手工导入 web-pay 初始化 SQL。第 5 章启动本地后端时,脚本会检测空库并通过 Flyway 自动建表和写入基础数据。SaaS 业务库仍按第 7 章的要求处理。 SaaS 业务库名要和后面 `saas-starter/env-scripts/rename-saas-service.sh` 里填写的「数据库名」一致。脚本默认规则是: ```text 服务名: saas-starter 默认数据库名称: saas_starter ``` 如果你还不准备改名,可以先使用模板默认库名: ```text saas_starter ``` ![RDS 双数据库准备关系](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-03-043-rds.png) ### 在华为云 RDS / DAS 中创建数据库 进入华为云 RDS 控制台: 1. 打开 **云数据库 RDS**。 2. 进入第 3 章创建好的 PostgreSQL 实例。 3. 点击 **登录** 或进入 DAS 数据库管理页面。 4. 使用 RDS 实例管理员账号登录,数据库名称通常先填 `postgres`。 5. 在数据库列表里点击 **新建数据库**。 6. 新建 `pay`(**第三章已经完成新建**,可保持空库) 7. 再新建你的 SaaS 业务库,例如 `saas_starter`。 ```{important} ✅ **完成标志:** RDS 里能看到 `pay` 和你的 SaaS 业务库,并且本机 `psql` 可以通过 RDS 公网地址连上它们。 ``` ![数据库配置](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/ENV-01.png) ## 4.4 配置关系总览 先把一句话讲清楚:前端看 `.env` 文件,后端看 Spring 配置文件。 ```{important} 🎯 **这句话后面会反复用到。** 页面里能看到的 API 地址通常来自前端 `.env`;数据库、Redis、ActiveMQ、支付密钥这类后端私有信息来自 Spring 配置。 ``` `.env` 是前端工程的环境变量文件。它通常放在各自前端目录下,例如收银台的 `zhcpay-ui/zhcpay-ui-cashier/.env.development`、运营平台的 `zhcpay-ui/zhcpay-ui-manager/.env.development`、SaaS 前端的 `saas-starter/frontend/.env.development`。前端构建或本地启动时,Vite、Vue CLI、UniApp 会读取这些变量,把 API 地址、页面标题、部署基础路径等写进前端运行时配置。注意:前端配置最终会被浏览器看到,所以这里不要放数据库密码、AppSecret、证书私钥这类敏感信息。 ```{danger} 🔐 **前端配置不是保密位置。** 只要最终会进浏览器,就不要放数据库密码、AppSecret、证书私钥、支付密钥或 SSH 密码。 ``` Spring 配置文件是后端工程的配置文件,通常放在 `src/main/resources/` 下面,例如 `application-local.yml` 和 `application.yml`。后端启动时,Spring Boot 会读取这些文件,决定服务端口、数据库连接、Redis、ActiveMQ、web-pay 对外地址、SaaS 通知地址、支付应用身份等信息。后端配置可以引用环境变量,也可以在本地用启动脚本生成的覆盖文件临时补充。 为什么本地环境和线上环境要分开?因为它们访问的对象不一样: | 对比项 | 本地联调 | 线上部署 | | ------ | -------- | -------- | | 运行位置 | 你的电脑 | 云服务器、OBS/CDN、Nginx 等线上环境 | | 前端访问后端 | 访问 `localhost` 端口,例如 `9216`、`9217`、`9220` | 访问正式域名,例如 `pay-api`、`paymanager-api`、SaaS API | | 后端访问数据库 | 通常用 RDS 公网地址,方便你电脑直连 | 通常用 RDS 内网地址,更稳定也更安全 | | 回调和通知 | 通过 cloudflared 把本机临时暴露成公网地址 | 通过正式域名和线上 Nginx 转发 | | 配置目标 | 方便调试、热更新、看日志 | 面向真实用户、正式支付和长期运行 | 所以同一个系统会有两套配置:本地配置用于“我在电脑上跑起来”,线上配置用于“服务部署到云上给用户访问”。本地配置应该尽量指向 `localhost` 和 RDS 公网地址;线上配置应该尽量指向正式域名、RDS 内网地址和生产环境变量。 ![本地与线上配置关系总览](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-04-044-config.png) 对应关系可以这样看: | 场景 | 前端读取 | 后端读取 | | -------- | ------------------ | -------------------------------------------------- | | 本地联调 | `.env.development` | `application-local.yml` 和启动脚本生成的覆盖配置 | | 线上部署 | `.env` | `application.yml` 或生产环境变量 | ```{tip} 📌 **后面脚本会替你写配置。** 你现在只需要理解哪些信息属于前端、哪些信息属于后端,真正填写时尽量交给脚本批量处理。 ``` 本地前端配置负责把浏览器请求打到本机后端: | 前端 | 本地文件 | 关键配置 | 指向 | | ---------------- | ----------------------------------------------- | ---------------------- | ------------------------------ | | web-pay 收银台 | `zhcpay-ui/zhcpay-ui-cashier/.env.development` | `VUE_APP_API_BASE_URL` | `http://localhost:9216` | | web-pay 运营平台 | `zhcpay-ui/zhcpay-ui-manager/.env.development` | `VITE_API_BASE_URL` | `http://localhost:9217` | | SaaS 前端 | `saas-starter/frontend/.env.development` | `VITE_API_BASE_URL` | `http://localhost:9220/api/v1` | 线上前端配置负责把线上页面请求打到线上 API: | 前端 | 线上文件 | 关键配置 | 指向 | | ---------------- | ----------------------------------------- | ---------------------- | ---------------------------- | | web-pay 收银台 | `zhcpay-ui/zhcpay-ui-cashier/.env` | `VUE_APP_API_BASE_URL` | 线上 `pay-api` 域名 | | web-pay 运营平台 | `zhcpay-ui/zhcpay-ui-manager/.env` | `VITE_API_BASE_URL` | 线上 `paymanager-api` 域名 | | SaaS 前端 | `saas-starter/frontend/.env` | `VITE_API_BASE_URL` | 线上 SaaS API 域名 `/api/v1` | 本地后端配置负责让本机服务接上对应的数据库、缓存和支付入口: | 后端 | 本地文件 | 重点关系 | | ---------------- | ---------------------------------------------------------------- | -------- | | web-pay 支付网关 | `zhcpay/zhcpay-payment/src/main/resources/application-local.yml` | 连接 RDS 公网 `pay` 库、本机 Redis、本机 ActiveMQ;启动脚本可把 `web-pay.public-base-url` 覆盖成 cloudflared 公网地址 | | web-pay 运营后端 | `zhcpay/zhcpay-manager/src/main/resources/application-local.yml` | 连接 RDS 公网 `pay` 库、本机 Redis、本机 ActiveMQ;运营平台前端本地调用 `9217` | | SaaS 后端 | `saas-starter/backend/src/main/resources/application-local.yml` | 连接 SaaS 业务库;本地支付验收时 `zhcpay.api-base-url` 指向线上 `pay-api`;`zhcpay.cashier-base-url` 指向线上收银台 | 线上后端配置负责让云服务器上的服务互相找到: | 后端 | 线上文件 | 重点关系 | | ---------------- | ----------------------------------------------------------- | -------- | | web-pay 支付网关 | `zhcpay/zhcpay-payment/src/main/resources/application.yml` | 连接 RDS 内网 `pay` 库;`web-pay.public-base-url` 是线上 `pay-api`;`cashier-public-base-url` 是线上收银台 | | web-pay 运营后端 | `zhcpay/zhcpay-manager/src/main/resources/application.yml` | 连接 RDS 内网 `pay` 库;运营后台对外地址是线上 `paymanager-api` | | SaaS 后端 | `saas-starter/backend/src/main/resources/application.yml` | 通过生产环境变量或私有配置连接生产库;调用线上 `pay-api`;跳转线上收银台;`notify-url` 是 SaaS API 的支付通知地址 | 一句话理解:本地前端只找本地后端;本地 SaaS 做支付验收时,后端直接调用第 8 章上线后的 web-pay;线上前端只找线上 API,线上 SaaS 后端也继续调用线上 web-pay。 这里看起来文件很多,但不用担心你要挨个去查、挨个手改。后面用到的 `rename-saas-service.sh` 脚本,作用就是把你在第 3 章准备好的域名、数据库、端口、SSH、支付应用信息快速写到对应位置。你只需要理解这些配置大概分工,真正填写参数时交给脚本批量处理。 ## 4.5 本章检查清单 继续第 5 章前确认: ```{warning} ✅ **不要跳过这张清单。** 第 5 章会直接启动多个前后端服务,如果这里有一项没准备好,后面错误信息会变得很绕。 ``` ![进入第 5 章前的本章检查](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-05-045-checklist.png) - [ ] 能进入自己的 `web-pay` 仓库根目录。 - [ ] 已经看懂 `env-scripts/`、`zhcpay-ui/`、`zhcpay/`、`saas-starter/`、`docs/` 分别负责什么。 - [ ] Git、Node.js、npm、JDK 17、Maven、OpenSSH、`cloudflared`、`psql` 都能输出版本。 - [ ] 本机 Redis `127.0.0.1:6379` 可用,`redis-cli ping` 输出 `PONG`。 - [ ] 本机 ActiveMQ `127.0.0.1:61616` 可用。 - [ ] 华为云 RDS 同一 PostgreSQL 实例中已经有 `pay` 和 SaaS 业务库,其中 `pay` 新库可保持空库。 - [ ] 本机能用 `psql` 连接 RDS 公网地址上的两个数据库。 - [ ] 已准备好第 3 章记录的域名、RDS、ActiveMQ 和 SSH 信息,下一章会写入 web-pay 配置。 - [ ] 已决定 SaaS 业务库名称;如果后续要改名 SaaS,第 7 章脚本输入要和这个库名一致。