# 腾讯云部署说明 本文档记录当前后端部署到腾讯云函数 SCF,并连接腾讯云数据库 MySQL 与 COS 的最小流程。 ## 1. 数据库初始化 先确认 `server/.env` 或部署环境变量中已配置数据库: ```env DB_HOST= DB_PORT=3306 DB_USER=root DB_PASSWORD= DB_NAME=jw_beauty ``` 本地直连公网数据库时,需要在腾讯云数据库的安全组/白名单中放行本机公网 IP。若本地无法直连,也可以临时通过支持 SOCKS5 的代理建立本地 TCP 隧道,再覆盖 `DB_HOST` 和 `DB_PORT` 执行初始化。 ```bash cd server npm install npm run db:init ``` 初始化会创建业务表,并写入临时后台账号。生产环境首次登录后应立即更换默认密码。 ## 2. SCF 函数配置 当前函数 `jw-beauty-api` 是腾讯云 HTTP 函数。HTTP 函数部署包根目录需要包含可执行的 `scf_bootstrap`,由它启动 HTTP 服务。 本项目的 HTTP 函数启动文件: ```text scf_bootstrap ``` `scf_bootstrap` 会执行: ```bash node scripts/local-server.js ``` HTTP 服务监听端口使用环境变量 `PORT`,建议配置为 `9000`。 如果以后改为普通事件函数,入口才使用: ```text index.main_handler ``` 触发器: ```text HTTP 触发器或函数 URL ``` 触发器需要透传: ```text method path headers queryStringParameters body ``` ## 3. 环境变量 参考模板: ```text server/.env.production.example ``` 生产必须配置: ```env NODE_ENV=production TENCENT_SECRET_ID= TENCENT_SECRET_KEY= TENCENT_REGION=ap-guangzhou DB_HOST= DB_PORT=3306 DB_USER= DB_PASSWORD= DB_NAME=jw_beauty COS_BUCKET=jw-bucket-1426323813 COS_REGION=ap-guangzhou WECHAT_APPID= WECHAT_SECRET= JWT_SECRET= ADMIN_JWT_SECRET= ADMIN_USERNAME=admin ADMIN_PASSWORD= ``` 不要提交真实 `.env`、密钥、数据库密码或微信密钥。 ## 4. 数据库网络 SCF 与腾讯云数据库建议使用同地域、同 VPC 内网连接。 如果使用公网地址,需要确认: - 数据库已开启公网访问。 - 安全组允许 SCF 出口或本机出口访问数据库端口。 - `DB_PORT` 与控制台展示端口一致。 ## 5. COS 固件 固件文件先上传到 COS,然后在后台登记对象 key。 相关接口: ```http GET /api/v1/admin/firmware POST /api/v1/admin/firmware POST /api/v1/admin/firmware/:firmware_id/status GET /api/v1/firmware/latest ``` 小程序调用 `GET /api/v1/firmware/latest` 时,后端会返回短期有效的 COS 签名下载 URL。 ## 6. 前端 API 地址 SCF HTTP 地址确认后,更新: ```text miniprogram/config/env.js admin-console/src/config/env.js ``` 把 `test` 或 `prod` 改为腾讯云函数 HTTPS 地址。 微信小程序正式联调还需要在微信公众平台配置 `request 合法域名`。 ## 7. 管理后台 H5 部署到 COS 管理后台构建产物位于: ```text admin-console/dist/build/h5 ``` 先确认 `admin-console/src/config/env.js` 已指向测试或生产 API,再执行: ```bash cd admin-console npm install npm run build:h5 ``` 如需直接上传到 COS,可复用 `server/.env` 中的 COS 凭证: ```bash cd admin-console npm run deploy:cos ``` 默认上传前缀: ```text admin/ ``` 可通过环境变量覆盖: ```bash ADMIN_COS_PREFIX=admin-test/ npm run deploy:cos ``` ## 8. 后端 SCF 代码更新 常规后端代码更新流程如下。当前线上函数名为 `jw-beauty-api`,部署包上传到 COS: ```text deploy/jw-beauty-api/hox-http-function.zip ``` ### 8.1 拉取代码并检查 ```bash git status --short --branch git pull --ff-only ``` 如果 `server/` 有依赖变更,先同步依赖: ```bash cd server npm install ``` 部署前至少做语法检查: ```bash cd server node -c src/app.js node -c src/index.js node -c src/lib/serverless.js node -c scripts/local-server.js ``` 如果只改了某个路由,也可以额外检查对应文件,例如: ```bash node -c src/routes/subscription.js ``` ### 8.2 打包后端代码 部署包必须以 `server/` 为根目录打包,并包含: - `index.js` - `package.json` - `package-lock.json` - `scripts/` - `scf_bootstrap` - `src/` - `sql/` - `node_modules/` 不要把 `server/.env` 打进部署包。 实际使用命令: ```bash cd server rm -f /tmp/hox-http-function.zip zip -qry /tmp/hox-http-function.zip index.js package.json package-lock.json scripts scf_bootstrap src sql node_modules ``` ### 8.3 上传部署包到 COS 上传复用 `server/.env` 中的腾讯云/COS 凭证。命令只读取本地环境变量,不要把真实密钥写入文档或提交到 Git。 ```bash cd server set -a; source ./.env; set +a node - <<'NODE' const fs = require('fs') const COS = require('cos-nodejs-sdk-v5') const cos = new COS({ SecretId: process.env.TENCENT_SECRET_ID, SecretKey: process.env.TENCENT_SECRET_KEY }) cos.putObject({ Bucket: process.env.COS_BUCKET, Region: process.env.COS_REGION || process.env.TENCENT_REGION || 'ap-guangzhou', Key: 'deploy/jw-beauty-api/hox-http-function.zip', Body: fs.createReadStream('/tmp/hox-http-function.zip') }, err => { if (err) { console.error(err) process.exit(1) } console.log('uploaded deploy/jw-beauty-api/hox-http-function.zip') }) NODE ``` ### 8.4 更新 SCF 函数代码 使用 `tccli scf UpdateFunctionCode` 指向刚上传的 COS 对象: ```bash cd server set -a; source ./.env; set +a /Users/guoguo/.local/bin/tccli scf UpdateFunctionCode \ --region ap-guangzhou \ --FunctionName jw-beauty-api \ --CosBucketName "$COS_BUCKET" \ --CosObjectName /deploy/jw-beauty-api/hox-http-function.zip \ --CosBucketRegion "${COS_REGION:-ap-guangzhou}" \ --secretId "$TENCENT_SECRET_ID" \ --secretKey "$TENCENT_SECRET_KEY" ``` 如果命令返回 `RequestId`,表示更新请求已提交成功。函数实例刷新通常需要等待几秒。 ### 8.5 更新后快速验证 ```bash node - <<'NODE' const base = 'https://api.vsai.net.cn' async function print(label, res) { const text = await res.text() console.log(label, res.status, text.slice(0, 1000)) return text } ;(async () => { await print('health', await fetch(base + '/health')) const loginText = await print('login', await fetch(base + '/api/v1/admin/login', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ username: 'admin', password: 'admin' }) })) const token = JSON.parse(loginText).data && JSON.parse(loginText).data.token if (token) { await print('settings', await fetch(base + '/api/v1/admin/settings', { headers: { authorization: 'Bearer ' + token } })) await print('dashboard', await fetch(base + '/api/v1/admin/dashboard', { headers: { authorization: 'Bearer ' + token } })) } })().catch(err => { console.error(err) process.exit(1) }) NODE ``` 常见成功结果: - `GET /health` 返回 `code: 0` - `POST /api/v1/admin/login` 使用 `admin/admin` 返回 `code: 0` - `GET /api/v1/admin/settings` 返回 `code: 0` - `GET /api/v1/admin/dashboard` 返回 `code: 0` ## 9. 部署后验证 建议按顺序验证: ```http GET /health POST /api/v1/admin/login GET /api/v1/admin/dashboard POST /api/v1/admin/devices GET /api/v1/admin/devices GET /api/v1/admin/firmware ``` 再进入小程序验证:登录、扫码绑定、BLE 连接、绑定确认、普通模式护理、护理记录同步。