Compare commits

..

2 Commits

Author SHA1 Message Date
yjm 22ebd66102 feat: 增加后台管理端UI 2026-04-25 21:59:54 +08:00
yjm 8bb2b9f176 first commit 2026-04-24 19:01:28 +08:00
18 changed files with 40 additions and 13108 deletions
-88
View File
@@ -1,88 +0,0 @@
name: build-and-push
on:
push:
branches: ["master", "main"]
tags: ["v*"]
workflow_dispatch:
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
env:
REGISTRY: ${{ secrets.ACR_REGISTRY }}
NAMESPACE: ${{ secrets.IMAGE_NAMESPACE }}
ADMIN_IMAGE_NAME: zzyl-admin
UI_IMAGE_NAME: zzyl-ui
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "11"
cache: maven
- name: Build Jar
run: mvn -B clean package -DskipTests
- name: Prepare image tag
shell: bash
run: |
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
echo "IMAGE_TAG=${GITHUB_REF_NAME}" >> "$GITHUB_ENV"
else
echo "IMAGE_TAG=${GITHUB_SHA::7}" >> "$GITHUB_ENV"
fi
echo "ADMIN_IMAGE=${REGISTRY}/${NAMESPACE}/${ADMIN_IMAGE_NAME}" >> "$GITHUB_ENV"
echo "UI_IMAGE=${REGISTRY}/${NAMESPACE}/${UI_IMAGE_NAME}" >> "$GITHUB_ENV"
- name: Log in to Alibaba Cloud ACR
uses: docker/login-action@v3
with:
registry: ${{ secrets.ACR_REGISTRY }}
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}
- name: Build and push admin image
uses: docker/build-push-action@v6
with:
context: zzyl-admin/target
file: zzyl-admin/Dockerfile
push: true
tags: |
${{ env.ADMIN_IMAGE }}:${{ env.IMAGE_TAG }}
- name: Build and push ui image
uses: docker/build-push-action@v6
with:
context: zzyl-ui
file: zzyl-ui/Dockerfile
push: true
tags: |
${{ env.UI_IMAGE }}:${{ env.IMAGE_TAG }}
- name: Push admin latest tag on default branches
if: github.ref_type == 'branch'
uses: docker/build-push-action@v6
with:
context: zzyl-admin/target
file: zzyl-admin/Dockerfile
push: true
tags: |
${{ env.ADMIN_IMAGE }}:latest
- name: Push ui latest tag on default branches
if: github.ref_type == 'branch'
uses: docker/build-push-action@v6
with:
context: zzyl-ui
file: zzyl-ui/Dockerfile
push: true
tags: |
${{ env.UI_IMAGE }}:latest
-55
View File
@@ -1,55 +0,0 @@
TZ=Asia/Shanghai
UI_PORT=80
APP_PORT=9000
ZZYL_ADMIN_IMAGE=registry.cn-hangzhou.aliyuncs.com/example/zzyl-admin:latest
ZZYL_UI_IMAGE=registry.cn-hangzhou.aliyuncs.com/example/zzyl-ui:latest
MYSQL_PORT=3306
MYSQL_DATABASE=zzyl
MYSQL_ROOT_PASSWORD=change_me_mysql_root
MYSQL_APP_USER=zzyl
MYSQL_APP_PASSWORD=change_me_mysql_app
MYSQL_URL=jdbc:mysql://zzyl-mysql:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
MYSQL_USERNAME=zzyl
MYSQL_PASSWORD=change_me_mysql_app
REDIS_PORT=6379
REDIS_HOST=zzyl-redis
REDIS_PASSWORD=change_me_redis
REDIS_DATABASE=2
APP_LOG_DIR=/data/zzyl/logs
APP_PROFILE_DIR=/data/zzyl/uploadPath
RUOYI_PROFILE=/data/zzyl/uploadPath
TOKEN_SECRET=change_me_token_secret
TOKEN_EXPIRE_TIME=3600
DRUID_LOGIN_USERNAME=ruoyi
DRUID_LOGIN_PASSWORD=change_me_druid
DEPT_NURSING_ID=201
ALIYUN_OSS_DOMAIN=oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_BUCKET=change-me-bucket
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ACCESS_KEY_ID=change_me_oss_key
ALIYUN_OSS_SECRET_ACCESS_KEY=change_me_oss_secret
BAIDU_ACCESS_KEY=change_me_baidu_key
BAIDU_SECRET_KEY=change_me_baidu_secret
BAIDU_QIANFAN_MODEL=ERNIE-4.0-8K
WECHAT_MINI_PROGRAM_APP_ID=change_me_wechat_appid
WECHAT_MINI_PROGRAM_SECRET=change_me_wechat_secret
HUAWEI_CLOUD_AK=change_me_huawei_ak
HUAWEI_CLOUD_SK=change_me_huawei_sk
HUAWEI_CLOUD_REGION_ID=cn-east-3
HUAWEI_CLOUD_ENDPOINT=change_me_huawei_endpoint
HUAWEI_CLOUD_PROJECT_ID=change_me_huawei_project_id
HUAWEI_CLOUD_AMQP_HOST=change_me_huawei_amqp_host
HUAWEI_CLOUD_AMQP_ACCESS_KEY=change_me_huawei_amqp_access_key
HUAWEI_CLOUD_AMQP_ACCESS_CODE=change_me_huawei_amqp_access_code
HUAWEI_CLOUD_AMQP_QUEUE_NAME=DefaultQueue
-24
View File
@@ -1,24 +0,0 @@
services:
zzyl-admin:
image: ${ZZYL_ADMIN_IMAGE}
container_name: zzyl-admin
restart: unless-stopped
env_file:
- .env
environment:
TZ: ${TZ}
SPRING_PROFILES_ACTIVE: prod
ports:
- "${APP_PORT}:9000"
volumes:
- ${APP_LOG_DIR}:/home/ruoyi/logs
- ${APP_PROFILE_DIR}:${APP_PROFILE_DIR}
zzyl-ui:
image: ${ZZYL_UI_IMAGE}
container_name: zzyl-ui
restart: unless-stopped
depends_on:
- zzyl-admin
ports:
- "${UI_PORT}:80"
-63
View File
@@ -1,63 +0,0 @@
services:
mysql:
image: registry.cn-hangzhou.aliyuncs.com/pull-image/mysql:8.0
container_name: zzyl-mysql
restart: unless-stopped
environment:
TZ: ${TZ}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_APP_USER}
MYSQL_PASSWORD: ${MYSQL_APP_PASSWORD}
ports:
- "${MYSQL_PORT}:3306"
command:
- --default-authentication-plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_general_ci
volumes:
- mysql_data:/var/lib/mysql
redis:
image: registry.cn-hangzhou.aliyuncs.com/pull-image/redis:7-alpine
container_name: zzyl-redis
restart: unless-stopped
environment:
TZ: ${TZ}
ports:
- "${REDIS_PORT}:6379"
command: >
sh -c "redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}"
volumes:
- redis_data:/data
zzyl-admin:
image: ${ZZYL_ADMIN_IMAGE}
container_name: zzyl-admin
restart: unless-stopped
env_file:
- .env
depends_on:
- mysql
- redis
environment:
TZ: ${TZ}
SPRING_PROFILES_ACTIVE: prod
ports:
- "${APP_PORT}:9000"
volumes:
- ${APP_LOG_DIR}:/home/ruoyi/logs
- ${APP_PROFILE_DIR}:${APP_PROFILE_DIR}
zzyl-ui:
image: ${ZZYL_UI_IMAGE}
container_name: zzyl-ui
restart: unless-stopped
depends_on:
- zzyl-admin
ports:
- "${UI_PORT}:80"
volumes:
mysql_data:
redis_data:
@@ -1,46 +0,0 @@
services:
mysql:
image: registry.cn-hangzhou.aliyuncs.com/pull-image/mysql:8.0
container_name: zzyl-mysql
restart: unless-stopped
environment:
TZ: ${TZ}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_APP_USER}
MYSQL_PASSWORD: ${MYSQL_APP_PASSWORD}
ports:
- "${MYSQL_PORT}:3306"
command:
- --default-authentication-plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_general_ci
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -uroot -p${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 10
redis:
image: registry.cn-hangzhou.aliyuncs.com/pull-image/redis:7-alpine
container_name: zzyl-redis
restart: unless-stopped
environment:
TZ: ${TZ}
ports:
- "${REDIS_PORT}:6379"
command: >
sh -c "redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD-SHELL", "redis-cli -a ${REDIS_PASSWORD} ping"]
interval: 10s
timeout: 5s
retries: 10
volumes:
mysql_data:
redis_data:
@@ -1,55 +0,0 @@
ruoyi:
profile: /data/zzyl/uploadPath
spring:
datasource:
druid:
master:
url: jdbc:mysql://zzyl-mysql:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
username: zzyl
password: change_me_mysql_app
statViewServlet:
login-username: ruoyi
login-password: change_me_druid
redis:
host: zzyl-redis
port: 6379
database: 2
password: change_me_redis
token:
secret: change_me_token_secret
expireTime: 3600
aliyun:
oss:
domain: oss-cn-hangzhou.aliyuncs.com
endpoint: https://oss-cn-hangzhou.aliyuncs.com
bucket-name: change-me-bucket
region: cn-hangzhou
accessKeyId: change_me_oss_key
secretAccessKey: change_me_oss_secret
dept:
nursingId: 201
baidu:
accessKey: change_me_baidu_key
secretKey: change_me_baidu_secret
qianfanModel: ERNIE-4.0-8K
wechat:
mini-program:
appId: change_me_wechat_appid
secret: change_me_wechat_secret
huaweicloud:
ak: change_me_huawei_ak
sk: change_me_huawei_sk
regionId: cn-east-3
endpoint: change_me_huawei_endpoint
projectId: change_me_huawei_project_id
host: change_me_huawei_amqp_host
accessKey: change_me_huawei_amqp_access_key
accessCode: change_me_huawei_amqp_access_code
queueName: DefaultQueue
-26
View File
@@ -1,26 +0,0 @@
server {
listen 80;
server_name _;
client_max_body_size 20m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /prod-api/ {
proxy_pass http://127.0.0.1:9000/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
-270
View File
@@ -1,270 +0,0 @@
# 中州养老部署指南
## 1. 部署架构
本项目按前后端分离部署:
- 前端:`zzyl-ui`Vue 2 项目,使用 `pnpm` 构建,打包为 Nginx 镜像。
- 后端:`zzyl-admin`Spring Boot 服务,JDK 11,容器内端口 `9000`
- 中间件:MySQL 8、Redis 7,镜像使用阿里云镜像源。
- CIGitHub Actions 构建并推送 `zzyl-admin``zzyl-ui` 两个镜像。
- CD:服务器上手动执行 Docker Compose,所有运行时变量统一写在 `deploy/compose/.env`
生产入口为前端服务:`http://服务器IP或域名:${UI_PORT}/`。前端 `/prod-api/` 会由 Nginx 转发到后端 `zzyl-admin:9000`
部署使用的基础中间件镜像:
- MySQL`registry.cn-hangzhou.aliyuncs.com/pull-image/mysql:8.0`
- Redis`registry.cn-hangzhou.aliyuncs.com/pull-image/redis:7-alpine`
- Nginx`registry.cn-hangzhou.aliyuncs.com/pull-image/nginx:mainline-alpine`
## 2. 需要准备的材料
- Linux 服务器,建议 2 核 4G 以上,已安装 Docker Engine、Docker Compose Plugin、Git、curl。
- 阿里云 ACR 或其他 Docker Registry,用于保存后端和前端镜像。
- GitHub Secrets`ACR_REGISTRY``ACR_USERNAME``ACR_PASSWORD``IMAGE_NAMESPACE`
- 域名和 DNS 解析;如对外提供 HTTPS,还需要证书或上层反向代理网关。
- 数据库初始化脚本:`sql/dev0302.sql``sql/quartz.sql`
- 阿里云 OSSBucket、Endpoint、Region、AccessKeyId、AccessKeySecret。
- 微信小程序:`appId``secret`,并把生产域名加入小程序后台白名单。
- 华为云 IoTDA/AMQPAK、SK、ProjectId、Endpoint、RegionId、AMQP Host、AccessKey、AccessCode、QueueName。
- 百度千帆:AccessKey、SecretKey、模型名。
## 3. CI 构建流程
工作流文件:`.github/workflows/build-and-push.yml`
触发方式:
- 推送到 `main``master`
- 推送 `v*` Tag。
- 在 GitHub Actions 手动执行 `workflow_dispatch`
CI 会执行:
1. 使用 JDK 11 执行 `mvn -B clean package -DskipTests`
2. 基于 `zzyl-admin/Dockerfile` 构建并推送 `zzyl-admin:${tag}`
3. 基于 `zzyl-ui/Dockerfile` 使用 `pnpm install --frozen-lockfile && pnpm build:prod` 构建并推送 `zzyl-ui:${tag}`
4. 分支构建会额外推送 `latest` 标签。
镜像地址示例:
```text
registry.cn-hangzhou.aliyuncs.com/your-namespace/zzyl-admin:latest
registry.cn-hangzhou.aliyuncs.com/your-namespace/zzyl-ui:latest
```
## 4. 拉取项目与环境变量
推荐目录:
```bash
mkdir -p /site
mkdir -p /data/zzyl/{logs,uploadPath}
```
如果当前用户没有权限创建 `/site`,请使用 `sudo mkdir -p /site`,并把目录授权给部署用户。
在服务器直接拉取本项目:
```bash
cd /site
git clone https://github.com/shenjianZ/zhongzhou-elderly-care.git
cd zhongzhou-elderly-care
cp deploy/compose/.env.example deploy/compose/.env
```
后续部署都在项目目录 `/site/zhongzhou-elderly-care` 内操作,不需要把 Compose 或 SQL 文件复制到其他目录。
编辑 `deploy/compose/.env`,至少修改:
- `ZZYL_ADMIN_IMAGE``ZZYL_UI_IMAGE`
- `UI_PORT`,如果宿主机 Nginx 也监听 80,建议改为 `8080`
- `MYSQL_ROOT_PASSWORD``MYSQL_APP_PASSWORD``MYSQL_PASSWORD`
- `REDIS_PASSWORD`
- `TOKEN_SECRET``DRUID_LOGIN_PASSWORD`
- OSS、微信、华为云、百度千帆相关变量
注意:`MYSQL_APP_USER/MYSQL_APP_PASSWORD` 必须与 `MYSQL_USERNAME/MYSQL_PASSWORD` 保持一致。
### 4.1 环境变量填写要求
基础与镜像变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `TZ` | 容器时区 | 否 | 默认 `Asia/Shanghai` |
| `UI_PORT` | 前端对外端口 | 否 | 默认 `80`;宿主机已有 Nginx 时建议改为 `8080` |
| `APP_PORT` | 后端对外端口 | 否 | 默认 `9000`;主要用于排查,前端通过容器网络访问后端 |
| `ZZYL_ADMIN_IMAGE` | 后端镜像地址 | 是 | GitHub Actions 推送的 `zzyl-admin` 镜像 |
| `ZZYL_UI_IMAGE` | 前端镜像地址 | 是 | GitHub Actions 推送的 `zzyl-ui` 镜像 |
MySQL 变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `MYSQL_PORT` | MySQL 对外端口 | 否 | 默认 `3306`;端口冲突时修改 |
| `MYSQL_DATABASE` | 业务库名 | 否 | 默认 `zzyl` |
| `MYSQL_ROOT_PASSWORD` | MySQL root 密码 | 是 | 首次初始化数据库时使用 |
| `MYSQL_APP_USER` | 应用数据库账号 | 否 | 默认 `zzyl` |
| `MYSQL_APP_PASSWORD` | 应用数据库账号密码 | 是 | MySQL 容器创建应用账号时使用 |
| `MYSQL_URL` | 后端 JDBC 地址 | 否 | 使用 Compose 内置 MySQL 时保留默认即可 |
| `MYSQL_USERNAME` | 后端连接 MySQL 用户名 | 否 | 默认应与 `MYSQL_APP_USER` 一致 |
| `MYSQL_PASSWORD` | 后端连接 MySQL 密码 | 是 | 必须与 `MYSQL_APP_PASSWORD` 一致 |
Redis 与后端运行变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `REDIS_PORT` | Redis 对外端口 | 否 | 默认 `6379`;端口冲突时修改 |
| `REDIS_HOST` | 后端连接 Redis 主机 | 否 | 使用 Compose 内置 Redis 时保留 `zzyl-redis` |
| `REDIS_PASSWORD` | Redis 密码 | 是 | Redis 容器启动和后端连接都会使用 |
| `REDIS_DATABASE` | Redis 数据库索引 | 否 | 默认 `2` |
| `APP_LOG_DIR` | 后端日志挂载目录 | 否 | 默认 `/data/zzyl/logs` |
| `APP_PROFILE_DIR` | 文件上传挂载目录 | 否 | 默认 `/data/zzyl/uploadPath` |
| `RUOYI_PROFILE` | 后端文件存储路径 | 否 | 应与 `APP_PROFILE_DIR` 保持一致 |
| `TOKEN_SECRET` | 登录令牌签名密钥 | 是 | 生产环境必须改成足够长的随机字符串 |
| `TOKEN_EXPIRE_TIME` | 登录令牌有效期 | 否 | 默认 `3600` 秒 |
| `DRUID_LOGIN_USERNAME` | Druid 监控页用户名 | 否 | 默认 `ruoyi` |
| `DRUID_LOGIN_PASSWORD` | Druid 监控页密码 | 是 | 生产环境必须修改 |
| `DEPT_NURSING_ID` | 护理部门 ID | 否 | 默认 `201`,需与初始化数据中的部门一致 |
阿里云 OSS 变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `ALIYUN_OSS_DOMAIN` | OSS 访问域名 | 按功能 | 文件访问 URL 拼接使用 |
| `ALIYUN_OSS_ENDPOINT` | OSS API Endpoint | 按功能 | 上传文件时使用 |
| `ALIYUN_OSS_BUCKET` | OSS Bucket 名称 | 按功能 | 上传目标 Bucket |
| `ALIYUN_OSS_REGION` | OSS Region | 按功能 | 例如 `cn-hangzhou` |
| `ALIYUN_OSS_ACCESS_KEY_ID` | OSS AccessKey ID | 按功能 | 上传文件时使用 |
| `ALIYUN_OSS_SECRET_ACCESS_KEY` | OSS AccessKey Secret | 按功能 | 上传文件时使用 |
说明:OSS 不影响系统启动,但上传文件、图片、健康评估报告等功能需要填写。
百度千帆与微信变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `BAIDU_ACCESS_KEY` | 百度千帆 AccessKey | 按功能 | 健康评估 AI 生成时使用 |
| `BAIDU_SECRET_KEY` | 百度千帆 SecretKey | 按功能 | 健康评估 AI 生成时使用 |
| `BAIDU_QIANFAN_MODEL` | 百度千帆模型名 | 按功能 | 默认 `ERNIE-4.0-8K` |
| `WECHAT_MINI_PROGRAM_APP_ID` | 微信小程序 AppID | 按功能 | 小程序登录和获取手机号使用 |
| `WECHAT_MINI_PROGRAM_SECRET` | 微信小程序 Secret | 按功能 | 小程序登录和获取手机号使用 |
说明:百度千帆和微信不影响后台管理系统启动;未填写时,对应业务功能会失败。
华为云 IoTDA/AMQP 变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `HUAWEI_CLOUD_AK` | 华为云 AK | 是 | IoTDA SDK 客户端启动使用 |
| `HUAWEI_CLOUD_SK` | 华为云 SK | 是 | IoTDA SDK 客户端启动使用 |
| `HUAWEI_CLOUD_REGION_ID` | 华为云区域 ID | 是 | 例如 `cn-east-3` |
| `HUAWEI_CLOUD_ENDPOINT` | IoTDA HTTPS 接入地址 | 是 | 设备管理接口使用 |
| `HUAWEI_CLOUD_PROJECT_ID` | 华为云 ProjectId | 是 | IoTDA SDK 鉴权使用 |
| `HUAWEI_CLOUD_AMQP_HOST` | AMQP 接入地址 | 是 | 设备消息消费客户端启动使用 |
| `HUAWEI_CLOUD_AMQP_ACCESS_KEY` | AMQP AccessKey | 是 | AMQP 连接用户名组成部分 |
| `HUAWEI_CLOUD_AMQP_ACCESS_CODE` | AMQP AccessCode | 是 | AMQP 连接密码 |
| `HUAWEI_CLOUD_AMQP_QUEUE_NAME` | AMQP 队列名称 | 是 | 默认通常为 `DefaultQueue` |
说明:当前后端启动时会自动启动华为云 AMQP 消费客户端,所以 `HUAWEI_CLOUD_*` 不能保留 `change_me` 占位值。
### 4.2 中间件清单
| 中间件 | 用途 | 是否必须 |
| --- | --- | --- |
| MySQL 8 | 存储业务数据、系统用户、菜单、养老业务数据、Quartz 任务表 | 必须 |
| Redis 7 | 缓存、验证码、登录 Token、系统临时数据 | 必须 |
| Nginx | 部署前端 `zzyl-ui` 静态资源,并反向代理 `/prod-api/` 到后端 | 必须,已内置在前端镜像中 |
| Docker / Docker Compose | 容器化部署 MySQL、Redis、后端、前端 | 必须 |
| Quartz | 后端定时任务调度,表结构来自 `sql/quartz.sql` | 必须,随后端运行 |
| Druid | 后端数据库连接池和监控页面 | 必须,随 Java 应用运行 |
第三方云服务不算传统中间件,但部署时也会用到:
| 服务 | 用途 | 是否必须 |
| --- | --- | --- |
| 阿里云 OSS | 文件、图片、报告上传存储 | 按功能需要 |
| 华为云 IoTDA / AMQP | 设备管理、设备消息消费 | 当前启动时必须配置 |
| 百度千帆 | 健康评估 AI 生成 | 按功能需要 |
| 微信小程序接口 | 小程序登录、获取手机号 | 按功能需要 |
| 阿里云 ACR 或其他镜像仓库 | 保存 CI 构建出的前后端镜像 | 部署镜像时必须 |
## 5. 首次部署
进入部署目录:
```bash
cd /site/zhongzhou-elderly-care/deploy/compose
docker compose --env-file .env up -d mysql redis
```
初始化数据库:
```bash
set -a
. ./.env
set +a
docker exec -i zzyl-mysql mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" < ../../sql/dev0302.sql
docker exec -i zzyl-mysql mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" zzyl < ../../sql/quartz.sql
```
启动完整系统:
```bash
docker compose --env-file .env pull
docker compose --env-file .env up -d
docker compose --env-file .env ps
```
## 6. 进入系统
浏览器访问:
```text
http://服务器IP或域名/
```
如果 `UI_PORT` 不是 `80`,访问:
```text
http://服务器IP或域名:${UI_PORT}/
```
默认后台账号:
- 用户名:`admin`
- 密码:`admin123`
首次登录后请立即修改管理员密码,并检查系统管理、养老业务菜单是否正常显示。
## 7. 升级与验证
升级:
```bash
cd /site/zhongzhou-elderly-care
git pull
cd deploy/compose
docker compose --env-file .env pull
docker compose --env-file .env up -d
docker image prune -f
```
验证:
```bash
docker compose --env-file .env ps
docker logs zzyl-admin --tail 200
docker logs zzyl-ui --tail 100
curl -I http://127.0.0.1:${UI_PORT}/
```
常见问题:
- 前端打不开:检查 `zzyl-ui` 容器、`UI_PORT`、安全组和防火墙。
- 登录验证码失败:检查 `/prod-api/captchaImage` 是否被 Nginx 转发到后端。
- 后端启动失败:优先查看 MySQL、Redis、华为云 IoTDA/AMQP、OSS、百度千帆变量。
- 上传失败:检查 OSS 配置和 `RUOYI_PROFILE=/data/zzyl/uploadPath`
+3 -1
View File
@@ -1,8 +1,10 @@
# 基础镜像
FROM eclipse-temurin:11-jre-jammy
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# ENV OSS_ACCESS_KEY_ID LTAI5tFww3VE7EZSs9dfh7j5
# ENV OSS_ACCESS_KEY_SECRET 3eVYBbuK1F8rX5Tv0ge8lkKG1TrOLs
# 拷贝jar包
COPY zzyl-admin.jar /app.jar
# 入口
@@ -199,8 +199,8 @@ aliyun:
endpoint: https://oss-cn-beijing.aliyuncs.com
bucket-name: hzhm-mlgb2
region: cn-hangzhou
accessKeyId: ${ALIYUN_OSS_ACCESS_KEY_ID:change_me_oss_key}
secretAccessKey: ${ALIYUN_OSS_SECRET_ACCESS_KEY:change_me_oss_secret}
accessKeyId: LTAI5t9pLcu65GPXwLv4PnE6
secretAccessKey: bdHXj3CpcsdiW084S1cvY6DBgjBwLZ
dept:
nursingId: 201
@@ -7,7 +7,7 @@ ruoyi:
# 版权年份
copyrightYear: 2024
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: ${RUOYI_PROFILE:/home/ruoyi/uploadPath}
profile: D:/JAVAdevelop/ruoyi/uploadPath
# 获取ip地址开关
addressEnabled: false
# 验证码类型 math 数字计算 char 字符验证
@@ -54,9 +54,9 @@ spring:
druid:
# 主库数据源
master:
url: ${MYSQL_URL:jdbc:mysql://zzyl-mysql:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai}
username: ${MYSQL_USERNAME:zzyl}
password: ${MYSQL_PASSWORD:change_me_mysql_app}
url: jdbc:mysql://192.168.100.168:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: heima123
# 从库数据源
slave:
# 从数据源开关/默认关闭
@@ -95,8 +95,8 @@ spring:
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: ${DRUID_LOGIN_USERNAME:ruoyi}
login-password: ${DRUID_LOGIN_PASSWORD:change_me_druid}
login-username: ruoyi
login-password: 123456
filter:
stat:
enabled: true
@@ -128,13 +128,13 @@ spring:
# redis 配置
redis:
# 地址
host: ${REDIS_HOST:zzyl-redis}
host: 192.168.100.168
# 端口,默认为6379
port: ${REDIS_PORT:6379}
port: 6379
# 数据库索引
database: ${REDIS_DATABASE:2}
database: 2
# 密码
password: ${REDIS_PASSWORD:change_me_redis}
password: 123456
# 连接超时时间
timeout: 10s
lettuce:
@@ -153,9 +153,9 @@ token:
# 令牌自定义标识
header: Authorization
# 令牌密钥
secret: ${TOKEN_SECRET:change_me_token_secret}
secret: abcdefghijklmnopqrstuvwxyz
# 令牌有效期(默认3600秒,即1小时)
expireTime: ${TOKEN_EXPIRE_TIME:3600}
expireTime: 3600
# MyBatisPlus配置
mybatis-plus:
@@ -195,34 +195,18 @@ xss:
# 阿里云OSS相关配置
aliyun:
oss:
domain: ${ALIYUN_OSS_DOMAIN:oss-cn-hangzhou.aliyuncs.com}
endpoint: ${ALIYUN_OSS_ENDPOINT:https://oss-cn-hangzhou.aliyuncs.com}
bucket-name: ${ALIYUN_OSS_BUCKET:change-me-bucket}
region: ${ALIYUN_OSS_REGION:cn-hangzhou}
accessKeyId: ${ALIYUN_OSS_ACCESS_KEY_ID:change_me_oss_key}
secretAccessKey: ${ALIYUN_OSS_SECRET_ACCESS_KEY:change_me_oss_secret}
domain: oss-cn-beijing.aliyuncs.com
endpoint: https://oss-cn-beijing.aliyuncs.com
bucket-name: hzhm-mlgb2
region: cn-hangzhou
accessKeyId: LTAI5t9pLcu65GPXwLv4PnE6
secretAccessKey: bdHXj3CpcsdiW084S1cvY6DBgjBwLZ
dept:
nursingId: ${DEPT_NURSING_ID:201}
nursingId: 201
# 百度千帆大模型配置
baidu:
accessKey: ${BAIDU_ACCESS_KEY:change_me_baidu_key}
secretKey: ${BAIDU_SECRET_KEY:change_me_baidu_secret}
qianfanModel: ${BAIDU_QIANFAN_MODEL:ERNIE-4.0-8K}
wechat:
mini-program:
appId: ${WECHAT_MINI_PROGRAM_APP_ID:change_me_wechat_appid}
secret: ${WECHAT_MINI_PROGRAM_SECRET:change_me_wechat_secret}
huaweicloud:
ak: ${HUAWEI_CLOUD_AK:change_me_huawei_ak}
sk: ${HUAWEI_CLOUD_SK:change_me_huawei_sk}
regionId: ${HUAWEI_CLOUD_REGION_ID:cn-east-3}
endpoint: ${HUAWEI_CLOUD_ENDPOINT:change_me_huawei_endpoint}
projectId: ${HUAWEI_CLOUD_PROJECT_ID:change_me_huawei_project_id}
host: ${HUAWEI_CLOUD_AMQP_HOST:change_me_huawei_amqp_host}
accessKey: ${HUAWEI_CLOUD_AMQP_ACCESS_KEY:change_me_huawei_amqp_access_key}
accessCode: ${HUAWEI_CLOUD_AMQP_ACCESS_CODE:change_me_huawei_amqp_access_code}
queueName: ${HUAWEI_CLOUD_AMQP_QUEUE_NAME:DefaultQueue}
accessKey: fONdLXB5zssLPU5PTIBRsyjl
secretKey: 9ntuGXNc482mKuOGy6pe1THSOzMB1oTs
qianfanModel: ERNIE-4.0-8K-Preview
@@ -199,8 +199,8 @@ aliyun:
endpoint: https://oss-cn-beijing.aliyuncs.com
bucket-name: hzhm-mlgb2
region: cn-hangzhou
accessKeyId: ${ALIYUN_OSS_ACCESS_KEY_ID:change_me_oss_key}
secretAccessKey: ${ALIYUN_OSS_SECRET_ACCESS_KEY:change_me_oss_secret}
accessKeyId: LTAI5t9pLcu65GPXwLv4PnE6
secretAccessKey: bdHXj3CpcsdiW084S1cvY6DBgjBwLZ
dept:
nursingId: 201
-7
View File
@@ -1,7 +0,0 @@
node_modules
dist
.git
.gitignore
.env.local
.env.*.local
*.log
-20
View File
@@ -1,20 +0,0 @@
FROM node:18-alpine AS build
WORKDIR /app
ENV NODE_OPTIONS=--openssl-legacy-provider
RUN corepack enable && corepack prepare pnpm@10.33.0 --activate
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build:prod
FROM registry.cn-hangzhou.aliyuncs.com/pull-image/nginx:mainline-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
+8 -5
View File
@@ -5,13 +5,16 @@
git clone https://gitee.com/y_project/RuoYi-Vue
# 进入项目目录
cd zzyl-ui
cd ruoyi-ui
# 安装依赖
pnpm install
npm install
# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npmmirror.com
# 启动服务
pnpm dev
npm run dev
```
浏览器访问 http://localhost:80
@@ -20,8 +23,8 @@ pnpm dev
```bash
# 构建测试环境
pnpm build:stage
npm run build:stage
# 构建生产环境
pnpm build:prod
npm run build:prod
```
-26
View File
@@ -1,26 +0,0 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
client_max_body_size 20m;
gzip_static on;
location / {
try_files $uri $uri/ /index.html;
}
location /prod-api/ {
proxy_pass http://zzyl-admin:9000/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
+1 -2
View File
@@ -86,6 +86,5 @@
"browserslist": [
"> 1%",
"last 2 versions"
],
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
]
}
-12376
View File
File diff suppressed because it is too large Load Diff