服务打包初步结构
This commit is contained in:
@@ -29,6 +29,7 @@ networks:
|
|||||||
|
|
||||||
# 共享卷定义
|
# 共享卷定义
|
||||||
volumes:
|
volumes:
|
||||||
|
# 基础设施
|
||||||
nacos-data:
|
nacos-data:
|
||||||
driver: local
|
driver: local
|
||||||
nacos-logs:
|
nacos-logs:
|
||||||
@@ -37,6 +38,7 @@ volumes:
|
|||||||
driver: local
|
driver: local
|
||||||
minio-config:
|
minio-config:
|
||||||
driver: local
|
driver: local
|
||||||
|
# Jitsi
|
||||||
jitsi-web:
|
jitsi-web:
|
||||||
driver: local
|
driver: local
|
||||||
jitsi-prosody:
|
jitsi-prosody:
|
||||||
@@ -45,7 +47,13 @@ volumes:
|
|||||||
driver: local
|
driver: local
|
||||||
jitsi-jvb:
|
jitsi-jvb:
|
||||||
driver: local
|
driver: local
|
||||||
|
# 后端服务
|
||||||
serv-logs:
|
serv-logs:
|
||||||
driver: local
|
driver: local
|
||||||
|
serv-config:
|
||||||
|
driver: local
|
||||||
|
# 前端服务
|
||||||
web-logs:
|
web-logs:
|
||||||
driver: local
|
driver: local
|
||||||
|
web-config:
|
||||||
|
driver: local
|
||||||
|
|||||||
37
docker/nginx/docker-compose.yml
Normal file
37
docker/nginx/docker-compose.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# ================================================
|
||||||
|
# Level 1: 基础设施服务
|
||||||
|
# Nacos, MinIO, Nginx, Jitsi Meet
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
# ====================== Nginx 反向代理 ======================
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: urban-lifeline-nginx
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- urban-lifeline
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
- ${DATA_ROOT:-../volumes}/nginx/logs:/var/log/nginx
|
||||||
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||||||
|
# SSL 证书(可选)
|
||||||
|
# - ./nginx/ssl:/etc/nginx/ssl:ro
|
||||||
|
depends_on:
|
||||||
|
- urban-lifeline-serv
|
||||||
|
- urban-lifeline-web
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 30s
|
||||||
|
|
||||||
|
networks:
|
||||||
|
urban-lifeline:
|
||||||
|
name: urban-lifeline
|
||||||
131
docker/nginx/nginx/conf.d/default.conf
Normal file
131
docker/nginx/nginx/conf.d/default.conf
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# ================================================
|
||||||
|
# Urban Lifeline - 站点配置 (All-in-One 模式)
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
# 上游服务定义 - 后端 All-in-One 容器
|
||||||
|
upstream gateway {
|
||||||
|
server urban-lifeline-serv:8080;
|
||||||
|
keepalive 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 上游服务定义 - 前端 All-in-One 容器
|
||||||
|
upstream shared {
|
||||||
|
server urban-lifeline-web:8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream platform {
|
||||||
|
server urban-lifeline-web:8001;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream workcase-web {
|
||||||
|
server urban-lifeline-web:8002;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream bidding-web {
|
||||||
|
server urban-lifeline-web:8003;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream workcase-wechat {
|
||||||
|
server urban-lifeline-web:8004;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
# 健康检查端点
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ====================== 前端应用代理 ======================
|
||||||
|
|
||||||
|
# Shared 公共模块 (Module Federation 远程模块)
|
||||||
|
location /shared/ {
|
||||||
|
proxy_pass http://shared/;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# 允许跨域 (Module Federation 需要)
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, OPTIONS";
|
||||||
|
add_header Access-Control-Allow-Headers "Origin, Content-Type, Accept";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Platform 管理平台
|
||||||
|
location /platform/ {
|
||||||
|
proxy_pass http://platform/;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Workcase 工单系统 PC端
|
||||||
|
location /workcase/ {
|
||||||
|
proxy_pass http://workcase-web/;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Bidding 招标系统
|
||||||
|
location /bidding/ {
|
||||||
|
proxy_pass http://bidding-web/;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Workcase 工单系统微信端
|
||||||
|
location /workcase-wechat/ {
|
||||||
|
proxy_pass http://workcase-wechat/;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 默认首页(重定向到 platform)
|
||||||
|
location = / {
|
||||||
|
return 302 /platform/;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ====================== API 代理 ======================
|
||||||
|
|
||||||
|
# 后端 API 代理
|
||||||
|
location /urban-lifeline/ {
|
||||||
|
proxy_pass http://gateway/urban-lifeline/;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# WebSocket 支持
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
# 超时设置
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ====================== 错误页面 ======================
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
||||||
47
docker/nginx/nginx/nginx.conf
Normal file
47
docker/nginx/nginx/nginx.conf
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# ================================================
|
||||||
|
# Urban Lifeline - Nginx 主配置
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
use epoll;
|
||||||
|
multi_accept on;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
# 日志格式
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
# 性能优化
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
types_hash_max_size 2048;
|
||||||
|
|
||||||
|
# Gzip 压缩
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_comp_level 6;
|
||||||
|
gzip_types text/plain text/css text/xml application/json application/javascript
|
||||||
|
application/xml application/xml+rss text/javascript application/x-javascript;
|
||||||
|
|
||||||
|
# 上传文件大小限制
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
# 引入站点配置
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
||||||
@@ -6,6 +6,10 @@
|
|||||||
# 镜像版本
|
# 镜像版本
|
||||||
IMAGE_VERSION=latest
|
IMAGE_VERSION=latest
|
||||||
|
|
||||||
|
# 数据目录 (日志、配置等)
|
||||||
|
DATA_ROOT=../volumes
|
||||||
|
|
||||||
|
# ==================== 后端配置 ====================
|
||||||
# Spring 运行环境
|
# Spring 运行环境
|
||||||
SPRING_PROFILES_ACTIVE=prod
|
SPRING_PROFILES_ACTIVE=prod
|
||||||
|
|
||||||
@@ -13,21 +17,30 @@ SPRING_PROFILES_ACTIVE=prod
|
|||||||
NACOS_SERVER_ADDR=nacos:8848
|
NACOS_SERVER_ADDR=nacos:8848
|
||||||
NACOS_NAMESPACE=
|
NACOS_NAMESPACE=
|
||||||
|
|
||||||
|
# ==================== 前端配置 ====================
|
||||||
|
# 前端端口 (可自定义)
|
||||||
|
SHARED_PORT=8000
|
||||||
|
PLATFORM_PORT=8001
|
||||||
|
WORKCASE_PORT=8002
|
||||||
|
BIDDING_PORT=8003
|
||||||
|
WORKCASE_WECHAT_PORT=8004
|
||||||
|
|
||||||
|
# ==================== 基础设施 ====================
|
||||||
|
# MySQL (Nacos 使用)
|
||||||
|
MYSQL_HOST=host.docker.internal
|
||||||
|
MYSQL_PORT=3306
|
||||||
|
MYSQL_USER=root
|
||||||
|
MYSQL_PASSWORD=123456
|
||||||
|
|
||||||
# MinIO 配置
|
# MinIO 配置
|
||||||
MINIO_ENDPOINT=http://minio:9000
|
MINIO_ROOT_USER=minioadmin
|
||||||
|
MINIO_ROOT_PASSWORD=minioadmin123
|
||||||
|
|
||||||
# Dify AI 配置
|
# Dify AI 配置
|
||||||
DIFY_API_URL=http://dify-api:5001
|
DIFY_API_URL=http://dify-api:5001
|
||||||
|
|
||||||
# 日志目录
|
# ==================== Jitsi 视频会议 ====================
|
||||||
LOG_ROOT=../../volumes/logs
|
JWT_APP_ID=urbanLifeline
|
||||||
|
JWT_APP_SECRET=urbanLifeline-jitsi-secret-key-2025-production-safe-hs256
|
||||||
# 前端 API 地址
|
JVB_HOST_ADDRESS=192.168.0.253
|
||||||
API_BASE_URL=http://gateway:8080
|
JITSI_PUBLIC_URL=https://org.xyzh.yslg.jitsi
|
||||||
|
|
||||||
# 端口映射
|
|
||||||
GATEWAY_PORT=8080
|
|
||||||
PLATFORM_PORT=8001
|
|
||||||
WORKCASE_PORT=8002
|
|
||||||
BIDDING_WEB_PORT=8003
|
|
||||||
WORKCASE_WECHAT_PORT=8004
|
|
||||||
|
|||||||
@@ -1,28 +1,26 @@
|
|||||||
# Urban Lifeline Docker 部署
|
# Urban Lifeline Docker 部署 (All-in-One)
|
||||||
|
|
||||||
## 目录结构
|
## 目录结构
|
||||||
|
|
||||||
```
|
```
|
||||||
docker/urbanLifeline/
|
docker/urbanLifeline/
|
||||||
├── .env.example # 环境变量示例
|
├── .env.example # 环境变量示例
|
||||||
|
├── Makefile # 快捷命令
|
||||||
├── README.md # 本文档
|
├── README.md # 本文档
|
||||||
├── serv/ # 后端服务
|
├── serv/ # 后端服务
|
||||||
│ ├── docker-compose.yml
|
|
||||||
│ ├── build.sh # 构建脚本
|
│ ├── build.sh # 构建脚本
|
||||||
│ ├── start.sh # 启动脚本
|
|
||||||
│ ├── Dockerfile.base # 基础镜像
|
│ ├── Dockerfile.base # 基础镜像
|
||||||
│ ├── Dockerfile.template # 服务模板
|
│ ├── Dockerfile.serv # 服务镜像
|
||||||
│ └── Dockerfile.* # 各服务 Dockerfile
|
│ └── service-manager.sh # 服务管理脚本
|
||||||
└── web/ # 前端应用
|
└── web/ # 前端应用
|
||||||
├── docker-compose.yml
|
|
||||||
├── build.sh # 构建脚本
|
├── build.sh # 构建脚本
|
||||||
├── nginx.conf # Nginx 配置
|
├── Dockerfile.web # 前端镜像
|
||||||
└── Dockerfile.* # 各前端 Dockerfile
|
└── web-manager.sh # 前端管理脚本
|
||||||
```
|
```
|
||||||
|
|
||||||
## 服务端口
|
## 服务端口
|
||||||
|
|
||||||
### 后端服务
|
### 后端服务 (urban-lifeline-serv)
|
||||||
| 服务 | 端口 | 说明 |
|
| 服务 | 端口 | 说明 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| gateway | 8080 | API 网关 |
|
| gateway | 8080 | API 网关 |
|
||||||
@@ -37,56 +35,82 @@ docker/urbanLifeline/
|
|||||||
| platform | 8089 | 平台服务 |
|
| platform | 8089 | 平台服务 |
|
||||||
| ai | 8090 | AI 服务 |
|
| ai | 8090 | AI 服务 |
|
||||||
|
|
||||||
### 前端应用
|
### 前端应用 (urban-lifeline-web)
|
||||||
| 应用 | 端口 | 说明 |
|
| 应用 | 端口 | 说明 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
|
| shared | 8000 | 公共模块 (Module Federation) |
|
||||||
| platform | 8001 | 管理平台 |
|
| platform | 8001 | 管理平台 |
|
||||||
| workcase-web | 8002 | 工单系统 PC |
|
| workcase | 8002 | 工单系统 PC |
|
||||||
| bidding-web | 8003 | 招标系统 |
|
| bidding | 8003 | 招标系统 |
|
||||||
| workcase-wechat | 8004 | 工单微信端 |
|
| workcase_wechat | 8004 | 工单微信端 |
|
||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
|
|
||||||
### 1. 准备环境变量
|
### 1. 准备环境变量
|
||||||
```bash
|
```bash
|
||||||
|
cd docker/urbanLifeline
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
# 编辑 .env 配置
|
# 编辑 .env 配置
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 构建后端
|
### 2. 构建镜像
|
||||||
```bash
|
```bash
|
||||||
# 先编译 Java 项目
|
# 构建后端 (需先编译 Java)
|
||||||
cd urbanLifelineServ
|
cd urbanLifelineServ && mvn clean package -DskipTests
|
||||||
mvn clean package -DskipTests
|
cd docker/urbanLifeline && make build-serv
|
||||||
|
|
||||||
# 构建 Docker 镜像
|
# 构建前端 (需先构建前端)
|
||||||
cd docker/urbanLifeline/serv
|
cd urbanLifelineWeb && pnpm build
|
||||||
./build.sh # 构建所有
|
cd docker/urbanLifeline && make build-web
|
||||||
./build.sh gateway # 构建单个
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 构建前端
|
### 3. 启动服务
|
||||||
```bash
|
```bash
|
||||||
# 先构建前端项目
|
make up
|
||||||
cd urbanLifelineWeb
|
|
||||||
pnpm install
|
|
||||||
pnpm build
|
|
||||||
|
|
||||||
# 构建 Docker 镜像
|
|
||||||
cd docker/urbanLifeline/web
|
|
||||||
./build.sh # 构建所有
|
|
||||||
./build.sh platform # 构建单个
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 启动服务
|
### 4. 管理服务
|
||||||
```bash
|
```bash
|
||||||
# 启动后端
|
# 查看状态
|
||||||
cd docker/urbanLifeline/serv
|
make status
|
||||||
docker-compose --profile serv up -d
|
|
||||||
|
|
||||||
# 启动前端
|
# 重启单个后端服务
|
||||||
cd docker/urbanLifeline/web
|
make restart-serv SERVICE=gateway
|
||||||
docker-compose --profile web up -d
|
|
||||||
|
# 重启单个前端站点
|
||||||
|
make restart-web SITE=platform
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
make logs
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置外挂
|
||||||
|
|
||||||
|
容器支持配置外挂,可在运行时覆盖默认配置:
|
||||||
|
|
||||||
|
### 后端配置目录结构
|
||||||
|
```
|
||||||
|
volumes/config/serv/
|
||||||
|
├── gateway.yml # gateway 服务配置
|
||||||
|
├── system.yml # system 服务配置
|
||||||
|
├── auth.yml # auth 服务配置
|
||||||
|
├── file.yml # file 服务配置
|
||||||
|
├── log.yml # log 服务配置
|
||||||
|
├── message.yml # message 服务配置
|
||||||
|
├── crontab.yml # crontab 服务配置
|
||||||
|
├── ai.yml # ai 服务配置
|
||||||
|
├── bidding.yml # bidding 服务配置
|
||||||
|
├── platform.yml # platform 服务配置
|
||||||
|
└── workcase.yml # workcase 服务配置
|
||||||
|
```
|
||||||
|
|
||||||
|
每个服务的配置文件会通过 `spring.config.additional-location` 加载,覆盖 JAR 包内的默认配置。
|
||||||
|
|
||||||
|
### 前端配置
|
||||||
|
```
|
||||||
|
volumes/config/web/
|
||||||
|
├── env.js # 运行时环境变量
|
||||||
|
└── config.json # 应用配置
|
||||||
```
|
```
|
||||||
|
|
||||||
## 依赖服务
|
## 依赖服务
|
||||||
@@ -97,4 +121,4 @@ docker-compose --profile web up -d
|
|||||||
- Redis (缓存)
|
- Redis (缓存)
|
||||||
- MinIO (对象存储)
|
- MinIO (对象存储)
|
||||||
|
|
||||||
可通过 `docker/infra` 目录启动基础设施。
|
通过 `docker compose --profile infra up -d` 启动基础设施。
|
||||||
|
|||||||
33
docker/urbanLifeline/postgres/.env.example
Normal file
33
docker/urbanLifeline/postgres/.env.example
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# ================================================
|
||||||
|
# PostgreSQL 配置
|
||||||
|
# 复制此文件为 .env 并修改配置
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# PostgreSQL 版本
|
||||||
|
# ------------------------------
|
||||||
|
POSTGRES_VERSION=16
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# 端口配置
|
||||||
|
# ------------------------------
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# 数据库配置
|
||||||
|
# ------------------------------
|
||||||
|
POSTGRES_USER=postgres
|
||||||
|
POSTGRES_PASSWORD=postgres123456
|
||||||
|
POSTGRES_DB=urban_lifeline
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# 挂载目录配置
|
||||||
|
# ------------------------------
|
||||||
|
# 数据目录
|
||||||
|
DATA_ROOT=./volumes
|
||||||
|
|
||||||
|
# 日志目录
|
||||||
|
LOG_ROOT=./volumes
|
||||||
|
|
||||||
|
# 配置文件目录
|
||||||
|
CONFIG_ROOT=./volumes
|
||||||
107
docker/urbanLifeline/postgres/Dockerfile.pg
Normal file
107
docker/urbanLifeline/postgres/Dockerfile.pg
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# ================================================
|
||||||
|
# Urban Lifeline - PostgreSQL 数据库镜像
|
||||||
|
# 支持初始化脚本和自定义配置
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
FROM postgres:16-alpine
|
||||||
|
|
||||||
|
# 设置环境变量
|
||||||
|
ENV LANG=C.UTF-8 \
|
||||||
|
TZ=Asia/Shanghai \
|
||||||
|
PGCLIENTENCODING=UTF8
|
||||||
|
|
||||||
|
# 安装时区数据
|
||||||
|
RUN apk add --no-cache tzdata \
|
||||||
|
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
|
||||||
|
&& echo "Asia/Shanghai" > /etc/timezone
|
||||||
|
|
||||||
|
# 创建初始化目录
|
||||||
|
RUN mkdir -p /docker-entrypoint-initdb.d /opt/sql
|
||||||
|
|
||||||
|
# 复制初始化脚本和 SQL 文件
|
||||||
|
COPY init/sql/ /opt/sql/
|
||||||
|
COPY init/bin.sh /opt/bin.sh
|
||||||
|
|
||||||
|
# 创建 Docker 初始化入口脚本
|
||||||
|
RUN cat > /docker-entrypoint-initdb.d/01-init-database.sh <<'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Urban Lifeline - PostgreSQL 数据库初始化"
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
|
# 设置环境变量
|
||||||
|
export PGCLIENTENCODING=UTF8
|
||||||
|
|
||||||
|
# 检查数据库是否已初始化(通过检查初始化状态表)
|
||||||
|
check_initialized() {
|
||||||
|
# 先检查数据库是否存在
|
||||||
|
if ! psql -U "$POSTGRES_USER" -d "postgres" -tAc "SELECT 1 FROM pg_database WHERE datname = '$POSTGRES_DB'" | grep -q 1; then
|
||||||
|
return 1 # 数据库不存在,需要初始化
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查初始化状态表是否存在且标记为成功
|
||||||
|
if psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -tAc "SELECT 1 FROM _db_init_status WHERE script_name = '01-init-database.sh' AND status = 'success'" 2>/dev/null | grep -q 1; then
|
||||||
|
return 0 # 已初始化
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1 # 未初始化
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查是否已经初始化
|
||||||
|
if check_initialized; then
|
||||||
|
echo "=========================================="
|
||||||
|
echo "✅ 数据库已初始化,跳过初始化步骤"
|
||||||
|
echo "=========================================="
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "首次启动,开始初始化数据库..."
|
||||||
|
|
||||||
|
cd /opt/sql
|
||||||
|
|
||||||
|
# 执行 initAll.sql(包含创建数据库、表结构和初始数据)
|
||||||
|
echo "执行数据库初始化脚本..."
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "postgres" -f initAll.sql
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "=========================================="
|
||||||
|
echo "❌ 数据库初始化失败!"
|
||||||
|
echo "=========================================="
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 创建初始化状态表并标记完成
|
||||||
|
echo "标记初始化状态..."
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||||
|
-- 创建初始化状态表
|
||||||
|
CREATE TABLE IF NOT EXISTS _db_init_status (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
script_name VARCHAR(255) NOT NULL UNIQUE,
|
||||||
|
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
status VARCHAR(50) DEFAULT 'init'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 标记初始化完成
|
||||||
|
INSERT INTO _db_init_status (script_name, status)
|
||||||
|
VALUES ('01-init-database.sh', 'success')
|
||||||
|
ON CONFLICT (script_name) DO UPDATE SET status = 'success', executed_at = CURRENT_TIMESTAMP;
|
||||||
|
EOSQL
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "✅ 数据库初始化完成!"
|
||||||
|
echo "默认用户: admin, 密码: 123456"
|
||||||
|
echo "=========================================="
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 设置执行权限
|
||||||
|
RUN chmod +x /docker-entrypoint-initdb.d/01-init-database.sh \
|
||||||
|
&& chmod +x /opt/bin.sh
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 5432
|
||||||
|
|
||||||
|
# 健康检查
|
||||||
|
HEALTHCHECK --interval=10s --timeout=5s --retries=5 --start-period=60s \
|
||||||
|
CMD pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-urban_lifeline} || exit 1
|
||||||
68
docker/urbanLifeline/postgres/docker-compose.yml
Normal file
68
docker/urbanLifeline/postgres/docker-compose.yml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# ================================================
|
||||||
|
# Urban Lifeline - PostgreSQL 数据库
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.pg
|
||||||
|
image: urban-lifeline-postgres:${POSTGRES_VERSION:-16}
|
||||||
|
container_name: urban-lifeline-postgres
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
networks:
|
||||||
|
- urban-lifeline
|
||||||
|
ports:
|
||||||
|
- "${POSTGRES_PORT:-5432}:5432"
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres123456}
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-urban_lifeline}
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
PGTZ: Asia/Shanghai
|
||||||
|
PGCLIENTENCODING: UTF8
|
||||||
|
volumes:
|
||||||
|
# 数据目录
|
||||||
|
- ${DATA_ROOT:-./volumes}/data:/var/lib/postgresql/data
|
||||||
|
# 日志目录
|
||||||
|
- ${LOG_ROOT:-./volumes}/logs:/var/log/postgresql
|
||||||
|
# 配置文件目录(可选,用于自定义 postgresql.conf)
|
||||||
|
- ${CONFIG_ROOT:-./volumes}/config:/etc/postgresql/conf.d:ro
|
||||||
|
command:
|
||||||
|
- "postgres"
|
||||||
|
- "-c"
|
||||||
|
- "max_connections=200"
|
||||||
|
- "-c"
|
||||||
|
- "shared_buffers=256MB"
|
||||||
|
- "-c"
|
||||||
|
- "effective_cache_size=768MB"
|
||||||
|
- "-c"
|
||||||
|
- "maintenance_work_mem=64MB"
|
||||||
|
- "-c"
|
||||||
|
- "checkpoint_completion_target=0.9"
|
||||||
|
- "-c"
|
||||||
|
- "wal_buffers=16MB"
|
||||||
|
- "-c"
|
||||||
|
- "default_statistics_target=100"
|
||||||
|
- "-c"
|
||||||
|
- "random_page_cost=1.1"
|
||||||
|
- "-c"
|
||||||
|
- "effective_io_concurrency=200"
|
||||||
|
- "-c"
|
||||||
|
- "log_timezone=Asia/Shanghai"
|
||||||
|
- "-c"
|
||||||
|
- "timezone=Asia/Shanghai"
|
||||||
|
- "-c"
|
||||||
|
- "client_encoding=UTF8"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-urban_lifeline}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 60s
|
||||||
|
|
||||||
|
networks:
|
||||||
|
urban-lifeline:
|
||||||
|
name: urban-lifeline
|
||||||
290
docker/urbanLifeline/postgres/init/bin.sh
Normal file
290
docker/urbanLifeline/postgres/init/bin.sh
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 定义颜色输出
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# 设置脚本所在目录为工作目录
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
SQL_DIR="${SCRIPT_DIR}/sql"
|
||||||
|
|
||||||
|
# 打印带时间戳的日志
|
||||||
|
log() {
|
||||||
|
local level=$1
|
||||||
|
local message=$2
|
||||||
|
local color=$NC
|
||||||
|
|
||||||
|
case $level in
|
||||||
|
"INFO") color=$BLUE;;
|
||||||
|
"SUCCESS") color=$GREEN;;
|
||||||
|
"WARN") color=$YELLOW;;
|
||||||
|
"ERROR") color=$RED;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] ${color}${level}${NC}: ${message}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 数据库连接信息(可通过环境变量覆盖)
|
||||||
|
DB_HOST=${POSTGRES_HOST:-"localhost"}
|
||||||
|
DB_PORT=${POSTGRES_PORT:-"5432"}
|
||||||
|
DB_NAME=${POSTGRES_DB:-"urban_lifeline"}
|
||||||
|
DB_USER=${POSTGRES_USER:-"postgres"}
|
||||||
|
DB_PASSWORD=${POSTGRES_PASSWORD:-"postgres"}
|
||||||
|
|
||||||
|
# 设置 PSQL 环境变量以支持中文
|
||||||
|
export PGCLIENTENCODING=UTF8
|
||||||
|
|
||||||
|
# 检查psql命令是否可用
|
||||||
|
check_psql() {
|
||||||
|
if ! command -v psql &> /dev/null; then
|
||||||
|
echo -e "${RED}Error: psql command not found. Please install PostgreSQL client.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查并创建数据库用户
|
||||||
|
check_and_create_user() {
|
||||||
|
local new_user=$1
|
||||||
|
local new_password=$2
|
||||||
|
|
||||||
|
# 使用 postgres 用户执行
|
||||||
|
if sudo -u postgres psql -c "SELECT 1 FROM pg_roles WHERE rolname = '$new_user'" | grep -q 1; then
|
||||||
|
echo -e "${GREEN}User $new_user already exists${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}Creating user $new_user...${NC}"
|
||||||
|
sudo -u postgres psql -c "CREATE USER $new_user WITH PASSWORD '$new_password' CREATEDB;"
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}User $new_user created successfully${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}Failed to create user $new_user${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查数据库连接
|
||||||
|
check_db_connection() {
|
||||||
|
# 首先尝试以当前用户身份连接
|
||||||
|
if ! psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "postgres" -c '\q' &> /dev/null; then
|
||||||
|
echo -e "${YELLOW}Could not connect with current settings, attempting to create user...${NC}"
|
||||||
|
# 创建用户并设置权限
|
||||||
|
check_and_create_user "$DB_USER" "$DB_PASSWORD"
|
||||||
|
|
||||||
|
# 再次检查连接
|
||||||
|
if ! psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "postgres" -c '\q' &> /dev/null; then
|
||||||
|
echo -e "${RED}Error: Could not connect to PostgreSQL server.${NC}"
|
||||||
|
echo "Please check your connection settings:"
|
||||||
|
echo "Host: $DB_HOST"
|
||||||
|
echo "Port: $DB_PORT"
|
||||||
|
echo "User: $DB_USER"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行SQL文件
|
||||||
|
execute_sql_file() {
|
||||||
|
local sql_file=$1
|
||||||
|
if [ ! -f "$sql_file" ]; then
|
||||||
|
echo -e "${RED}Error: SQL file not found: $sql_file${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${YELLOW}Executing SQL file: $sql_file${NC}"
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -f "$sql_file"
|
||||||
|
local status=$?
|
||||||
|
if [ $status -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}Successfully executed: $sql_file${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}Failed to execute: $sql_file${NC}"
|
||||||
|
return $status
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 初始化数据库
|
||||||
|
init() {
|
||||||
|
echo -e "${YELLOW}Initializing database...${NC}"
|
||||||
|
|
||||||
|
# 执行完整的初始化脚本
|
||||||
|
log "INFO" "Executing initialization script..."
|
||||||
|
# Run from inside the SQL_DIR so relative \i includes in initAll.sql (like createDB.sql)
|
||||||
|
# resolve relative to the SQL directory.
|
||||||
|
(
|
||||||
|
if [ ! -d "$SQL_DIR" ]; then
|
||||||
|
echo -e "${RED}Error: SQL directory not found: $SQL_DIR${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
cd "$SQL_DIR" || exit 1
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "postgres" -v ON_ERROR_STOP=1 -f "initAll.sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log "SUCCESS" "Database initialization completed successfully"
|
||||||
|
else
|
||||||
|
log "ERROR" "Database initialization failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo -e "${RED}Failed to create database.${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. 创建扩展和设置搜索路径
|
||||||
|
echo -e "${YELLOW}Creating extensions...${NC}"
|
||||||
|
check_extensions_availability() {
|
||||||
|
# 检查服务器上是否存在需创建的扩展
|
||||||
|
local missing=()
|
||||||
|
local exts=("uuid-ossp" "pg_trgm" "btree_gist")
|
||||||
|
for ext in "${exts[@]}"; do
|
||||||
|
# 查询 pg_available_extensions 来判断扩展是否已安装到服务器目录
|
||||||
|
if ! PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -tAc "SELECT 1 FROM pg_available_extensions WHERE name = '$ext';" | grep -q 1; then
|
||||||
|
missing+=("$ext")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#missing[@]} -ne 0 ]; then
|
||||||
|
echo -e "${RED}Error: The following server-side extensions are not available: ${missing[*]}${NC}"
|
||||||
|
echo "If you compiled PostgreSQL from source, you need to build and install the contrib modules into the server's installation prefix. Example steps:"
|
||||||
|
echo " # 在 PostgreSQL 源码目录下运行:"
|
||||||
|
echo " cd /path/to/postgresql-source/contrib"
|
||||||
|
echo " make"
|
||||||
|
echo " sudo make install"
|
||||||
|
echo "或者只安装缺失的模块(例如 uuid-ossp):"
|
||||||
|
echo " cd /path/to/postgresql-source/contrib/uuid-ossp"
|
||||||
|
echo " make"
|
||||||
|
echo " sudo make install"
|
||||||
|
echo "安装完成后,重启 PostgreSQL 服务并重新运行此脚本:"
|
||||||
|
echo " sudo systemctl restart postgresql"
|
||||||
|
echo "如果你使用的是容器或自定义路径,请确保将编译安装的扩展安装到 PostgreSQL 的 \$(pg_config --sharedir)/extension 目录下。"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查扩展可用性,若缺失则给出建议并退出
|
||||||
|
if ! check_extensions_availability; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "
|
||||||
|
CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";
|
||||||
|
CREATE EXTENSION IF NOT EXISTS \"pg_trgm\";
|
||||||
|
CREATE EXTENSION IF NOT EXISTS \"btree_gist\";"
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo -e "${RED}Failed to create extensions.${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. 逐个执行初始化SQL文件
|
||||||
|
echo -e "${YELLOW}Initializing tables...${NC}"
|
||||||
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||||
|
# 跳过注释和空行
|
||||||
|
[[ $line =~ ^--.*$ ]] && continue
|
||||||
|
[[ -z "${line// }" ]] && continue
|
||||||
|
|
||||||
|
# 从 \i 命令中提取文件名
|
||||||
|
if [[ $line =~ \\i[[:space:]]+([^[:space:]]+) ]]; then
|
||||||
|
sql_file="${SQL_DIR}/${BASH_REMATCH[1]}"
|
||||||
|
if [[ $sql_file != *"createDB.sql"* ]]; then # 跳过createDB.sql
|
||||||
|
echo -e "${YELLOW}Executing: $sql_file${NC}"
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -f "$sql_file"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo -e "${RED}Failed to execute: $sql_file${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < "${SQL_DIR}/initAll.sql"
|
||||||
|
|
||||||
|
# 4. 设置搜索路径
|
||||||
|
echo -e "${YELLOW}Setting search path...${NC}"
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "
|
||||||
|
ALTER DATABASE $DB_NAME SET search_path TO sys, public;"
|
||||||
|
|
||||||
|
echo -e "${GREEN}Database initialization completed successfully.${NC}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 重新初始化数据库
|
||||||
|
reinit() {
|
||||||
|
echo -e "${YELLOW}Reinitializing database...${NC}"
|
||||||
|
delete
|
||||||
|
init
|
||||||
|
}
|
||||||
|
|
||||||
|
# 删除数据库
|
||||||
|
delete() {
|
||||||
|
echo -e "${YELLOW}Deleting database...${NC}"
|
||||||
|
|
||||||
|
# 多次尝试终止连接(因为某些连接可能会立即重连)
|
||||||
|
for i in {1..3}; do
|
||||||
|
log "INFO" "Terminating database connections (attempt $i/3)..."
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "postgres" -c "
|
||||||
|
SELECT pg_terminate_backend(pg_stat_activity.pid)
|
||||||
|
FROM pg_stat_activity
|
||||||
|
WHERE pg_stat_activity.datname = '$DB_NAME'
|
||||||
|
AND pid <> pg_backend_pid();" > /dev/null 2>&1
|
||||||
|
|
||||||
|
# 等待连接完全关闭
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# 尝试删除数据库,最多重试3次
|
||||||
|
for i in {1..3}; do
|
||||||
|
log "INFO" "Attempting to drop database (attempt $i/3)..."
|
||||||
|
if PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "postgres" -c "DROP DATABASE IF EXISTS $DB_NAME;" 2>&1; then
|
||||||
|
log "SUCCESS" "Database deleted successfully"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log "WARN" "Failed to drop database, retrying after 2 seconds..."
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
log "ERROR" "Failed to delete database after 3 attempts"
|
||||||
|
log "ERROR" "Please ensure all connections to the database are closed, including:"
|
||||||
|
log "ERROR" " - Running application servers"
|
||||||
|
log "ERROR" " - IDE database connections"
|
||||||
|
log "ERROR" " - pgAdmin or other database tools"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示帮助信息
|
||||||
|
show_help() {
|
||||||
|
echo "Usage: $0 {init|reinit|delete}"
|
||||||
|
echo "Commands:"
|
||||||
|
echo " init Initialize the database"
|
||||||
|
echo " reinit Reinitialize the database (delete and create)"
|
||||||
|
echo " delete Delete the database"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
check_psql
|
||||||
|
check_db_connection
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
"init")
|
||||||
|
init
|
||||||
|
;;
|
||||||
|
"reinit")
|
||||||
|
reinit
|
||||||
|
;;
|
||||||
|
"delete")
|
||||||
|
delete
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Call main with all passed arguments so the script runs when invoked
|
||||||
|
main "$@"
|
||||||
28
docker/urbanLifeline/postgres/init/sql/createDB.sql
Normal file
28
docker/urbanLifeline/postgres/init/sql/createDB.sql
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
-- 删除已存在的数据库(如果存在)
|
||||||
|
DROP DATABASE IF EXISTS urban_lifeline;
|
||||||
|
|
||||||
|
-- 创建新数据库,使用 UTF8 编码,并设置适合中文的排序规则
|
||||||
|
-- 使用 template0 确保干净的数据库模板
|
||||||
|
-- zh_CN.UTF-8 支持中文字符排序和比较
|
||||||
|
CREATE DATABASE urban_lifeline
|
||||||
|
ENCODING 'UTF8'
|
||||||
|
TEMPLATE template0
|
||||||
|
LC_COLLATE 'zh_CN.UTF-8'
|
||||||
|
LC_CTYPE 'zh_CN.UTF-8';
|
||||||
|
|
||||||
|
-- 连接到新创建的数据库
|
||||||
|
\c urban_lifeline;
|
||||||
|
|
||||||
|
-- -- 创建扩展(如果需要)
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- UUID 支持
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- 文本搜索支持
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "btree_gist"; -- GiST 索引支持
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "vector"; -- 向量
|
||||||
|
|
||||||
|
-- 设置搜索路径(可选,但建议设置)
|
||||||
|
-- ALTER DATABASE urban-lifeline SET search_path TO sys, public;
|
||||||
|
|
||||||
|
-- sudo ./configure --prefix=/opt/postgres/postgres-17.6
|
||||||
|
-- --with-uuid=ossp --with-openssl --with-libxml --with-pam
|
||||||
|
-- && sudo make && sudo make install
|
||||||
188
docker/urbanLifeline/postgres/init/sql/createTableAI.sql
Normal file
188
docker/urbanLifeline/postgres/init/sql/createTableAI.sql
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
CREATE SCHEMA IF NOT EXISTS ai;
|
||||||
|
|
||||||
|
-- AI智能体配置
|
||||||
|
DROP TABLE IF EXISTS ai.tb_agent CASCADE;
|
||||||
|
CREATE TABLE ai.tb_agent(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||||
|
name VARCHAR(50) NOT NULL, -- 智能体名称
|
||||||
|
description VARCHAR(500) DEFAULT NULL, -- 智能体描述
|
||||||
|
link VARCHAR(500) DEFAULT NULL, -- 智能体url
|
||||||
|
api_key VARCHAR(500) NOT NULL, -- dify智能体APIKEY
|
||||||
|
is_outer BOOLEAN DEFAULT false, -- 是否是对外智能体,未登录可用
|
||||||
|
introduce VARCHAR(500) NOT NULL, -- 引导词
|
||||||
|
prompt_cards JSONB DEFAULT '[]'::jsonb, -- 提示卡片数组 [{file_id:'', prompt:''}]
|
||||||
|
category VARCHAR(50) NOT NULL, -- 分类
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (agent_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
UNIQUE (api_key)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- AI智能体对话
|
||||||
|
DROP TABLE IF EXISTS ai.tb_chat CASCADE;
|
||||||
|
CREATE TABLE ai.tb_chat(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
chat_id VARCHAR(50) NOT NULL, -- 对话ID
|
||||||
|
agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||||
|
user_type BOOLEAN NOT NULL DEFAULT true, -- 用户类型 true-系统内部人员 false-系统外部人员
|
||||||
|
title VARCHAR(500) NOT NULL, -- 对话标题
|
||||||
|
channel VARCHAR(50) DEFAULT 'agent', -- 对话渠道 agent、wechat
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (chat_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- AI智能体对话消息
|
||||||
|
DROP TABLE IF EXISTS ai.tb_chat_message CASCADE;
|
||||||
|
CREATE TABLE ai.tb_chat_message(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
message_id VARCHAR(50) NOT NULL, -- 消息ID
|
||||||
|
dify_message_id VARCHAR(100) DEFAULT NULL, -- Dify消息ID
|
||||||
|
chat_id VARCHAR(50) NOT NULL, -- 对话ID
|
||||||
|
role VARCHAR(50) NOT NULL, -- 角色:user-用户/ai-智能体/recipient-来客
|
||||||
|
content TEXT NOT NULL, -- 消息内容
|
||||||
|
files VARCHAR(50)[] DEFAULT NULL, -- 文件id数组
|
||||||
|
comment VARCHAR(50) DEFAULT NULL, -- 评价
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (message_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
-- 知识库配置 bidding和workcase2个服务使用
|
||||||
|
DROP TABLE IF EXISTS ai.tb_knowledge CASCADE;
|
||||||
|
CREATE TABLE ai.tb_knowledge(
|
||||||
|
-- 知识库dify相关配置
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
knowledge_id VARCHAR(50) NOT NULL, -- 知识库ID
|
||||||
|
title VARCHAR(255) NOT NULL, -- 知识库标题
|
||||||
|
avatar VARCHAR(255) DEFAULT NULL, -- 知识库头像
|
||||||
|
description VARCHAR(500) DEFAULT NULL, -- 知识库描述
|
||||||
|
dify_dataset_id VARCHAR(100) DEFAULT NULL, -- Dify知识库ID(Dataset ID)
|
||||||
|
dify_indexing_technique VARCHAR(50) DEFAULT 'high_quality', -- Dify索引方式(high_quality/economy)
|
||||||
|
embedding_model VARCHAR(100) DEFAULT NULL, -- 向量模型名称
|
||||||
|
embedding_model_provider VARCHAR(100) DEFAULT NULL, -- 向量模型提供商
|
||||||
|
rerank_model VARCHAR(100) DEFAULT NULL, -- Rerank模型名称
|
||||||
|
rerank_model_provider VARCHAR(100) DEFAULT NULL, -- Rerank模型提供商
|
||||||
|
reranking_enable BOOLEAN DEFAULT false, -- 是否启用Rerank
|
||||||
|
retrieval_top_k INTEGER DEFAULT 2, -- 检索Top K(返回前K个结果)
|
||||||
|
retrieval_score_threshold DECIMAL(3,2) DEFAULT 0.00, -- 检索分数阈值(0.00-1.00)
|
||||||
|
document_count INTEGER DEFAULT 0, -- 文档数量
|
||||||
|
total_chunks INTEGER DEFAULT 0, -- 总分段数
|
||||||
|
-- 下面是服务使用
|
||||||
|
service VARCHAR(50) DEFAULT NULL, -- 所属服务 workcase、bidding
|
||||||
|
project_id VARCHAR(50) DEFAULT NULL, -- bidding所属项目ID
|
||||||
|
category VARCHAR(50) DEFAULT NULL, -- 所属分类 workcase 内部知识库、外部知识库
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建者(用户ID)
|
||||||
|
dept_path VARCHAR(50) DEFAULT NULL, -- 创建者部门路径
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (optsn),
|
||||||
|
UNIQUE (knowledge_id),
|
||||||
|
UNIQUE (dify_dataset_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 知识库配置表字段注释
|
||||||
|
COMMENT ON TABLE ai.tb_knowledge IS '知识库配置表';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.knowledge_id IS '知识库ID';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.title IS '知识库标题';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.avatar IS '知识库头像';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.description IS '知识库描述';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.dify_dataset_id IS 'Dify知识库ID(Dataset ID)';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.dify_indexing_technique IS 'Dify索引方式(high_quality/economy)';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.embedding_model IS '向量模型名称';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.embedding_model_provider IS '向量模型提供商';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.rerank_model IS 'Rerank模型名称';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.rerank_model_provider IS 'Rerank模型提供商';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.reranking_enable IS '是否启用Rerank';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.retrieval_top_k IS '检索Top K(返回前K个结果)';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.retrieval_score_threshold IS '检索分数阈值(0.00-1.00)';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.document_count IS '文档数量';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.total_chunks IS '总分段数';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.service IS '所属服务 workcase、bidding';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.project_id IS 'bidding所属项目ID';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.category IS '所属分类 workcase 内部知识库、外部知识库';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.creator IS '创建者(用户ID)';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.dept_path IS '创建者部门路径';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge.deleted IS '是否删除';
|
||||||
|
-- bidding知识库根据project等变化
|
||||||
|
-- workcase知识库固定8个
|
||||||
|
-- workcase外部知识库:4个知识库:
|
||||||
|
-- 1. 设备操作指南
|
||||||
|
-- 2. 常见故障解决方案
|
||||||
|
-- 3. 三包外服务政策
|
||||||
|
-- 4. 配件咨询话术
|
||||||
|
-- workcase内部知识库:4个知识库:
|
||||||
|
-- 1. 技术维修手册
|
||||||
|
-- 2. 产品参数明细
|
||||||
|
-- 3. 内部服务流程规范
|
||||||
|
-- 4. 客户服务话术模板
|
||||||
|
|
||||||
|
-- 知识库文件 文件上传dify知识库,对dify内的文件修改不生成新版本, 只有重新上传才生成新版本
|
||||||
|
DROP TABLE IF EXISTS ai.tb_knowledge_file CASCADE;
|
||||||
|
CREATE TABLE ai.tb_knowledge_file(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
knowledge_id VARCHAR(50) NOT NULL, -- 知识库ID
|
||||||
|
file_root_id VARCHAR(50) NOT NULL, -- 文件根ID
|
||||||
|
file_id VARCHAR(50) NOT NULL, -- 文件ID
|
||||||
|
dify_file_id VARCHAR(50) NOT NULL, -- dify文件ID
|
||||||
|
version INTEGER NOT NULL DEFAULT 1, -- 文件版本
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (optsn),
|
||||||
|
UNIQUE (knowledge_id, file_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 知识库文件表字段注释
|
||||||
|
COMMENT ON TABLE ai.tb_knowledge_file IS '知识库文件表';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.knowledge_id IS '知识库ID';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.file_root_id IS '文件根ID';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.file_id IS '文件ID';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.dify_file_id IS 'dify文件ID';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.version IS '文件版本';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN ai.tb_knowledge_file.deleted IS '是否删除';
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS ai.tb_knowledge_file_log CASCADE;
|
||||||
|
CREATE TABLE ai.tb_knowledge_file_log(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
log_id VARCHAR(50) NOT NULL, -- 日志ID
|
||||||
|
knowledge_id VARCHAR(50) NOT NULL, -- 知识库ID
|
||||||
|
file_root_id VARCHAR(50) NOT NULL, -- 文件根ID
|
||||||
|
file_id VARCHAR(50) NOT NULL, -- 文件ID
|
||||||
|
file_name VARCHAR(100) NOT NULL, -- 文件名
|
||||||
|
service VARCHAR(50) NOT NULL, -- 所属服务 workcase、bidding
|
||||||
|
version INTEGER NOT NULL DEFAULT 1, -- 文件版本
|
||||||
|
action VARCHAR(50) NOT NULL, -- 操作类型 upload、update、delete
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建者(用户ID)
|
||||||
|
creator_name VARCHAR(100) NOT NULL, -- 创建者姓名
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
PRIMARY KEY (optsn),
|
||||||
|
UNIQUE (knowledge_id, file_id)
|
||||||
|
);
|
||||||
264
docker/urbanLifeline/postgres/init/sql/createTableBidding.sql
Normal file
264
docker/urbanLifeline/postgres/init/sql/createTableBidding.sql
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
-- =============================
|
||||||
|
-- 招投标智能体业务模块
|
||||||
|
-- 支持:招标文件管理、投标文件生成、评分分析、流程跟踪
|
||||||
|
-- =============================
|
||||||
|
CREATE SCHEMA IF NOT EXISTS bidding;
|
||||||
|
|
||||||
|
-- 招标项目表
|
||||||
|
DROP TABLE IF EXISTS bidding.tb_bidding_project CASCADE;
|
||||||
|
CREATE TABLE bidding.tb_bidding_project (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
project_id VARCHAR(50) NOT NULL, -- 项目ID
|
||||||
|
project_no VARCHAR(100) NOT NULL, -- 项目编号
|
||||||
|
project_name VARCHAR(500) NOT NULL, -- 项目名称
|
||||||
|
project_type VARCHAR(50) NOT NULL, -- 项目类型:public-公开招标/invitation-邀请招标/competitive_negotiation-竞争性谈判
|
||||||
|
industry VARCHAR(100), -- 所属行业
|
||||||
|
source_platform VARCHAR(100), -- 来源平台(如:政府采购网、企业官网等)
|
||||||
|
source_url VARCHAR(500), -- 来源URL
|
||||||
|
publish_date TIMESTAMPTZ, -- 发布日期
|
||||||
|
deadline TIMESTAMPTZ, -- 投标截止日期
|
||||||
|
opening_date TIMESTAMPTZ, -- 开标日期
|
||||||
|
budget_amount DECIMAL(18,2), -- 预算金额
|
||||||
|
currency VARCHAR(10) DEFAULT 'CNY', -- 货币单位
|
||||||
|
project_status VARCHAR(30) NOT NULL DEFAULT 'collecting', -- 项目状态:collecting-收集中/analyzing-分析中/preparing-准备投标/submitted-已提交/opened-已开标/won-中标/lost-未中标/abandoned-放弃
|
||||||
|
winning_status VARCHAR(30), -- 中标状态:pending-待定/won-中标/lost-未中标
|
||||||
|
winning_amount DECIMAL(18,2), -- 中标金额
|
||||||
|
client_name VARCHAR(255), -- 客户名称
|
||||||
|
client_contact VARCHAR(100), -- 客户联系方式
|
||||||
|
contact_person VARCHAR(100), -- 联系人
|
||||||
|
project_location VARCHAR(500), -- 项目地点
|
||||||
|
description TEXT, -- 项目描述
|
||||||
|
keywords TEXT[], -- 关键词数组
|
||||||
|
metadata JSONB DEFAULT NULL, -- 项目元数据
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
responsible_user VARCHAR(50), -- 负责人
|
||||||
|
team_members VARCHAR(50)[], -- 团队成员数组
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (project_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
UNIQUE (project_no)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_project_status ON bidding.tb_bidding_project(project_status) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_project_deadline ON bidding.tb_bidding_project(deadline) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_project_dept ON bidding.tb_bidding_project(dept_path) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_project_responsible ON bidding.tb_bidding_project(responsible_user) WHERE deleted = false;
|
||||||
|
|
||||||
|
COMMENT ON TABLE bidding.tb_bidding_project IS '招标项目表';
|
||||||
|
COMMENT ON COLUMN bidding.tb_bidding_project.project_status IS '项目状态:collecting/analyzing/preparing/submitted/opened/won/lost/abandoned';
|
||||||
|
|
||||||
|
-- 招标文件表
|
||||||
|
DROP TABLE IF EXISTS bidding.tb_bidding_document CASCADE;
|
||||||
|
CREATE TABLE bidding.tb_bidding_document (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
doc_id VARCHAR(50) NOT NULL, -- 文档ID
|
||||||
|
project_id VARCHAR(50) NOT NULL, -- 所属项目ID
|
||||||
|
doc_type VARCHAR(50) NOT NULL, -- 文档类型:tender-招标文件/technical-技术标/commercial-商务标/clarification-澄清文件/other-其他
|
||||||
|
doc_name VARCHAR(500) NOT NULL, -- 文档名称
|
||||||
|
file_id VARCHAR(50), -- 关联文件表ID
|
||||||
|
file_path VARCHAR(500), -- 文件路径
|
||||||
|
file_size BIGINT, -- 文件大小
|
||||||
|
mime_type VARCHAR(100), -- MIME类型
|
||||||
|
version INTEGER DEFAULT 1, -- 版本号
|
||||||
|
language VARCHAR(20) DEFAULT 'zh-CN', -- 语言
|
||||||
|
page_count INTEGER, -- 页数
|
||||||
|
parse_status VARCHAR(30) DEFAULT 'pending', -- 解析状态:pending-待解析/parsing-解析中/completed-已完成/failed-失败
|
||||||
|
parse_result JSONB, -- 解析结果(JSON格式:提取的要素、表格、图纸等)
|
||||||
|
extraction_data JSONB, -- 提取的结构化数据
|
||||||
|
ai_analysis TEXT, -- AI分析结果
|
||||||
|
upload_date TIMESTAMPTZ DEFAULT now(), -- 上传日期
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (doc_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
FOREIGN KEY (project_id) REFERENCES bidding.tb_bidding_project(project_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_doc_project ON bidding.tb_bidding_document(project_id) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_doc_type ON bidding.tb_bidding_document(doc_type) WHERE deleted = false;
|
||||||
|
|
||||||
|
COMMENT ON TABLE bidding.tb_bidding_document IS '招标文件表';
|
||||||
|
COMMENT ON COLUMN bidding.tb_bidding_document.parse_status IS '解析状态:pending/parsing/completed/failed';
|
||||||
|
|
||||||
|
-- 招标要素提取表
|
||||||
|
DROP TABLE IF EXISTS bidding.tb_bidding_requirement CASCADE;
|
||||||
|
CREATE TABLE bidding.tb_bidding_requirement (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
req_id VARCHAR(50) NOT NULL, -- 要素ID
|
||||||
|
project_id VARCHAR(50) NOT NULL, -- 所属项目ID
|
||||||
|
doc_id VARCHAR(50), -- 来源文档ID
|
||||||
|
req_category VARCHAR(50) NOT NULL, -- 要素类别:commercial-商务要素/technical-技术参数/veto-否决项/qualification-资质要求/delivery-交付要求/payment-付款条件/scoring-评分标准
|
||||||
|
req_name VARCHAR(255) NOT NULL, -- 要素名称
|
||||||
|
req_content TEXT NOT NULL, -- 要素内容
|
||||||
|
req_value VARCHAR(500), -- 要素值
|
||||||
|
is_mandatory BOOLEAN DEFAULT false, -- 是否必填
|
||||||
|
is_veto BOOLEAN DEFAULT false, -- 是否为否决项
|
||||||
|
priority INTEGER DEFAULT 0, -- 优先级
|
||||||
|
extraction_method VARCHAR(30) DEFAULT 'ai', -- 提取方式:ai-AI提取/manual-人工录入
|
||||||
|
confidence_score DECIMAL(5,4), -- 置信度分数(0-1)
|
||||||
|
source_location JSONB, -- 来源位置(页码、段落等)
|
||||||
|
compliance_status VARCHAR(30), -- 合规状态:compliant-符合/non_compliant-不符合/pending-待确认
|
||||||
|
response_content TEXT, -- 响应内容(我方的应答)
|
||||||
|
notes TEXT, -- 备注
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (req_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
FOREIGN KEY (project_id) REFERENCES bidding.tb_bidding_project(project_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_req_project ON bidding.tb_bidding_requirement(project_id) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_req_category ON bidding.tb_bidding_requirement(req_category) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_req_veto ON bidding.tb_bidding_requirement(is_veto) WHERE deleted = false AND is_veto = true;
|
||||||
|
|
||||||
|
COMMENT ON TABLE bidding.tb_bidding_requirement IS '招标要素提取表';
|
||||||
|
COMMENT ON COLUMN bidding.tb_bidding_requirement.req_category IS '要素类别:commercial/technical/veto/qualification/delivery/payment/scoring';
|
||||||
|
|
||||||
|
-- 投标文件生成表
|
||||||
|
DROP TABLE IF EXISTS bidding.tb_bid_response CASCADE;
|
||||||
|
CREATE TABLE bidding.tb_bid_response (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
response_id VARCHAR(50) NOT NULL, -- 响应文件ID
|
||||||
|
project_id VARCHAR(50) NOT NULL, -- 所属项目ID
|
||||||
|
response_type VARCHAR(50) NOT NULL, -- 响应类型:technical-技术标/commercial-商务标/comprehensive-综合标
|
||||||
|
doc_name VARCHAR(500) NOT NULL, -- 文档名称
|
||||||
|
outline TEXT, -- 文档大纲(JSON格式)
|
||||||
|
content TEXT, -- 文档内容
|
||||||
|
generation_method VARCHAR(30) DEFAULT 'ai', -- 生成方式:ai-AI生成/template-模板生成/manual-人工编写
|
||||||
|
template_id VARCHAR(50), -- 使用的模板ID
|
||||||
|
ai_model VARCHAR(100), -- 使用的AI模型
|
||||||
|
generation_status VARCHAR(30) DEFAULT 'draft', -- 生成状态:draft-草稿/reviewing-审核中/approved-已批准/rejected-已拒绝/submitted-已提交
|
||||||
|
file_id VARCHAR(50), -- 生成的文件ID
|
||||||
|
file_path VARCHAR(500), -- 文件路径
|
||||||
|
version INTEGER DEFAULT 1, -- 版本号
|
||||||
|
parent_version_id VARCHAR(50), -- 父版本ID
|
||||||
|
review_comments TEXT, -- 审核意见
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (response_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
FOREIGN KEY (project_id) REFERENCES bidding.tb_bidding_project(project_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_response_project ON bidding.tb_bid_response(project_id) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_response_status ON bidding.tb_bid_response(generation_status) WHERE deleted = false;
|
||||||
|
|
||||||
|
COMMENT ON TABLE bidding.tb_bid_response IS '投标文件生成表';
|
||||||
|
COMMENT ON COLUMN bidding.tb_bid_response.generation_status IS '生成状态:draft/reviewing/approved/rejected/submitted';
|
||||||
|
|
||||||
|
-- 评分规则表
|
||||||
|
DROP TABLE IF EXISTS bidding.tb_bidding_scoring_rule CASCADE;
|
||||||
|
CREATE TABLE bidding.tb_bidding_scoring_rule (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
rule_id VARCHAR(50) NOT NULL, -- 规则ID
|
||||||
|
project_id VARCHAR(50) NOT NULL, -- 所属项目ID
|
||||||
|
rule_category VARCHAR(50) NOT NULL, -- 规则类别:technical-技术分/commercial-商务分/price-价格分/credit-信誉分
|
||||||
|
rule_name VARCHAR(255) NOT NULL, -- 规则名称
|
||||||
|
rule_description TEXT, -- 规则描述
|
||||||
|
max_score DECIMAL(10,2) NOT NULL, -- 最高分值
|
||||||
|
weight DECIMAL(5,4), -- 权重(0-1)
|
||||||
|
scoring_method VARCHAR(50), -- 评分方法:fixed-固定分值/range-区间评分/formula-公式计算
|
||||||
|
calculation_formula TEXT, -- 计算公式
|
||||||
|
evaluation_criteria TEXT, -- 评分标准
|
||||||
|
our_score DECIMAL(10,2), -- 我方得分(预估)
|
||||||
|
score_analysis TEXT, -- 得分分析
|
||||||
|
optimization_advice TEXT, -- 优化建议
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (rule_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
FOREIGN KEY (project_id) REFERENCES bidding.tb_bidding_project(project_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_rule_project ON bidding.tb_bidding_scoring_rule(project_id) WHERE deleted = false;
|
||||||
|
|
||||||
|
COMMENT ON TABLE bidding.tb_bidding_scoring_rule IS '评分规则表';
|
||||||
|
|
||||||
|
-- 项目流程节点表
|
||||||
|
DROP TABLE IF EXISTS bidding.tb_bidding_process CASCADE;
|
||||||
|
CREATE TABLE bidding.tb_bidding_process (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
process_id VARCHAR(50) NOT NULL, -- 流程节点ID
|
||||||
|
project_id VARCHAR(50) NOT NULL, -- 所属项目ID
|
||||||
|
node_name VARCHAR(255) NOT NULL, -- 节点名称
|
||||||
|
node_type VARCHAR(50) NOT NULL, -- 节点类型:collection-文件收集/analysis-需求分析/preparation-文件准备/review-内部审核/submission-投标提交/opening-开标/result-结果通知
|
||||||
|
node_order INTEGER NOT NULL, -- 节点顺序
|
||||||
|
node_status VARCHAR(30) DEFAULT 'pending', -- 节点状态:pending-待处理/in_progress-进行中/completed-已完成/skipped-已跳过
|
||||||
|
planned_start_time TIMESTAMPTZ, -- 计划开始时间
|
||||||
|
planned_end_time TIMESTAMPTZ, -- 计划结束时间
|
||||||
|
actual_start_time TIMESTAMPTZ, -- 实际开始时间
|
||||||
|
actual_end_time TIMESTAMPTZ, -- 实际结束时间
|
||||||
|
responsible_user VARCHAR(50), -- 负责人
|
||||||
|
participants VARCHAR(50)[], -- 参与人员数组
|
||||||
|
notes TEXT, -- 节点备注
|
||||||
|
attachments VARCHAR(50)[], -- 附件ID数组
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (process_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
FOREIGN KEY (project_id) REFERENCES bidding.tb_bidding_project(project_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_process_project ON bidding.tb_bidding_process(project_id, node_order) WHERE deleted = false;
|
||||||
|
|
||||||
|
COMMENT ON TABLE bidding.tb_bidding_process IS '项目流程节点表';
|
||||||
|
COMMENT ON COLUMN bidding.tb_bidding_process.node_type IS '节点类型:collection/analysis/preparation/review/submission/opening/result';
|
||||||
|
|
||||||
|
-- 投标模板表
|
||||||
|
DROP TABLE IF EXISTS bidding.tb_bid_template CASCADE;
|
||||||
|
CREATE TABLE bidding.tb_bid_template (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
template_id VARCHAR(50) NOT NULL, -- 模板ID
|
||||||
|
template_name VARCHAR(255) NOT NULL, -- 模板名称
|
||||||
|
template_type VARCHAR(50) NOT NULL, -- 模板类型:technical-技术标/commercial-商务标/comprehensive-综合标
|
||||||
|
industry VARCHAR(100), -- 适用行业
|
||||||
|
template_content TEXT, -- 模板内容
|
||||||
|
outline_structure JSONB, -- 大纲结构(JSON格式)
|
||||||
|
file_id VARCHAR(50), -- 模板文件ID
|
||||||
|
usage_count INTEGER DEFAULT 0, -- 使用次数
|
||||||
|
is_default BOOLEAN DEFAULT false, -- 是否默认模板
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
status VARCHAR(20) DEFAULT 'active', -- 状态:active-激活/inactive-停用
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (template_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_template_type ON bidding.tb_bid_template(template_type) WHERE deleted = false;
|
||||||
|
|
||||||
|
COMMENT ON TABLE bidding.tb_bid_template IS '投标模板表';
|
||||||
51
docker/urbanLifeline/postgres/init/sql/createTableConfig.sql
Normal file
51
docker/urbanLifeline/postgres/init/sql/createTableConfig.sql
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
CREATE SCHEMA IF NOT EXISTS config;
|
||||||
|
DROP TABLE IF EXISTS config.tb_sys_config CASCADE;
|
||||||
|
CREATE TABLE config.tb_sys_config (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
config_id VARCHAR(50) NOT NULL, -- 配置ID
|
||||||
|
key VARCHAR(255) NOT NULL, -- 配置键
|
||||||
|
name VARCHAR(255) NOT NULL, -- 配置名称
|
||||||
|
value VARCHAR(255) NOT NULL, -- 配置值
|
||||||
|
config_type VARCHAR(50) NOT NULL, -- 数据类型(String, INTEGER, BOOLEAN, Float, Double)
|
||||||
|
render_type VARCHAR(50) NOT NULL, -- 配置渲染类型(select, input, textarea, checkbox, radio, switch)
|
||||||
|
description VARCHAR(255) NOT NULL, -- 配置描述
|
||||||
|
re JSON DEFAULT NULL, -- 正则表达式校验规则
|
||||||
|
options JSON DEFAULT NULL, -- 可选项,render_type为select、checkbox、radio时使用
|
||||||
|
"group" VARCHAR(255) NOT NULL, -- 配置组
|
||||||
|
module_id VARCHAR(255) NOT NULL, -- 模块id
|
||||||
|
order_num INT NOT NULL, -- 配置顺序
|
||||||
|
status INT NOT NULL DEFAULT 0, -- 配置状态 0:启用 1:禁用
|
||||||
|
remark VARCHAR(255) NOT NULL, -- 配置备注
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径,支持like递归(如/1/2/3/)
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 配置创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 配置更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 配置删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (config_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE config.tb_sys_config IS '系统配置表';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.config_id IS '配置ID';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.key IS '配置键';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.name IS '配置名称';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.value IS '配置值';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.config_type IS '数据类型';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.render_type IS '数据渲染类型';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.description IS '配置描述';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.re IS '正则表达式校验规则';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.options IS '可选项';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.group IS'配置组名称';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.module_id IS '模块id';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.order_num IS '配置顺序';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.status IS '配置状态';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.remark IS '配置备注';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.create_time IS '配置创建时间';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.update_time IS '配置更新时间';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.delete_time IS '配置删除时间';
|
||||||
|
COMMENT ON COLUMN config.tb_sys_config.deleted IS '是否删除';
|
||||||
153
docker/urbanLifeline/postgres/init/sql/createTableCrontab.sql
Normal file
153
docker/urbanLifeline/postgres/init/sql/createTableCrontab.sql
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
-- ====================================================
|
||||||
|
-- 定时任务表
|
||||||
|
-- ====================================================
|
||||||
|
CREATE SCHEMA IF NOT EXISTS crontab;
|
||||||
|
DROP TABLE IF EXISTS crontab.tb_crontab_task CASCADE;
|
||||||
|
CREATE TABLE crontab.tb_crontab_task (
|
||||||
|
id VARCHAR(64) NOT NULL,
|
||||||
|
task_id VARCHAR(64) NOT NULL,
|
||||||
|
task_name VARCHAR(100) NOT NULL,
|
||||||
|
task_group VARCHAR(50) NOT NULL DEFAULT 'DEFAULT',
|
||||||
|
meta_id VARCHAR(64) NOT NULL,
|
||||||
|
default_recipient SMALLINT NOT NULL DEFAULT 0, -- 是否使用默认接收人(0:否 1:是)
|
||||||
|
bean_name VARCHAR(100) NOT NULL,
|
||||||
|
method_name VARCHAR(100) NOT NULL,
|
||||||
|
method_params VARCHAR(500) DEFAULT NULL,
|
||||||
|
cron_expression VARCHAR(100) NOT NULL,
|
||||||
|
status SMALLINT NOT NULL DEFAULT 0, -- 任务状态(0:暂停 1:运行中)
|
||||||
|
description VARCHAR(500) DEFAULT NULL,
|
||||||
|
concurrent SMALLINT NOT NULL DEFAULT 0, -- 是否允许并发执行(0:否 1:是)
|
||||||
|
misfire_policy SMALLINT NOT NULL DEFAULT 1, -- 错过执行策略(1:立即执行 2:执行一次 3:放弃执行)
|
||||||
|
creator VARCHAR(64) DEFAULT NULL,
|
||||||
|
updater VARCHAR(64) DEFAULT NULL,
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
deleted SMALLINT NOT NULL DEFAULT 0, -- 是否删除(0:否 1:是)
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_task_name ON crontab.tb_crontab_task(task_name);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_bean_name ON crontab.tb_crontab_task(bean_name);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_status ON crontab.tb_crontab_task(status);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_deleted ON crontab.tb_crontab_task(deleted);
|
||||||
|
|
||||||
|
COMMENT ON TABLE crontab.tb_crontab_task IS '定时任务配置表';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.id IS '主键ID';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.task_id IS '任务ID';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.task_name IS '任务名称';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.task_group IS '任务分组';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.meta_id IS '任务元数据ID';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.default_recipient IS '是否使用默认接收人(0:否 1:是)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.bean_name IS 'Bean名称';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.method_name IS '方法名称';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.method_params IS '方法参数';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.cron_expression IS 'Cron表达式';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.status IS '任务状态(0:暂停 1:运行中)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.description IS '任务描述';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.concurrent IS '是否允许并发执行(0:否 1:是)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.misfire_policy IS '错过执行策略(1:立即执行 2:执行一次 3:放弃执行)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task.deleted IS '是否删除(0:否 1:是)';
|
||||||
|
|
||||||
|
-- ====================================================
|
||||||
|
-- 定时任务执行日志表
|
||||||
|
-- ====================================================
|
||||||
|
DROP TABLE IF EXISTS crontab.tb_crontab_log CASCADE;
|
||||||
|
CREATE TABLE crontab.tb_crontab_log (
|
||||||
|
id VARCHAR(64) NOT NULL,
|
||||||
|
task_id VARCHAR(64) NOT NULL,
|
||||||
|
task_name VARCHAR(100) NOT NULL,
|
||||||
|
task_group VARCHAR(50) NOT NULL DEFAULT 'DEFAULT',
|
||||||
|
bean_name VARCHAR(100) NOT NULL,
|
||||||
|
method_name VARCHAR(100) NOT NULL,
|
||||||
|
method_params VARCHAR(500) DEFAULT NULL,
|
||||||
|
execute_status SMALLINT NOT NULL, -- 执行状态(0:失败 1:成功)
|
||||||
|
execute_message TEXT DEFAULT NULL,
|
||||||
|
exception_info TEXT DEFAULT NULL,
|
||||||
|
start_time TIMESTAMPTZ NOT NULL,
|
||||||
|
end_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
execute_duration INT DEFAULT NULL,
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
deleted SMALLINT NOT NULL DEFAULT 0, -- 是否删除(0:否 1:是)
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_task_id ON crontab.tb_crontab_log(task_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_log_task_name ON crontab.tb_crontab_log(task_name);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_execute_status ON crontab.tb_crontab_log(execute_status);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_start_time ON crontab.tb_crontab_log(start_time);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_log_deleted ON crontab.tb_crontab_log(deleted);
|
||||||
|
|
||||||
|
COMMENT ON TABLE crontab.tb_crontab_log IS '定时任务执行日志表';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.id IS '主键ID';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.task_id IS '任务ID';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.task_name IS '任务名称';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.task_group IS '任务分组';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.bean_name IS 'Bean名称';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.method_name IS '方法名称';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.method_params IS '方法参数';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.execute_status IS '执行状态(0:失败 1:成功)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.execute_message IS '执行结果信息';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.exception_info IS '异常信息';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.start_time IS '开始时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.end_time IS '结束时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.execute_duration IS '执行时长(毫秒)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_log.deleted IS '是否删除(0:否 1:是)';
|
||||||
|
|
||||||
|
-- ====================================================
|
||||||
|
-- 定时任务元数据表(存储爬虫任务的元数据配置)
|
||||||
|
-- ====================================================
|
||||||
|
DROP TABLE IF EXISTS crontab.tb_crontab_task_meta CASCADE;
|
||||||
|
CREATE TABLE crontab.tb_crontab_task_meta (
|
||||||
|
id VARCHAR(64) NOT NULL,
|
||||||
|
meta_id VARCHAR(64) NOT NULL,
|
||||||
|
name VARCHAR(100) NOT NULL,
|
||||||
|
description VARCHAR(500) DEFAULT NULL,
|
||||||
|
category VARCHAR(50) NOT NULL,
|
||||||
|
bean_name VARCHAR(100) NOT NULL,
|
||||||
|
method_name VARCHAR(100) NOT NULL,
|
||||||
|
script_path VARCHAR(255) DEFAULT NULL,
|
||||||
|
param_schema TEXT DEFAULT NULL,
|
||||||
|
auto_publish SMALLINT NOT NULL DEFAULT 0, -- 是否自动发布
|
||||||
|
sort_order INT DEFAULT 0,
|
||||||
|
creator VARCHAR(64) DEFAULT NULL,
|
||||||
|
updater VARCHAR(64) DEFAULT NULL,
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
deleted SMALLINT NOT NULL DEFAULT 0, -- 是否删除(0:否 1:是)
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
UNIQUE (meta_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_category ON crontab.tb_crontab_task_meta(category);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_meta_deleted ON crontab.tb_crontab_task_meta(deleted);
|
||||||
|
|
||||||
|
COMMENT ON TABLE crontab.tb_crontab_task_meta IS '定时任务元数据表';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.id IS '主键ID';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.meta_id IS '元数据ID';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.name IS '任务名称';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.description IS '任务描述';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.category IS '任务分类(如:人民日报新闻爬取)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.bean_name IS 'Bean名称(执行器类名)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.method_name IS '执行方法名';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.script_path IS 'Python脚本路径(相对于basePath)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.param_schema IS '参数模板(JSON格式,定义参数名、类型、描述、默认值等)';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.auto_publish IS '是否自动发布';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.sort_order IS '排序号';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN crontab.tb_crontab_task_meta.deleted IS '是否删除(0:否 1:是)';
|
||||||
79
docker/urbanLifeline/postgres/init/sql/createTableFile.sql
Normal file
79
docker/urbanLifeline/postgres/init/sql/createTableFile.sql
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
CREATE SCHEMA IF NOT EXISTS file;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS file.tb_sys_file CASCADE;
|
||||||
|
CREATE TABLE file.tb_sys_file (
|
||||||
|
-- BaseDTO 继承字段
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 操作流水号
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建人
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新人
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门路径
|
||||||
|
remark TEXT DEFAULT NULL, -- 备注
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否已删除(false-未删除,true-已删除)
|
||||||
|
|
||||||
|
-- TbSysFileDTO 特有字段
|
||||||
|
file_id VARCHAR(50) NOT NULL, -- 文件ID (主键)
|
||||||
|
file_root_id VARCHAR(50) DEFAULT NULL, -- 文件根ID
|
||||||
|
version INTEGER DEFAULT 1, -- 文件版本
|
||||||
|
name VARCHAR(255) NOT NULL, -- 文件名
|
||||||
|
path VARCHAR(500) NOT NULL, -- 文件路径
|
||||||
|
size BIGINT NOT NULL, -- 文件大小(字节)
|
||||||
|
type VARCHAR(50) DEFAULT NULL, -- 文件类型
|
||||||
|
storage_type VARCHAR(50) DEFAULT NULL, -- 存储类型
|
||||||
|
mime_type VARCHAR(255) DEFAULT NULL, -- MIME 类型
|
||||||
|
url VARCHAR(500) DEFAULT NULL, -- 后端下载接口路径(保留用于扩展,建议使用 /api/file/download/{fileId})
|
||||||
|
status VARCHAR(50) DEFAULT NULL, -- 文件状态
|
||||||
|
module VARCHAR(100) DEFAULT NULL, -- 所属模块
|
||||||
|
business_id VARCHAR(50) DEFAULT NULL, -- 业务ID
|
||||||
|
uploader VARCHAR(50) DEFAULT NULL, -- 上传者用户ID
|
||||||
|
object_name VARCHAR(500) DEFAULT NULL, -- MinIO对象名称
|
||||||
|
bucket_name VARCHAR(100) DEFAULT NULL, -- MinIO存储桶名称
|
||||||
|
md5_hash VARCHAR(32) DEFAULT NULL, -- 文件MD5值
|
||||||
|
extension VARCHAR(20) DEFAULT NULL, -- 文件扩展名
|
||||||
|
|
||||||
|
PRIMARY KEY (file_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TABLE file.tb_sys_file IS '系统文件表';
|
||||||
|
|
||||||
|
-- BaseDTO 继承字段注释
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.optsn IS '操作流水号';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.creator IS '创建人';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.updater IS '更新人';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.dept_path IS '部门路径';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.remark IS '备注';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.deleted IS '是否已删除(false-未删除,true-已删除)';
|
||||||
|
|
||||||
|
-- TbSysFileDTO 特有字段注释
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.file_id IS '文件ID (主键)';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.file_root_id IS '文件根ID';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.version IS '文件版本';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.name IS '文件名';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.path IS '文件路径';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.size IS '文件大小(字节)';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.type IS '文件类型';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.storage_type IS '存储类型';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.mime_type IS 'MIME 类型';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.url IS '后端下载接口路径(保留用于扩展,建议使用 /api/file/download/{fileId})';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.status IS '文件状态';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.module IS '所属模块';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.business_id IS '业务ID';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.uploader IS '上传者用户ID';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.object_name IS 'MinIO对象名称';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.bucket_name IS 'MinIO存储桶名称';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.md5_hash IS '文件MD5值';
|
||||||
|
COMMENT ON COLUMN file.tb_sys_file.extension IS '文件扩展名';
|
||||||
|
|
||||||
|
-- 文件表索引
|
||||||
|
-- CREATE INDEX idx_file_module_business ON file.tb_sys_file(module, business_id) WHERE deleted = false;
|
||||||
|
-- CREATE INDEX idx_file_uploader ON file.tb_sys_file(uploader) WHERE deleted = false;
|
||||||
|
-- CREATE INDEX idx_file_bucket ON file.tb_sys_file(bucket_name) WHERE deleted = false;
|
||||||
|
-- CREATE INDEX idx_file_status ON file.tb_sys_file(status) WHERE deleted = false;
|
||||||
|
-- CREATE INDEX idx_file_create_time ON file.tb_sys_file(create_time) WHERE deleted = false;
|
||||||
|
-- CREATE INDEX idx_file_md5 ON file.tb_sys_file(md5_hash) WHERE deleted = false;
|
||||||
42
docker/urbanLifeline/postgres/init/sql/createTableLog.sql
Normal file
42
docker/urbanLifeline/postgres/init/sql/createTableLog.sql
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
DROP TABLE IF EXISTS sys.tb_sys_log CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_log (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
log_id VARCHAR(50) NOT NULL, -- 日志ID
|
||||||
|
type VARCHAR(50) NOT NULL, -- 日志类型
|
||||||
|
level VARCHAR(50) NOT NULL, -- 日志级别
|
||||||
|
module VARCHAR(50) NOT NULL, -- 日志模块
|
||||||
|
ip_address VARCHAR(45), -- IP地址
|
||||||
|
ip_source VARCHAR(100), -- IP来源
|
||||||
|
browser VARCHAR(100), -- 浏览器
|
||||||
|
os VARCHAR(100), -- 操作系统
|
||||||
|
message VARCHAR(255) NOT NULL, -- 日志消息
|
||||||
|
data JSONB DEFAULT NULL, -- 日志数据
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
creator_name VARCHAR(200) DEFAULT NULL, -- 创建者姓名
|
||||||
|
service VARCHAR(50) NOT NULL, -- 服务类型
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 日志创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 日志更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 日志删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (log_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_log IS '系统日志表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.log_id IS '日志ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.type IS '日志类型';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.level IS '日志级别';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.module IS '日志模块';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.message IS '日志消息';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.data IS '日志数据';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.creator_name IS '创建者姓名';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.service IS '服务类型';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.create_time IS '日志创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.update_time IS '日志更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.delete_time IS '日志删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_log.deleted IS '是否删除';
|
||||||
200
docker/urbanLifeline/postgres/init/sql/createTableMessage.sql
Normal file
200
docker/urbanLifeline/postgres/init/sql/createTableMessage.sql
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
CREATE SCHEMA IF NOT EXISTS message;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS message.tb_message CASCADE;
|
||||||
|
CREATE TABLE message.tb_message (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
message_id VARCHAR(50) NOT NULL, -- 消息ID
|
||||||
|
title VARCHAR(255) NOT NULL, -- 消息标题
|
||||||
|
content VARCHAR(255) NOT NULL, -- 消息内容
|
||||||
|
type VARCHAR(50) NOT NULL, -- 消息类型
|
||||||
|
status VARCHAR(50) NOT NULL, -- 消息状态
|
||||||
|
service VARCHAR(50) NOT NULL, -- 服务类型
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径(隔离)
|
||||||
|
creator VARCHAR(50) NOT NULL DEFAULT 'system',-- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
PRIMARY KEY (message_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TABLE message.tb_message IS '消息表';
|
||||||
|
COMMENT ON COLUMN message.tb_message.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN message.tb_message.message_id IS '消息ID';
|
||||||
|
COMMENT ON COLUMN message.tb_message.title IS '消息标题';
|
||||||
|
COMMENT ON COLUMN message.tb_message.content IS '消息内容';
|
||||||
|
COMMENT ON COLUMN message.tb_message.type IS '消息类型';
|
||||||
|
COMMENT ON COLUMN message.tb_message.status IS '消息状态';
|
||||||
|
COMMENT ON COLUMN message.tb_message.service IS '服务类型';
|
||||||
|
COMMENT ON COLUMN message.tb_message.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN message.tb_message.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN message.tb_message.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN message.tb_message.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message.deleted IS '是否删除';
|
||||||
|
|
||||||
|
|
||||||
|
-- 消息发送范围定义表(定义消息要发送给哪些对象,通过什么渠道)
|
||||||
|
DROP TABLE IF EXISTS message.tb_message_range CASCADE;
|
||||||
|
CREATE TABLE message.tb_message_range (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
message_id VARCHAR(50) NOT NULL, -- 消息ID
|
||||||
|
target_type VARCHAR(20) NOT NULL, -- 目标类型:user/dept/role/all
|
||||||
|
target_id VARCHAR(50) DEFAULT NULL, -- 目标ID(用户、部门、角色ID等,all类型时为空)
|
||||||
|
channel VARCHAR(20) NOT NULL DEFAULT 'app', -- 发送渠道:app/sms/email/wechat_official_account/wechat_applet等
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径,支持like递归(如/1/2/3/)
|
||||||
|
creator VARCHAR(50) NOT NULL DEFAULT 'system',-- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (optsn),
|
||||||
|
UNIQUE (message_id, target_type, target_id, channel)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TABLE message.tb_message_range IS '消息发送范围定义表';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.message_id IS '消息ID';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.target_type IS '目标类型:user-指定用户/dept-部门/role-角色/all-全员';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.target_id IS '目标ID(用户、部门、角色ID等,all类型时为空)';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.channel IS '发送渠道:app/sms/email/wechat_official_account/wechat_applet等';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_range.deleted IS '是否删除';
|
||||||
|
|
||||||
|
|
||||||
|
-- 用户消息接收记录表(记录每个用户实际收到的消息及处理状态)
|
||||||
|
DROP TABLE IF EXISTS message.tb_message_receiver CASCADE;
|
||||||
|
CREATE TABLE message.tb_message_receiver (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
message_id VARCHAR(50) NOT NULL, -- 消息ID
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||||
|
channel VARCHAR(20) DEFAULT 'app', -- 接收渠道:app/sms/email/wechat等
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'unread', -- 消息状态:unread-未读/read-已读/handled-已处理/deleted-已删除
|
||||||
|
read_time TIMESTAMPTZ DEFAULT NULL, -- 阅读时间
|
||||||
|
handle_time TIMESTAMPTZ DEFAULT NULL, -- 处理时间
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径(数据隔离)
|
||||||
|
creator VARCHAR(50) NOT NULL DEFAULT 'system',-- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间(接收时间)
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (optsn),
|
||||||
|
UNIQUE (message_id, user_id, channel)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 创建索引以提高查询效率
|
||||||
|
CREATE INDEX idx_message_user_user_status ON message.tb_message_receiver(user_id, status, create_time DESC) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_message_user_message ON message.tb_message_receiver(message_id) WHERE deleted = false;
|
||||||
|
|
||||||
|
COMMENT ON TABLE message.tb_message_receiver IS '用户消息接收记录表';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.message_id IS '消息ID';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.user_id IS '用户ID';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.channel IS '接收渠道:app/sms/email/wechat等';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.status IS '消息状态:unread-未读/read-已读/handled-已处理/deleted-已删除';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.read_time IS '阅读时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.handle_time IS '处理时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.create_time IS '创建时间(接收时间)';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_receiver.deleted IS '是否删除';
|
||||||
|
|
||||||
|
|
||||||
|
-- 消息渠道配置表(管理各种消息发送渠道的配置)
|
||||||
|
DROP TABLE IF EXISTS message.tb_message_channel CASCADE;
|
||||||
|
CREATE TABLE message.tb_message_channel (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
channel_id VARCHAR(50) NOT NULL, -- 渠道ID
|
||||||
|
channel_code VARCHAR(50) NOT NULL, -- 渠道编码:app/sms/email/wechat/dingtalk等
|
||||||
|
channel_name VARCHAR(100) NOT NULL, -- 渠道名称
|
||||||
|
channel_desc VARCHAR(255) DEFAULT NULL, -- 渠道描述
|
||||||
|
config JSON DEFAULT NULL, -- 渠道配置(如API密钥、服务器地址等)
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'enabled', -- 渠道状态:enabled-启用/disabled-禁用/maintenance-维护中
|
||||||
|
priority INTEGER DEFAULT 0, -- 优先级(数字越大优先级越高)
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径(数据隔离)
|
||||||
|
creator VARCHAR(50) NOT NULL DEFAULT 'system',-- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (channel_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
UNIQUE (channel_code)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TABLE message.tb_message_channel IS '消息渠道配置表';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.channel_id IS '渠道ID';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.channel_code IS '渠道编码:app/sms/email/wechat/dingtalk等';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.channel_name IS '渠道名称';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.channel_desc IS '渠道描述';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.config IS '渠道配置(JSON格式)';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.status IS '渠道状态:enabled-启用/disabled-禁用/maintenance-维护中';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.priority IS '优先级(数字越大优先级越高)';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_channel.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 消息模板表
|
||||||
|
-- =============================
|
||||||
|
DROP TABLE IF EXISTS message.tb_message_template CASCADE;
|
||||||
|
CREATE TABLE message.tb_message_template (
|
||||||
|
optsn VARCHAR(50) NOT NULL,
|
||||||
|
template_id VARCHAR(50) NOT NULL,
|
||||||
|
template_code VARCHAR(100) NOT NULL, -- 模板编码
|
||||||
|
template_name VARCHAR(255) NOT NULL, -- 模板名称
|
||||||
|
template_type VARCHAR(30) NOT NULL, -- 模板类型:system-系统/business-业务
|
||||||
|
title_template TEXT, -- 标题模板(支持变量)
|
||||||
|
content_template TEXT NOT NULL, -- 内容模板(支持变量)
|
||||||
|
variables JSONB, -- 模板变量定义
|
||||||
|
service VARCHAR(50) NOT NULL, -- 服务类型
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (template_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
UNIQUE (template_code)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TABLE message.tb_message_template IS '消息模板表';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.template_id IS '模板ID';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.template_code IS '模板编码';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.template_name IS '模板名称';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.template_type IS '模板类型:system-系统/business-业务';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.title_template IS '标题模板(支持变量)';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.content_template IS '内容模板(支持变量)';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.variables IS '模板变量定义';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.service IS '服务类型';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN message.tb_message_template.deleted IS '是否删除';
|
||||||
|
|
||||||
|
CREATE INDEX idx_template_type ON message.tb_message_template(template_type) WHERE deleted = false;
|
||||||
473
docker/urbanLifeline/postgres/init/sql/createTablePermission.sql
Normal file
473
docker/urbanLifeline/postgres/init/sql/createTablePermission.sql
Normal file
@@ -0,0 +1,473 @@
|
|||||||
|
CREATE SCHEMA IF NOT EXISTS sys;
|
||||||
|
|
||||||
|
-- 通用更新时间触发函数(用于模拟 MySQL 的 ON UPDATE CURRENT_TIMESTAMP)
|
||||||
|
-- CREATE OR REPLACE FUNCTION sys.set_update_time()
|
||||||
|
-- RETURNS trigger AS $$
|
||||||
|
-- BEGIN
|
||||||
|
-- NEW.update_time := CURRENT_TIMESTAMP;
|
||||||
|
-- RETURN NEW;
|
||||||
|
-- END;
|
||||||
|
-- $$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
-- 部门表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_dept CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_dept (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
dept_id VARCHAR(50) NOT NULL, -- 部门ID
|
||||||
|
name VARCHAR(100) NOT NULL, -- 部门名称
|
||||||
|
parent_id VARCHAR(50) DEFAULT NULL, -- 父部门ID
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
description VARCHAR(255) DEFAULT NULL, -- 部门描述
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (dept_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
-- 创建索引
|
||||||
|
CREATE INDEX idx_sys_dept_parent ON sys.tb_sys_dept USING btree (parent_id);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_dept IS '部门表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.dept_id IS '部门ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.name IS '部门名称';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.parent_id IS '父部门ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.description IS '部门描述';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- 角色表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_role CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_role (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
role_id VARCHAR(50) NOT NULL, -- 角色ID
|
||||||
|
name VARCHAR(100) NOT NULL,
|
||||||
|
description VARCHAR(200) DEFAULT NULL, -- 角色名称
|
||||||
|
scope VARCHAR(20) NOT NULL DEFAULT 'dept', -- 角色作用域:global/dept
|
||||||
|
owner_dept_id VARCHAR(50) DEFAULT NULL, -- 当scope=dept时,所属部门ID
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL,
|
||||||
|
status BOOLEAN NOT NULL DEFAULT false, -- 部门全路径
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (role_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_role IS '角色表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.role_id IS '角色ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.name IS '角色名称';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.description IS '角色名称';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.scope IS '角色作用域:global=通用,dept=部门私有';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.owner_dept_id IS '部门私有角色的所属部门ID(scope=dept 时必填)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.status IS '角色状态';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- 唯一性:
|
||||||
|
-- 全局角色:name 在未删除且 scope=global 下唯一
|
||||||
|
-- 部门私有角色:同一部门下 name 唯一(scope=dept)
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_sys_role_global_name
|
||||||
|
ON sys.tb_sys_role USING btree (name)
|
||||||
|
WHERE deleted = false AND scope = 'global';
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_sys_role_dept_name
|
||||||
|
ON sys.tb_sys_role USING btree (owner_dept_id, name)
|
||||||
|
WHERE deleted = false AND scope = 'dept';
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sys_role_owner_dept ON sys.tb_sys_role USING btree (owner_dept_id) WHERE deleted = false;
|
||||||
|
|
||||||
|
-- 部门角色关联表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_dept_role CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_dept_role (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
dept_id VARCHAR(50) NOT NULL, -- 部门ID
|
||||||
|
role_id VARCHAR(50) NOT NULL, -- 角色ID
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (dept_id, role_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_dept_role IS '部门角色关联表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.dept_id IS '部门ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.role_id IS '角色ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_dept_role.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- 用户角色关联表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_user_role CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_user_role (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||||
|
role_id VARCHAR(50) NOT NULL, -- 角色ID
|
||||||
|
dept_id VARCHAR(50) NOT NULL, -- 部门ID
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (user_id, role_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_user_role IS '用户角色关联表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.user_id IS '用户ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.role_id IS '角色ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.dept_id IS '部门ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_role.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- 视图表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_view CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_view (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
view_id VARCHAR(50) NOT NULL, -- 视图ID
|
||||||
|
name VARCHAR(100) NOT NULL, -- 视图名称
|
||||||
|
parent_id VARCHAR(50) DEFAULT NULL, -- 父视图ID
|
||||||
|
url VARCHAR(255) DEFAULT NULL, -- 视图URL
|
||||||
|
component VARCHAR(255) DEFAULT NULL, -- 视图组件
|
||||||
|
icon VARCHAR(100) DEFAULT NULL, -- 视图图标
|
||||||
|
type INTEGER DEFAULT 0, -- 视图类型:0=导航栏 1=侧边栏 2=按钮,3空白页
|
||||||
|
view_type VARCHAR(20) DEFAULT 'route', -- 页面类型:route=路由页面 iframe=嵌入页面
|
||||||
|
iframe_url VARCHAR(500) DEFAULT NULL, -- iframe URL(仅当view_type=iframe时有效)
|
||||||
|
service VARCHAR(20) DEFAULT 'platform', -- 所属服务:platform=平台应用 bidding=招标应用 workcase=客服应用
|
||||||
|
layout VARCHAR(100) DEFAULT NULL, -- 布局组件路径名称
|
||||||
|
order_num INTEGER DEFAULT 0, -- 视图排序号
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
description VARCHAR(255) DEFAULT NULL, -- 视图描述
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (view_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
-- 创建索引
|
||||||
|
CREATE INDEX idx_sys_view_parent ON sys.tb_sys_view USING btree (parent_id) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_sys_view_service ON sys.tb_sys_view USING btree (service) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_sys_view_type ON sys.tb_sys_view USING btree (view_type) WHERE deleted = false;
|
||||||
|
COMMENT ON TABLE sys.tb_sys_view IS '视图表(菜单表)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.view_id IS '视图ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.name IS '视图名称';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.parent_id IS '父视图ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.url IS '视图URL';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.component IS '视图组件';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.icon IS '视图图标';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.type IS '视图类型:0=目录 1=菜单页面 2=按钮';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.view_type IS '页面类型:route=路由页面 iframe=嵌入页面';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.iframe_url IS 'iframe URL(仅当view_type=iframe时有效)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.service IS '所属服务:platform=平台应用 bidding=招标应用 workcase=客服应用';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.layout IS '布局组件路径名称';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.order_num IS '视图排序号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.description IS '视图描述';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view.deleted IS '是否删除';
|
||||||
|
|
||||||
|
|
||||||
|
-- 模块表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_module CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_module (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
module_id VARCHAR(50) NOT NULL, -- 模块ID
|
||||||
|
name VARCHAR(100) NOT NULL, -- 模块名称
|
||||||
|
description VARCHAR(255) DEFAULT NULL, -- 模块描述
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (module_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_module IS '模块表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.module_id IS '模块ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.name IS '模块名称';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.description IS '模块描述';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_module.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- 权限表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_permission CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_permission (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
permission_id VARCHAR(50) NOT NULL, -- 权限ID
|
||||||
|
name VARCHAR(100) NOT NULL, -- 权限名称
|
||||||
|
code VARCHAR(100) NOT NULL, -- 权限代码
|
||||||
|
description VARCHAR(255) DEFAULT NULL, -- 权限描述
|
||||||
|
module_id VARCHAR(50) DEFAULT NULL, -- 所属模块ID
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL,
|
||||||
|
status BOOLEAN NOT NULL DEFAULT false, -- 部门全路径
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (permission_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_permission IS '权限表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.permission_id IS '权限ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.name IS '权限名称';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.code IS '权限代码';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.description IS '权限描述' ;
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.module_id IS '所属模块ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.status IS '角色状态';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_permission.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- 角色权限
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_role_permission CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_role_permission (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
role_id VARCHAR(50) NOT NULL, -- 角色ID
|
||||||
|
permission_id VARCHAR(50) NOT NULL, -- 权限ID
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (role_id, permission_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_role_permission IS '角色权限表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.role_id IS '角色ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.permission_id IS '权限ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_role_permission.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- 视图权限
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_view_permission CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_view_permission (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
view_id VARCHAR(50) NOT NULL, -- 视图ID
|
||||||
|
permission_id VARCHAR(50) NOT NULL, -- 权限ID
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (view_id, permission_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_view_permission IS '视图权限表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.view_id IS '视图ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.permission_id IS '权限ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.creator IS '创建者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.dept_path IS '部门全路径';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.updater IS '更新者';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_view_permission.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- 为所有表创建更新时间触发器
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_tb_sys_dept_update_time ON sys.tb_sys_dept;
|
||||||
|
-- CREATE TRIGGER trg_tb_sys_dept_update_time
|
||||||
|
-- BEFORE UPDATE ON sys.tb_sys_dept
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION sys.set_update_time();
|
||||||
|
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_tb_sys_role_update_time ON sys.tb_sys_role;
|
||||||
|
-- CREATE TRIGGER trg_tb_sys_role_update_time
|
||||||
|
-- BEFORE UPDATE ON sys.tb_sys_role
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION sys.set_update_time();
|
||||||
|
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_tb_sys_dept_role_update_time ON sys.tb_sys_dept_role;
|
||||||
|
-- CREATE TRIGGER trg_tb_sys_dept_role_update_time
|
||||||
|
-- BEFORE UPDATE ON sys.tb_sys_dept_role
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION sys.set_update_time();
|
||||||
|
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_tb_sys_user_role_update_time ON sys.tb_sys_user_role;
|
||||||
|
-- CREATE TRIGGER trg_tb_sys_user_role_update_time
|
||||||
|
-- BEFORE UPDATE ON sys.tb_sys_user_role
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION sys.set_update_time();
|
||||||
|
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_tb_sys_view_update_time ON sys.tb_sys_view;
|
||||||
|
-- CREATE TRIGGER trg_tb_sys_view_update_time
|
||||||
|
-- BEFORE UPDATE ON sys.tb_sys_view
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION sys.set_update_time();
|
||||||
|
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_tb_sys_module_update_time ON sys.tb_sys_module;
|
||||||
|
-- CREATE TRIGGER trg_tb_sys_module_update_time
|
||||||
|
-- BEFORE UPDATE ON sys.tb_sys_module
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION sys.set_update_time();
|
||||||
|
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_tb_sys_permission_update_time ON sys.tb_sys_permission;
|
||||||
|
-- CREATE TRIGGER trg_tb_sys_permission_update_time
|
||||||
|
-- BEFORE UPDATE ON sys.tb_sys_permission
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION sys.set_update_time();
|
||||||
|
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_tb_sys_role_permission_update_time ON sys.tb_sys_role_permission;
|
||||||
|
-- CREATE TRIGGER trg_tb_sys_role_permission_update_time
|
||||||
|
-- BEFORE UPDATE ON sys.tb_sys_role_permission
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION sys.set_update_time();
|
||||||
|
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_tb_sys_view_permission_update_time ON sys.tb_sys_view_permission;
|
||||||
|
-- CREATE TRIGGER trg_tb_sys_view_permission_update_time
|
||||||
|
-- BEFORE UPDATE ON sys.tb_sys_view_permission
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION sys.set_update_time();
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 通用对象级权限(ACL)
|
||||||
|
-- 支持对象类型:任意(如 article/file/course/...)
|
||||||
|
-- 支持主体:user/dept/role
|
||||||
|
-- 权限位:1=读(read),2=写(write),4=执行(exec),可相加
|
||||||
|
-- include_descendants:当主体为 dept/role 时,是否包含其子级(便于“所有子级可查看”场景)
|
||||||
|
-- allow:true=允许;false=显式拒绝(拒绝优先生效)
|
||||||
|
-- dept_path:用于数据范围隔离(与现有规则一致)
|
||||||
|
-- =============================
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_acl CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_acl (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
acl_id VARCHAR(50) NOT NULL, -- ACL主键
|
||||||
|
object_type VARCHAR(50) NOT NULL, -- 对象类型:article/file/course/...
|
||||||
|
object_id VARCHAR(50) NOT NULL, -- 对象ID
|
||||||
|
principal_type VARCHAR(20) NOT NULL, -- 主体类型:user/dept/role
|
||||||
|
principal_id VARCHAR(50) NOT NULL, -- 主体ID
|
||||||
|
principal_dept_id VARCHAR(50) DEFAULT NULL, -- 当主体为role且限定到某部门时的部门ID(支持“某部门的某角色”)
|
||||||
|
permission SMALLINT NOT NULL, -- 权限位:1读 2写 4执行
|
||||||
|
allow BOOLEAN NOT NULL DEFAULT true, -- 允许或显式拒绝
|
||||||
|
include_descendants BOOLEAN NOT NULL DEFAULT false, -- 是否包含子级(对dept/role生效)
|
||||||
|
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径(数据隔离)
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (acl_id),
|
||||||
|
UNIQUE (object_type, object_id, principal_type, principal_id, principal_dept_id, deleted),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TABLE sys.tb_sys_acl IS '通用对象级权限表(ACL)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl.object_type IS '对象类型:article/file/course/...';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl.object_id IS '对象ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl.principal_type IS '主体类型:user/dept/role';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl.principal_id IS '主体ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl.principal_dept_id IS '当主体为角色时,可选的限定部门ID(某部门的某角色)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl.permission IS '权限位:1读 2写 4执行,可相加';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl.allow IS '是否允许(false=显式拒绝)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl.include_descendants IS '是否包含子级(dept/role时启用)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl.dept_path IS '部门全路径(用于数据范围隔离)';
|
||||||
|
|
||||||
|
CREATE INDEX idx_sys_acl_object ON sys.tb_sys_acl USING btree (object_type, object_id) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_sys_acl_principal ON sys.tb_sys_acl USING btree (principal_type, principal_id) WHERE deleted = false;
|
||||||
|
CREATE INDEX idx_sys_acl_dept_path ON sys.tb_sys_acl USING btree (dept_path) WHERE deleted = false;
|
||||||
|
-- 针对“某部门的某角色”的检索优化
|
||||||
|
CREATE INDEX idx_sys_acl_role_scoped ON sys.tb_sys_acl USING btree (principal_id, principal_dept_id)
|
||||||
|
WHERE deleted = false AND principal_type = 'role';
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- ACL 策略表:定义对象类型的层级可见/可编辑规则
|
||||||
|
-- 例如:
|
||||||
|
-- - 同级与父级管理员可修改(edit_hierarchy_rule = 'parent_or_same_admin')
|
||||||
|
-- - 子级全部可查看(view_hierarchy_rule = 'children_all')
|
||||||
|
-- - 课程:下级只有指定部门/角色可查看(view_hierarchy_rule = 'children_specified')
|
||||||
|
-- 说明:业务侧需结合“管理员”的判定(通常由角色判定)在应用层实现;本表做规则声明
|
||||||
|
-- =============================
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_acl_policy CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_acl_policy (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
policy_id VARCHAR(50) NOT NULL, -- 策略ID
|
||||||
|
name VARCHAR(255) NOT NULL, -- 策略名称
|
||||||
|
object_type VARCHAR(50) NOT NULL, -- 目标对象类型
|
||||||
|
edit_hierarchy_rule VARCHAR(50) DEFAULT NULL, -- 编辑层级规则:parent_only/parent_or_same_admin/owner_only/none
|
||||||
|
view_hierarchy_rule VARCHAR(50) DEFAULT NULL, -- 查看层级规则:children_all/children_specified/none
|
||||||
|
default_permission SMALLINT DEFAULT 0, -- 默认权限位(无显式ACL时应用)
|
||||||
|
default_allow BOOLEAN DEFAULT true, -- 默认是否允许
|
||||||
|
apply_to_children BOOLEAN DEFAULT true, -- 是否默认应用到子级
|
||||||
|
creator VARCHAR(50) DEFAULT NULL,
|
||||||
|
updater VARCHAR(50) DEFAULT NULL,
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL,
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
PRIMARY KEY (policy_id),
|
||||||
|
UNIQUE (object_type, deleted),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TABLE sys.tb_sys_acl_policy IS 'ACL对象类型策略表(层级可见/可编辑规则)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl_policy.object_type IS '对象类型:article/file/course/...';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl_policy.edit_hierarchy_rule IS '编辑层级规则:parent_only/parent_or_same_admin/owner_only/none';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl_policy.view_hierarchy_rule IS '查看层级规则:children_all/children_specified/none';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl_policy.default_permission IS '默认权限位(无显式ACL时兜底)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_acl_policy.apply_to_children IS '默认是否应用到子级';
|
||||||
|
|
||||||
|
CREATE INDEX idx_sys_acl_policy_object ON sys.tb_sys_acl_policy USING btree (object_type) WHERE deleted = false;
|
||||||
124
docker/urbanLifeline/postgres/init/sql/createTableUser.sql
Normal file
124
docker/urbanLifeline/postgres/init/sql/createTableUser.sql
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
|
||||||
|
-- 创建 sys schema(如果不存在)
|
||||||
|
CREATE SCHEMA IF NOT EXISTS sys;
|
||||||
|
|
||||||
|
-- 用户表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_user CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_user (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||||
|
usercode VARCHAR(100) DEFAULT NULL, -- 用户code。sso同步数据获取
|
||||||
|
password VARCHAR(128) NOT NULL, -- 密码(建议存储 bcrypt/argon2 哈希)
|
||||||
|
email VARCHAR(100), -- 电子邮件
|
||||||
|
phone VARCHAR(500), -- 电话号码
|
||||||
|
phone_hash VARCHAR(200), -- 电话hash
|
||||||
|
wechat_id VARCHAR(50), -- 微信ID
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间(使用带时区时间)
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除(使用 BOOLEAN)
|
||||||
|
status INTEGER NOT NULL DEFAULT 1, -- 状态
|
||||||
|
remark VARCHAR(255) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (user_id),
|
||||||
|
UNIQUE (optsn),
|
||||||
|
UNIQUE (email),
|
||||||
|
UNIQUE (phone),
|
||||||
|
UNIQUE (wechat_id),
|
||||||
|
UNIQUE (usercode)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_tb_sys_user_phone ON sys.tb_sys_user USING btree (phone);
|
||||||
|
|
||||||
|
-- 按 email 域名建立表达式索引(对域名小写处理以实现不区分大小写的域名查询)
|
||||||
|
-- 使用 split_part(email, '@', 2) 提取 @ 之后的域名部分,再做 lower() 归一化
|
||||||
|
-- WHERE email IS NOT NULL 可以避免索引包含大量 NULL
|
||||||
|
CREATE INDEX idx_tb_sys_user_email_domain ON sys.tb_sys_user USING btree (lower(split_part(email, '@', 2)))
|
||||||
|
WHERE email IS NOT NULL;
|
||||||
|
CREATE INDEX idx_tb_sys_user_wechat_id ON sys.tb_sys_user USING btree (wechat_id);
|
||||||
|
|
||||||
|
-- 可选:保留列注释(如果你想把 MySQL 的 COMMENT 同步到 Postgres)
|
||||||
|
COMMENT ON TABLE sys.tb_sys_user IS '用户表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.user_id IS '用户ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.password IS '密码(建议存储 bcrypt/argon2 哈希)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.email IS '电子邮件';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.phone IS '电话号码';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.wechat_id IS '微信ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.deleted IS '是否删除';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user.status IS '状态';
|
||||||
|
|
||||||
|
-- 用户信息表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_user_info CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_user_info (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||||
|
avatar VARCHAR(255), -- 头像
|
||||||
|
gender INTEGER DEFAULT 0, -- 性别
|
||||||
|
username VARCHAR(100) NOT NULL, -- 用户名
|
||||||
|
level INTEGER DEFAULT 1, -- 等级
|
||||||
|
id_card VARCHAR(50), -- 身份证号
|
||||||
|
address VARCHAR(255), -- 地址
|
||||||
|
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||||
|
remark VARCHAR(500) DEFAULT NULL, -- 备注
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(触发器维护)
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (user_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE sys.tb_sys_user_info IS '用户信息表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.user_id IS '用户ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.avatar IS '头像';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.gender IS '性别';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.username IS '用户名';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.level IS '等级';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.id_card IS '身份证号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.address IS '地址';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.remark IS '备注';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.create_time IS '创建时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.delete_time IS '删除时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_user_info.deleted IS '是否删除';
|
||||||
|
|
||||||
|
-- 登录日志表
|
||||||
|
DROP TABLE IF EXISTS sys.tb_sys_login_log CASCADE;
|
||||||
|
CREATE TABLE sys.tb_sys_login_log (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号(作为主键)
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||||
|
username VARCHAR(50) NOT NULL, -- 用户名
|
||||||
|
ip_address VARCHAR(45), -- IP地址
|
||||||
|
ip_source VARCHAR(100), -- IP来源
|
||||||
|
browser VARCHAR(100), -- 浏览器
|
||||||
|
os VARCHAR(100), -- 操作系统
|
||||||
|
password VARCHAR(128), -- 密码(建议存储 bcrypt/argon2 哈希)
|
||||||
|
login_time TIMESTAMPTZ DEFAULT now(), -- 登录时间
|
||||||
|
status INTEGER DEFAULT 1, -- 登录状态(0失败 1成功)
|
||||||
|
error_count INTEGER DEFAULT 0, -- 错误次数
|
||||||
|
message VARCHAR(255), -- 登录消息
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
PRIMARY KEY (optsn)
|
||||||
|
);
|
||||||
|
-- B-tree 索引(显式指定 USING btree,Postgres 默认即为 btree)
|
||||||
|
CREATE INDEX idx_tb_sys_login_log_user_id ON sys.tb_sys_login_log USING btree (user_id);
|
||||||
|
CREATE INDEX idx_tb_sys_login_log_login_time ON sys.tb_sys_login_log USING btree (login_time);
|
||||||
|
|
||||||
|
-- 可选:保留列注释
|
||||||
|
COMMENT ON TABLE sys.tb_sys_login_log IS '登录日志表';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.optsn IS '流水号';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.user_id IS '用户ID';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.username IS '用户名';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.ip_address IS 'IP地址';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.ip_source IS 'IP来源';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.browser IS '浏览器';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.os IS '操作系统';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.password IS '密码(建议存储 bcrypt/argon2 哈希)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.login_time IS '登录时间';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.status IS '登录状态(0失败 1成功)';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.error_count IS '错误次数';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.message IS '登录消息';
|
||||||
|
COMMENT ON COLUMN sys.tb_sys_login_log.create_time IS '创建时间';
|
||||||
331
docker/urbanLifeline/postgres/init/sql/createTableWorkcase.sql
Normal file
331
docker/urbanLifeline/postgres/init/sql/createTableWorkcase.sql
Normal file
@@ -0,0 +1,331 @@
|
|||||||
|
CREATE SCHEMA IF NOT EXISTS workcase;
|
||||||
|
|
||||||
|
-- 系统外部人员(来客)管理 用于给系统外人员创建id
|
||||||
|
DROP TABLE IF EXISTS sys.tb_guest CASCADE;
|
||||||
|
CREATE TABLE sys.tb_guest(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 来客ID
|
||||||
|
name VARCHAR(50) NOT NULL, -- 姓名
|
||||||
|
phone VARCHAR(50) DEFAULT NULL, -- 电话
|
||||||
|
email VARCHAR(50) DEFAULT NULL, -- 邮箱
|
||||||
|
wechat_id VARCHAR(50) DEFAULT NULL, -- 微信号
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 创建时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (user_id),
|
||||||
|
UNIQUE (wechat_id),
|
||||||
|
UNIQUE (phone),
|
||||||
|
UNIQUE (email)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
-- ==========================================
|
||||||
|
-- IM聊天室 + Jitsi Meet 视频会议 表设计
|
||||||
|
-- ==========================================
|
||||||
|
|
||||||
|
-- 1. 聊天室表(核心表)
|
||||||
|
-- 一个工单对应一个聊天室,来客创建,客服人员可加入
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_chat_room CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_chat_room(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
room_id VARCHAR(50) NOT NULL, -- 聊天室ID
|
||||||
|
workcase_id VARCHAR(50) DEFAULT NULL, -- 关联工单ID
|
||||||
|
room_name VARCHAR(200) NOT NULL, -- 聊天室名称(如:工单#12345的客服支持)
|
||||||
|
room_type VARCHAR(20) NOT NULL DEFAULT 'workcase', -- 聊天室类型:workcase-工单客服
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态:active-活跃 closed-已关闭 archived-已归档
|
||||||
|
guest_id VARCHAR(50) NOT NULL, -- 来客ID(创建者)
|
||||||
|
guest_name VARCHAR(100) NOT NULL, -- 来客姓名
|
||||||
|
ai_session_id VARCHAR(50) DEFAULT NULL, -- AI对话会话ID(从ai.tb_chat同步)
|
||||||
|
message_count INTEGER NOT NULL DEFAULT 0, -- 消息总数
|
||||||
|
device_code VARCHAR(50) NOT NULL, -- 设备代码
|
||||||
|
last_message_time TIMESTAMPTZ DEFAULT NULL, -- 最后消息时间
|
||||||
|
last_message TEXT DEFAULT NULL, -- 最后一条消息内容(用于列表展示)
|
||||||
|
comment_level INTEGER DEFAULT 0, -- 服务评分(1-5)
|
||||||
|
closed_by VARCHAR(50) DEFAULT NULL, -- 关闭人
|
||||||
|
closed_time TIMESTAMPTZ DEFAULT NULL, -- 关闭时间
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建人(系统自动创建)
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (room_id),
|
||||||
|
UNIQUE (workcase_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_chat_room_guest ON workcase.tb_chat_room(guest_id, status);
|
||||||
|
CREATE INDEX idx_chat_room_time ON workcase.tb_chat_room(last_message_time DESC);
|
||||||
|
COMMENT ON TABLE workcase.tb_chat_room IS 'IM聊天室表,一个工单对应一个聊天室';
|
||||||
|
|
||||||
|
-- 2. 聊天室成员表
|
||||||
|
-- 记录聊天室内的所有成员(来客+客服人员)
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_chat_room_member CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_chat_room_member(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
member_id VARCHAR(50) NOT NULL, -- 成员记录ID
|
||||||
|
room_id VARCHAR(50) NOT NULL, -- 聊天室ID
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 用户ID(来客ID或员工ID)
|
||||||
|
user_type VARCHAR(20) NOT NULL, -- 用户类型:guest-来客 staff-客服 ai-AI助手
|
||||||
|
user_name VARCHAR(100) NOT NULL, -- 用户名称
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态:active-活跃 left-已离开 removed-被移除
|
||||||
|
unread_count INTEGER NOT NULL DEFAULT 0, -- 该成员的未读消息数
|
||||||
|
last_read_time TIMESTAMPTZ DEFAULT NULL, -- 最后阅读时间
|
||||||
|
last_read_msg_id VARCHAR(50) DEFAULT NULL, -- 最后阅读的消息ID
|
||||||
|
join_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 加入时间
|
||||||
|
leave_time TIMESTAMPTZ DEFAULT NULL, -- 离开时间
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建人
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
PRIMARY KEY (member_id),
|
||||||
|
UNIQUE (room_id, user_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_chat_member_room ON workcase.tb_chat_room_member(room_id, status);
|
||||||
|
CREATE INDEX idx_chat_member_user ON workcase.tb_chat_room_member(user_id, user_type, status);
|
||||||
|
COMMENT ON TABLE workcase.tb_chat_room_member IS '聊天室成员表,记录来客和客服人员';
|
||||||
|
|
||||||
|
-- 3. 聊天室消息表
|
||||||
|
-- 存储所有聊天消息(AI对话+人工客服对话)
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_chat_room_message CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_chat_room_message(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
message_id VARCHAR(50) NOT NULL, -- 消息ID
|
||||||
|
room_id VARCHAR(50) NOT NULL, -- 聊天室ID
|
||||||
|
sender_id VARCHAR(50) NOT NULL, -- 发送者ID
|
||||||
|
sender_type VARCHAR(20) NOT NULL, -- 发送者类型:guest-来客 agent-客服 ai-AI助手 system-系统消息
|
||||||
|
sender_name VARCHAR(100) NOT NULL, -- 发送者名称
|
||||||
|
message_type VARCHAR(20) NOT NULL DEFAULT 'text', -- 消息类型:text-文本 image-图片 file-文件 voice-语音 video-视频 system-系统消息 meeting-会议通知
|
||||||
|
content TEXT NOT NULL, -- 消息内容
|
||||||
|
files VARCHAR(50)[] DEFAULT '{}', -- 附件文件ID数组(图片、文件、语音、视频等)
|
||||||
|
content_extra JSONB DEFAULT NULL, -- 扩展内容(会议链接、引用信息等)
|
||||||
|
reply_to_msg_id VARCHAR(50) DEFAULT NULL, -- 回复的消息ID(引用回复)
|
||||||
|
is_ai_message BOOLEAN NOT NULL DEFAULT false, -- 是否AI消息(标记从ai.tb_chat同步的消息)
|
||||||
|
ai_message_id VARCHAR(50) DEFAULT NULL, -- AI原始消息ID(用于追溯)
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'sent', -- 状态:sending-发送中 sent-已发送 delivered-已送达 read-已读 failed-失败 recalled-已撤回
|
||||||
|
read_count INTEGER NOT NULL DEFAULT 0, -- 已读人数
|
||||||
|
send_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 发送时间
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建人
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
PRIMARY KEY (message_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_chat_msg_room ON workcase.tb_chat_room_message(room_id, send_time DESC);
|
||||||
|
CREATE INDEX idx_chat_msg_sender ON workcase.tb_chat_room_message(sender_id, sender_type);
|
||||||
|
CREATE INDEX idx_chat_msg_ai ON workcase.tb_chat_room_message(ai_message_id) WHERE ai_message_id IS NOT NULL;
|
||||||
|
COMMENT ON TABLE workcase.tb_chat_room_message IS 'IM聊天消息表,包含AI对话和人工客服消息';
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_chat_room_summary CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_chat_room_summary (
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
summary_id VARCHAR(50) NOT NULL, -- 总结ID
|
||||||
|
room_id VARCHAR(50) NOT NULL, -- 聊天室ID
|
||||||
|
question TEXT DEFAULT NULL, -- 核心问题
|
||||||
|
needs VARCHAR(500)[] DEFAULT '{}', -- 核心诉求数组
|
||||||
|
answer TEXT DEFAULT NULL, -- 解决方案
|
||||||
|
workcloud VARCHAR(500)[] DEFAULT '{}', -- 词云关键词数组
|
||||||
|
message_count INTEGER DEFAULT 0, -- 参与总结的消息数量
|
||||||
|
summary_time TIMESTAMPTZ DEFAULT NULL, -- 总结生成时间
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建人
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (summary_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_chat_room_summary_room ON workcase.tb_chat_room_summary(room_id, summary_time DESC);
|
||||||
|
CREATE INDEX idx_chat_room_summary_time ON workcase.tb_chat_room_summary(summary_time DESC);
|
||||||
|
COMMENT ON TABLE workcase.tb_chat_room_summary IS '聊天室总结表,保存AI生成的聊天总结分析';
|
||||||
|
|
||||||
|
|
||||||
|
-- 4. 视频会议表(Jitsi Meet)
|
||||||
|
-- 记录聊天室内创建的视频会议
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_video_meeting CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_video_meeting(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
meeting_id VARCHAR(50) NOT NULL, -- 会议ID(也是Jitsi房间名)
|
||||||
|
room_id VARCHAR(50) NOT NULL, -- 关联聊天室ID
|
||||||
|
workcase_id VARCHAR(50) NOT NULL, -- 关联工单ID
|
||||||
|
meeting_name VARCHAR(200) NOT NULL, -- 会议名称
|
||||||
|
meeting_password VARCHAR(50) DEFAULT NULL, -- 会议密码(可选)
|
||||||
|
description VARCHAR(500) DEFAULT NULL, -- 会议模式
|
||||||
|
jwt_token TEXT DEFAULT NULL, -- JWT Token(用于身份验证)
|
||||||
|
jitsi_room_name VARCHAR(200) NOT NULL, -- Jitsi房间名(格式:workcase_{workcase_id}_{timestamp})
|
||||||
|
jitsi_server_url VARCHAR(500) NOT NULL DEFAULT 'https://meet.jit.si', -- Jitsi服务器地址
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'scheduled', -- 状态:scheduled-已安排 ongoing-进行中 ended-已结束 cancelled-已取消
|
||||||
|
creator_type VARCHAR(20) NOT NULL, -- 创建者类型:guest-来客 agent-客服
|
||||||
|
creator_name VARCHAR(100) NOT NULL, -- 创建者名称
|
||||||
|
participant_count INTEGER NOT NULL DEFAULT 0, -- 参与人数
|
||||||
|
max_participants INTEGER DEFAULT 10, -- 最大参与人数
|
||||||
|
start_time TIMESTAMPTZ NOT NULL, -- 定义会议开始时间
|
||||||
|
end_time TIMESTAMPTZ NOT NULL, -- 定义会议结束时间
|
||||||
|
advance INTEGER DEFAULT 5, -- 提前入会时间(分钟)
|
||||||
|
actual_start_time TIMESTAMPTZ DEFAULT NULL, -- 真正会议开始时间
|
||||||
|
actual_end_time TIMESTAMPTZ DEFAULT NULL, -- 真正会议结束时间
|
||||||
|
duration_seconds INTEGER DEFAULT 0, -- 会议时长(秒)
|
||||||
|
iframe_url TEXT DEFAULT NULL, -- iframe嵌入URL(生成后存储)
|
||||||
|
config JSONB DEFAULT NULL, -- Jitsi配置项(自定义配置)
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建人
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (meeting_id),
|
||||||
|
UNIQUE (jitsi_room_name)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_meeting_room ON workcase.tb_video_meeting(room_id, status);
|
||||||
|
CREATE INDEX idx_meeting_workcase ON workcase.tb_video_meeting(workcase_id, status);
|
||||||
|
CREATE INDEX idx_meeting_time ON workcase.tb_video_meeting(create_time DESC);
|
||||||
|
COMMENT ON TABLE workcase.tb_video_meeting IS 'Jitsi Meet视频会议表';
|
||||||
|
|
||||||
|
-- 5. 会议参与记录表(可选,用于审计和统计)
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_meeting_participant CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_meeting_participant(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
participant_id VARCHAR(50) NOT NULL, -- 参与记录ID
|
||||||
|
meeting_id VARCHAR(50) NOT NULL, -- 会议ID
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||||
|
user_type VARCHAR(20) NOT NULL, -- 用户类型:guest-来客 agent-客服
|
||||||
|
user_name VARCHAR(100) NOT NULL, -- 用户名称
|
||||||
|
join_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 加入时间
|
||||||
|
leave_time TIMESTAMPTZ DEFAULT NULL, -- 离开时间
|
||||||
|
duration_seconds INTEGER DEFAULT 0, -- 参与时长(秒)
|
||||||
|
is_moderator BOOLEAN NOT NULL DEFAULT false, -- 是否主持人
|
||||||
|
join_method VARCHAR(20) DEFAULT 'web', -- 加入方式:web-网页 mobile-移动端 desktop-桌面端
|
||||||
|
device_info VARCHAR(200) DEFAULT NULL, -- 设备信息
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
PRIMARY KEY (participant_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_meeting_participant ON workcase.tb_meeting_participant(meeting_id, join_time);
|
||||||
|
CREATE INDEX idx_participant_user ON workcase.tb_meeting_participant(user_id, user_type);
|
||||||
|
COMMENT ON TABLE workcase.tb_meeting_participant IS '视频会议参与记录表';
|
||||||
|
|
||||||
|
-- 7. 会议转录记录表(音频转文字)
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_meeting_transcription CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_meeting_transcription(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
transcription_id VARCHAR(50) NOT NULL, -- 转录记录ID
|
||||||
|
meeting_id VARCHAR(50) NOT NULL, -- 会议ID
|
||||||
|
speaker_id VARCHAR(50) NOT NULL, -- 说话人ID
|
||||||
|
speaker_name VARCHAR(100) NOT NULL, -- 说话人名称
|
||||||
|
speaker_type VARCHAR(20) NOT NULL, -- 说话人类型:guest-来客 agent-客服
|
||||||
|
content TEXT NOT NULL, -- 转录文本内容
|
||||||
|
content_raw TEXT DEFAULT NULL, -- 原始转录结果(含标点前)
|
||||||
|
language VARCHAR(10) DEFAULT 'zh-CN', -- 语言:zh-CN en-US等
|
||||||
|
confidence NUMERIC(3,2) DEFAULT NULL, -- 识别置信度(0-1)
|
||||||
|
speech_start_time TIMESTAMPTZ NOT NULL, -- 语音开始时间
|
||||||
|
speech_end_time TIMESTAMPTZ NOT NULL, -- 语音结束时间
|
||||||
|
duration_ms INTEGER NOT NULL, -- 语音时长(毫秒)
|
||||||
|
audio_url VARCHAR(500) DEFAULT NULL, -- 音频片段URL(可选)
|
||||||
|
segment_index INTEGER NOT NULL DEFAULT 0, -- 片段序号(按时间排序)
|
||||||
|
is_final BOOLEAN NOT NULL DEFAULT true, -- 是否最终结果(实时转录会有中间结果)
|
||||||
|
service_provider VARCHAR(50) DEFAULT 'xunfei', -- 服务提供商:xunfei aliyun tencent google
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
PRIMARY KEY (transcription_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_transcription_meeting ON workcase.tb_meeting_transcription(meeting_id, segment_index);
|
||||||
|
COMMENT ON TABLE workcase.tb_meeting_transcription IS '会议转录记录表,用于保存视频会议的语音转文字内容';
|
||||||
|
|
||||||
|
-- 8. 员工配置表
|
||||||
|
-- 用于控制哪些人员可以在聊天室里接待来客
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_customer_service CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_customer_service(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 员工ID(关联sys用户ID)
|
||||||
|
username VARCHAR(100) NOT NULL, -- 员工姓名
|
||||||
|
user_code VARCHAR(50) DEFAULT NULL, -- 员工工号
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'offline', -- 状态:online-在线 busy-忙碌 offline-离线
|
||||||
|
skill_tags VARCHAR(50)[] DEFAULT '{}', -- 技能标签(如:电力、燃气、水务)
|
||||||
|
max_concurrent INTEGER NOT NULL DEFAULT 5, -- 最大并发接待数
|
||||||
|
current_workload INTEGER NOT NULL DEFAULT 0, -- 当前工作量
|
||||||
|
total_served INTEGER NOT NULL DEFAULT 0, -- 累计服务次数
|
||||||
|
avg_response_time INTEGER DEFAULT NULL, -- 平均响应时间(秒)
|
||||||
|
satisfaction_score NUMERIC(3,2) DEFAULT NULL, -- 满意度评分(0-5)
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建人
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (user_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_customer_service_status ON workcase.tb_customer_service(status, current_workload);
|
||||||
|
COMMENT ON TABLE workcase.tb_customer_service IS '员工配置表,用于控制哪些人员可以在聊天室接待来客';
|
||||||
|
|
||||||
|
-- 工单表
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_workcase CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_workcase(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
workcase_id VARCHAR(50) NOT NULL, -- 工单ID
|
||||||
|
room_id VARCHAR(50) NOT NULL, -- 聊天室ID
|
||||||
|
user_id VARCHAR(50) NOT NULL, -- 来客ID
|
||||||
|
username VARCHAR(200) NOT NULL, -- 来客姓名
|
||||||
|
phone VARCHAR(20) NOT NULL, -- 来客电话
|
||||||
|
type VARCHAR(50) NOT NULL, -- 故障类型
|
||||||
|
device VARCHAR(50) DEFAULT NULL, -- 设备名称
|
||||||
|
device_code VARCHAR(50) DEFAULT NULL, -- 设备代码
|
||||||
|
device_name_plate VARCHAR(50) DEFAULT NULL, -- 设备名称牌
|
||||||
|
device_name_plate_img VARCHAR(50) NOT NULL, -- 设备名称牌图片
|
||||||
|
address VARCHAR(1000) DEFAULT NULL, -- 现场地址
|
||||||
|
description VARCHAR(1000) DEFAULT NULL, -- 故障描述
|
||||||
|
imgs VARCHAR(50)[] DEFAULT '{}', -- 工单图片id
|
||||||
|
emergency VARCHAR(50) NOT NULL DEFAULT 'normal', -- 紧急程度 normal-普通 emergency-紧急
|
||||||
|
status VARCHAR(50) NOT NULL DEFAULT 'pending', -- 状态 pending-待处理 processing-处理中 done-已完成
|
||||||
|
processor VARCHAR(50) DEFAULT NULL, -- 处理人
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建人
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
|
PRIMARY KEY (workcase_id),
|
||||||
|
UNIQUE (room_id),
|
||||||
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 工单处理过程表(包含工单流转)
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_workcase_process CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_workcase_process(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
workcase_id VARCHAR(50) NOT NULL, -- 工单ID
|
||||||
|
process_id VARCHAR(50) NOT NULL, -- 过程id
|
||||||
|
action VARCHAR(50) NOT NULL, -- 动作 info:记录,assign:指派,redeploy:转派,repeal:撤销,finish:完成
|
||||||
|
message VARCHAR(200) DEFAULT NULL, -- 消息
|
||||||
|
files VARCHAR(50)[] DEFAULT '{}', -- 携带文件
|
||||||
|
processor VARCHAR(50) DEFAULT NULL, -- 处理人(指派、转派专属)
|
||||||
|
remark VARCHAR(500) DEFAULT NULL, -- 备注
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 过程发起人
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
PRIMARY KEY (process_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 工单设备涉及的文件表
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_workcase_device CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_workcase_device(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
workcase_id VARCHAR(50) NOT NULL, -- 工单ID
|
||||||
|
device VARCHAR(50) NOT NULL, -- 设备名称
|
||||||
|
device_code VARCHAR(50) DEFAULT NULL, -- 设备代码
|
||||||
|
file_id VARCHAR(50) NOT NULL, -- 文件id
|
||||||
|
file_name VARCHAR(50) NOT NULL, -- 文件名
|
||||||
|
file_root_id VARCHAR(50) DEFAULT NULL, -- 文件根id
|
||||||
|
PRIMARY KEY(workcase_id, file_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 来客对话、工单过程中生成的词云表
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_word_cloud CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_word_cloud(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
word_id VARCHAR(50) NOT NULL, -- 词条ID
|
||||||
|
word VARCHAR(100) NOT NULL, -- 词语
|
||||||
|
frequency INTEGER NOT NULL DEFAULT 1, -- 词频
|
||||||
|
source_type VARCHAR(20) NOT NULL, -- 来源类型 chat-聊天 workcase-工单 global-全局
|
||||||
|
source_id VARCHAR(50) DEFAULT NULL, -- 来源ID(room_id/workcase_id,NULL表示全局统计)
|
||||||
|
category VARCHAR(50) DEFAULT NULL, -- 分类(如:fault-故障类型 device-设备 emotion-情绪词等)
|
||||||
|
stat_date DATE NOT NULL, -- 统计日期(按天聚合)
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
PRIMARY KEY (word_id),
|
||||||
|
UNIQUE (word, source_type, source_id, stat_date, category) -- 同一天同一来源同一分类的词唯一
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_word_cloud_source ON workcase.tb_word_cloud(source_type, source_id, stat_date);
|
||||||
|
CREATE INDEX idx_word_cloud_category ON workcase.tb_word_cloud(category, stat_date);
|
||||||
|
COMMENT ON TABLE workcase.tb_word_cloud IS '词云统计表,记录聊天和工单中的关键词';
|
||||||
52
docker/urbanLifeline/postgres/init/sql/initAll.sql
Normal file
52
docker/urbanLifeline/postgres/init/sql/initAll.sql
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
-- =============================
|
||||||
|
-- 城市生命线AI数智化平台 - 数据库初始化脚本
|
||||||
|
-- 按顺序执行各模块建表SQL及数据初始化
|
||||||
|
-- =============================
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 第一阶段:创建数据库和表结构
|
||||||
|
-- =============================
|
||||||
|
\i createDB.sql
|
||||||
|
|
||||||
|
-- 1. 系统基础模块
|
||||||
|
\i createTablePermission.sql
|
||||||
|
\i createTableUser.sql
|
||||||
|
|
||||||
|
-- 2. 文件管理模块
|
||||||
|
\i createTableFile.sql
|
||||||
|
|
||||||
|
-- 3. 消息通知模块
|
||||||
|
\i createTableMessage.sql
|
||||||
|
|
||||||
|
-- 4. 日志模块
|
||||||
|
\i createTableLog.sql
|
||||||
|
|
||||||
|
-- 5. 配置管理模块
|
||||||
|
\i createTableConfig.sql
|
||||||
|
|
||||||
|
-- 6. AI模块 智能体+知识库
|
||||||
|
\i createTableAI.sql
|
||||||
|
|
||||||
|
-- 7. 招投标业务模块
|
||||||
|
\i createTableBidding.sql
|
||||||
|
|
||||||
|
-- 8. 智能客服业务模块
|
||||||
|
\i createTableWorkcase.sql
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 第二阶段:初始化基础数据
|
||||||
|
-- =============================
|
||||||
|
|
||||||
|
-- 1. 初始化权限相关基础数据(部门、角色、权限、视图、模块)
|
||||||
|
\i initDataPermission.sql
|
||||||
|
|
||||||
|
-- 2. 初始化用户数据(管理员账户)
|
||||||
|
\i initDataUser.sql
|
||||||
|
|
||||||
|
-- 3. 初始化消息渠道配置
|
||||||
|
\i initDataMessage.sql
|
||||||
|
|
||||||
|
-- 4. 初始化系统配置
|
||||||
|
\i initDataConfig.sql
|
||||||
|
|
||||||
|
-- 注意:文件、日志、知识库、招投标、客服等业务表无需初始化数据
|
||||||
108
docker/urbanLifeline/postgres/init/sql/initDataConfig.sql
Normal file
108
docker/urbanLifeline/postgres/init/sql/initDataConfig.sql
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
-- 初始化系统常用配置(与 config.tb_sys_config 对应)
|
||||||
|
-- 仅插入常用示例,可按需调整 value/remark
|
||||||
|
|
||||||
|
INSERT INTO config.tb_sys_config (
|
||||||
|
optsn, config_id, key, name, value, config_type, render_type, description,
|
||||||
|
re, options, "group", module_id, order_num, status, remark,
|
||||||
|
creator, dept_path, updater, create_time, update_time, delete_time, deleted
|
||||||
|
) VALUES
|
||||||
|
|
||||||
|
-- 站点与品牌
|
||||||
|
('CFG-0001', 'cfg_site_name', 'site.name', '站点名称', 'urban-lifeline 平台', 'String', 'input', '站点名称', NULL, NULL, 'site', 'mod_system', 10, 0, '展示在标题/登录/页脚', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0002', 'cfg_site_logo', 'site.logo', '站点Logo', '/static/logo.png', 'String', 'input', '站点Logo地址', NULL, NULL, 'site', 'mod_system', 20, 0, '相对或绝对URL', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0003', 'cfg_site_icp', 'site.icp', 'ICP备案号', '', 'String', 'input', 'ICP备案号', NULL, NULL, 'site', 'mod_system', 30, 0, '页脚展示', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- 国际化与时区
|
||||||
|
('CFG-0101', 'cfg_i18n_locale', 'i18n.defaultLocale', '默认语言', 'zh-CN', 'String', 'select', '默认语言', NULL, '["zh-CN", "en-US"]'::json, 'i18n', 'mod_system', 10, 0, '如 zh-CN/en-US', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0102', 'cfg_timezone', 'system.timezone', '系统时区', 'Asia/Shanghai', 'String', 'input', '系统默认时区', NULL, NULL, 'i18n', 'mod_system', 20, 0, 'IANA时区名', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- 安全与认证
|
||||||
|
('CFG-0201', 'cfg_pwd_policy', 'security.passwordPolicy','密码策略', '{"minLen":8,"upper":1,"lower":1,"digit":1,"special":0}', 'String', 'textarea', '密码策略', NULL, NULL, 'security', 'mod_system', 10, 0, 'JSON结构', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0202', 'cfg_jwt_exp', 'security.jwt.expireSeconds','JWT过期时间', '86400', 'INTEGER', 'input', 'JWT过期秒数', NULL, NULL, 'security', 'mod_system', 20, 0, '默认24小时', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0203', 'cfg_session_timeout', 'security.session.timeoutMinutes','会话超时', '30', 'INTEGER', 'input', '会话超时(分钟)', NULL, NULL, 'security', 'mod_system', 30, 0, '空闲登出', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0204', 'cfg_signup_enabled', 'security.signup.enabled','开放注册', 'false', 'BOOLEAN', 'switch', '是否开放注册', NULL, NULL, 'security', 'mod_system', 40, 0, '生产建议关闭', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- 存储与上传
|
||||||
|
('CFG-0301', 'cfg_upload_max', 'upload.maxSizeMB', '最大上传大小', '50', 'INTEGER', 'input', '单文件最大上传(MB)', NULL, NULL, 'storage', 'mod_file', 10, 0, '前后端需一致校验', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0302', 'cfg_storage_backend', 'storage.backend', '存储后端', 'minio', 'String', 'select', '存储后端类型', NULL, '["local", "minio", "s3"]'::json, 'storage', 'mod_file', 20, 0, '本地/MinIO/S3等,当前默认MinIO', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0303', 'cfg_storage_base', 'storage.basePath', '存储路径', '/data/urban-lifeline', 'String', 'input', '本地存储基路径', NULL, NULL, 'storage', 'mod_file', 30, 0, '当 backend=local', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- MinIO 对象存储配置
|
||||||
|
('CFG-0310', 'cfg_minio_endpoint', 'minio.endpoint', 'MinIO服务端点', 'http://localhost:9000', 'String', 'input', 'MinIO服务器地址', NULL, NULL, 'storage', 'mod_file', 40, 0, 'MinIO API服务地址,如 http://localhost:9000', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0311', 'cfg_minio_accesskey', 'minio.accessKey', 'MinIO访问密钥', 'minioadmin', 'String', 'input', 'MinIO AccessKey', NULL, NULL, 'storage', 'mod_file', 50, 0, 'MinIO认证的AccessKey', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0312', 'cfg_minio_secretkey', 'minio.secretKey', 'MinIO私钥', 'minioadmin123', 'String', 'password', 'MinIO SecretKey', NULL, NULL, 'storage', 'mod_file', 60, 0, 'MinIO认证的SecretKey', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0313', 'cfg_minio_bucket', 'minio.bucketName', 'MinIO存储桶', 'urban-lifeline', 'String', 'input', 'MinIO默认存储桶名称', NULL, NULL, 'storage', 'mod_file', 70, 0, '用于存储文件的默认bucket', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0314', 'cfg_minio_publicurl', 'minio.publicUrl', 'MinIO公网地址', 'http://localhost:9000', 'String', 'input', 'MinIO公网访问地址', NULL, NULL, 'storage', 'mod_file', 80, 0, '用于生成文件访问URL,可与endpoint不同', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0315', 'cfg_minio_ssl', 'minio.ssl.enabled', '启用SSL', 'false', 'BOOLEAN', 'switch', '是否启用SSL连接', NULL, NULL, 'storage', 'mod_file', 90, 0, 'HTTPS连接MinIO服务', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0316', 'cfg_minio_region', 'minio.region', 'MinIO区域', 'us-east-1', 'String', 'input', 'MinIO存储区域', NULL, NULL, 'storage', 'mod_file', 100, 0, 'AWS S3兼容的区域配置', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- 文件管理配置
|
||||||
|
('CFG-0320', 'cfg_file_allowed_exts','file.allowedExtensions', '允许的文件扩展名', 'jpg,jpeg,png,gif,pdf,doc,docx,xls,xlsx,ppt,pptx,txt,zip,rar', 'String', 'textarea', '允许上传的文件扩展名', NULL, NULL, 'storage', 'mod_file', 110, 0, '逗号分隔,如 jpg,png,pdf', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0321', 'cfg_file_forbidden_exts','file.forbiddenExtensions','禁止的文件扩展名', 'exe,bat,sh,php,jsp,asp', 'String', 'textarea', '禁止上传的文件扩展名', NULL, NULL, 'storage', 'mod_file', 120, 0, '逗号分隔,安全考虑', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0322', 'cfg_file_cleanup_days', 'file.tempCleanupDays', '临时文件清理天数', '7', 'INTEGER', 'input', '临时文件自动清理天数', NULL, NULL, 'storage', 'mod_file', 130, 0, '超过天数的临时文件将被清理', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0323', 'cfg_file_duplicate_check','file.duplicateCheck.enabled','启用文件去重', 'true', 'BOOLEAN', 'switch', '是否启用MD5去重检查', NULL, NULL, 'storage', 'mod_file', 140, 0, '基于MD5值检查重复文件', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0324', 'cfg_file_virus_scan', 'file.virusScan.enabled', '启用病毒扫描', 'false', 'BOOLEAN', 'switch', '是否启用文件病毒扫描', NULL, NULL, 'storage', 'mod_file', 150, 0, '需要集成防病毒引擎', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- 通知(邮件/SMS)
|
||||||
|
-- 邮件配置
|
||||||
|
('CFG-0401', 'cfg_mail_host', 'email.host', 'SMTP服务器地址', 'smtp.qq.com', 'String', 'input', 'SMTP服务器地址', NULL, NULL, 'notify', 'mod_message', 10, 1, '邮件发送服务器地址', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0402', 'cfg_mail_port', 'email.port', 'SMTP端口', '587', 'INTEGER', 'input', 'SMTP服务器端口', NULL, NULL, 'notify', 'mod_message', 20, 1, '常用:25/465/587', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0403', 'cfg_mail_username', 'email.username', '发件人邮箱', '3223905473@qq.com', 'String', 'input', '发件人邮箱地址', NULL, NULL, 'notify', 'mod_message', 30, 1, '用于发送邮件的邮箱账号', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0404', 'cfg_mail_password', 'email.password', '邮箱授权码', 'xmdmxvtjumxocicc', 'String', 'password', '邮箱授权码/密码', NULL, NULL, 'notify', 'mod_message', 40, 1, '邮箱的授权码或密码', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0405', 'cfg_mail_fromname', 'email.fromName', '发件人名称', 'urban-lifeline平台', 'String', 'input', '发件人显示名称', NULL, NULL, 'notify', 'mod_message', 50, 1, '邮件中显示的发件人名称', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0406', 'cfg_mail_ssl', 'email.ssl.enable', '启用SSL', 'true', 'BOOLEAN', 'switch', '是否启用SSL', NULL, NULL, 'notify', 'mod_message', 60, 1, 'SSL加密连接', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0407', 'cfg_mail_timeout', 'email.timeout', '连接超时时间', '30000', 'INTEGER', 'input', '连接超时时间(毫秒)', NULL, NULL, 'notify', 'mod_message', 70, 1, 'SMTP连接超时时间(5000-60000)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- 短信配置
|
||||||
|
('CFG-0411', 'cfg_sms_provider', 'sms.provider', '短信服务商', 'aliyun', 'String', 'select', '短信服务提供商', NULL, '["aliyun", "tencent"]'::json, 'notify', 'mod_message', 80, 1, '短信服务提供商类型', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0412', 'cfg_sms_keyid', 'sms.accessKeyId', 'AccessKey ID', 'LTAI5t68do3qVXx5Rufugt3X', 'String', 'input', '短信服务AccessKey ID', NULL, NULL, 'notify', 'mod_message', 90, 1, '云服务商的AccessKey ID', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0413', 'cfg_sms_secret', 'sms.accessKeySecret', 'AccessKey Secret', '2vD9ToIff49Vph4JQXsn0Cy8nXQfzA', 'String', 'password', '短信服务AccessKey Secret', NULL, NULL, 'notify', 'mod_message', 100, 1, '云服务商的AccessKey Secret', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0414', 'cfg_sms_sign', 'sms.signName', '短信签名', 'urban-lifeline', 'String', 'input', '短信签名', NULL, NULL, 'notify', 'mod_message', 110, 1, '发送短信使用的签名', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0415', 'cfg_sms_tpl_login', 'sms.templateCode.login', '登录验证码模板', 'SMS_491985030', 'String', 'input', '登录验证码模板编码', NULL, NULL, 'notify', 'mod_message', 120, 1, '登录验证码短信模板', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0416', 'cfg_sms_tpl_register', 'sms.templateCode.register','注册验证码模板', 'SMS_491985030', 'String', 'input', '注册验证码模板编码', NULL, NULL, 'notify', 'mod_message', 130, 1, '注册验证码短信模板', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0417', 'cfg_sms_timeout', 'sms.timeout', '请求超时时间', '30000', 'INTEGER', 'input', '请求超时时间(毫秒)', NULL, NULL, 'notify', 'mod_message', 140, 1, 'API请求超时时间(5000-60000)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- Dify AI 配置
|
||||||
|
-- Dify 基础配置
|
||||||
|
('CFG-0450', 'cfg_dify_api_base', 'dify.apiBaseUrl', 'Dify API地址', 'http://localhost:8000/v1', 'String', 'input', 'Dify API基础地址', NULL, NULL, 'dify', 'mod_agent', 10, 1, 'Dify服务的API基础地址,如 http://localhost/dify/api', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0452', 'cfg_dify_knowledge_key','dify.knowledgeApiKey', '知识库API密钥', 'dataset-LepcmgOE95n2S7yweNhQzNoB', 'String', 'password', '知识库API密钥', NULL, NULL, 'dify', 'mod_agent', 30, 1, '用于访问Dify知识库的API密钥', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0453', 'cfg_dify_timeout', 'dify.timeout', '请求超时时间', '60', 'INTEGER', 'input', '请求超时时间(秒)', NULL, NULL, 'dify', 'mod_agent', 40, 1, 'API请求的超时时间(10-600秒)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0454', 'cfg_dify_conn_timeout','dify.connectTimeout', '连接超时时间', '10', 'INTEGER', 'input', '连接超时时间(秒)', NULL, NULL, 'dify', 'mod_agent', 50, 1, 'API连接的超时时间(5-60秒)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0455', 'cfg_dify_read_timeout','dify.readTimeout', '读取超时时间', '60', 'INTEGER', 'input', '读取超时时间(秒)', NULL, NULL, 'dify', 'mod_agent', 60, 1, 'API读取响应的超时时间(10-600秒)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0456', 'cfg_dify_stream_timeout','dify.streamTimeout', '流式响应超时时间', '300', 'INTEGER', 'input', '流式响应超时时间(秒)', NULL, NULL, 'dify', 'mod_agent', 70, 1, '流式API响应的超时时间(30-1800秒)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- Dify 上传配置
|
||||||
|
('CFG-0460', 'cfg_dify_upload_types','dify.upload.allowedTypes','允许的文件类型', 'pdf,txt,docx,doc,md,html,htm,xlsx,xls,csv', 'String', 'textarea', '上传文件允许的类型', NULL, NULL, 'dify', 'mod_agent', 80, 1, '支持上传的文件类型列表,逗号分隔', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0461', 'cfg_dify_upload_max', 'dify.upload.maxSize', '最大文件大小', '50', 'INTEGER', 'input', '最大文件大小(MB)', NULL, NULL, 'dify', 'mod_agent', 90, 1, '单个文件上传的最大大小限制(1-500MB)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- Dify 知识库配置
|
||||||
|
('CFG-0470', 'cfg_dify_index_tech', 'dify.knowledge.indexing.tchnique','默认索引方式', 'high_quality', 'String', 'select', '默认索引方式', NULL, '["high_quality", "economy"]'::json, 'dify', 'mod_agent', 100, 1, '知识库文档的默认索引方式:high_quality(高质量)或 economy(经济)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0471', 'cfg_dify_embed_model', 'dify.knowledge.embedding.model','默认Embedding模型', 'Qwen/Qwen3-Embedding-8B', 'String', 'input', '默认Embedding模型', NULL, NULL, 'dify', 'mod_agent', 110, 1, '知识库使用的默认Embedding模型名称', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0472', 'cfg_dify_embed_provider', 'dify.knowledge.embedding.model.provider','Embedding模型供应商', 'langgenius/siliconflow/siliconflow', 'String', 'input', 'Embedding模型供应商', NULL, NULL, 'dify', 'mod_agent', 120, 1, 'Embedding模型的供应商标识', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0473', 'cfg_dify_rerank_enable', 'dify.knowledge.reranking.enable','启用Rerank', 'true', 'BOOLEAN', 'switch', '是否启用Rerank重排序', NULL, NULL, 'dify', 'mod_agent', 130, 1, '启用后会对检索结果进行重排序提升相关性', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0474', 'cfg_dify_rerank_model', 'dify.knowledge.rerank.model','Rerank模型', 'Qwen/Qwen3-Reranker-8B', 'String', 'input', 'Rerank重排序模型', NULL, NULL, 'dify', 'mod_agent', 140, 1, '知识库使用的Rerank模型名称', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0475', 'cfg_dify_rerank_provider', 'dify.knowledge.rerank.model.provider','Rerank模型供应商', 'langgenius/siliconflow/siliconflow', 'String', 'input', 'Rerank模型供应商', NULL, NULL, 'dify', 'mod_agent', 150, 1, 'Rerank模型的供应商标识', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0476', 'cfg_dify_retrieval_topk', 'dify.knowledge.retrieval.top.k','检索TopK', '5', 'INTEGER', 'input', '检索返回的最大文档数', NULL, NULL, 'dify', 'mod_agent', 160, 1, '知识库检索时返回的最相关文档数量(1-20)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0477', 'cfg_dify_retrieval_threshold', 'dify.knowledge.retrieval.score.threshold','相似度阈值', '0.5', 'DOUBLE', 'input', '检索相似度阈值', NULL, NULL, 'dify', 'mod_agent', 170, 1, '低于此阈值的文档将被过滤(0.0-1.0)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
-- Dify workcase相关智能体配置
|
||||||
|
('CFG-0478', 'cfg_dify_workcase_chat', 'dify.workcase.agent.chat','泰豪小电AgentApiKey', 'app-CDKy0wYkPnl6dA6G7eu113Vw', 'String', 'input', '泰豪小电AgentApiKey', NULL, NULL, 'dify', 'mod_agent', 160, 1, '泰豪小电AgentApiKey', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0479', 'cfg_dify_workcase_summary', 'dify.workcase.workflow.summary','工单总结AgentApikey', 'app-YMlj2B0m21KpYZPv3YdObi7r', 'String', 'input', '工单总结AgentApikey', NULL, NULL, 'dify', 'mod_agent', 170, 1, '工单总结AgentApikey', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
|
||||||
|
-- 日志与审计
|
||||||
|
('CFG-0501', 'cfg_log_level', 'log.level', '日志级别', 'INFO', 'String', 'select', '系统日志级别', NULL, '["DEBUG", "INFO", "WARN", "ERROR"]'::json, 'log', 'mod_system', 10, 0, 'DEBUG/INFO/WARN/ERROR', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0502', 'cfg_audit_retention', 'audit.retentionDays', '审计日志保留', '90', 'INTEGER', 'input', '审计日志保留天数', NULL, NULL, 'log', 'mod_system', 20, 0, '合规按需调整', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- 平台特性
|
||||||
|
('CFG-0601', 'cfg_maintenance', 'platform.maintenance', '维护模式', 'false', 'BOOLEAN', 'switch', '维护模式开关', NULL, NULL, 'platform', 'mod_system', 10, 0, 'true时仅管理员可用', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0602', 'cfg_feature_acl_policy','feature.acl.policy', 'ACL策略', 'enabled', 'String', 'select', 'ACL策略开关', NULL, '["enabled", "disabled"]'::json, 'platform', 'mod_system', 20, 0, 'enabled/disabled', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
|
||||||
|
-- 微信客服配置
|
||||||
|
('CFG-0701', 'cfg_wechat_kefu_corpid', 'wechat.kefu.corpId', '企业ID', '', 'String', 'input', '企业微信的企业ID', NULL, NULL, 'wechat', 'mod_workcase', 10, 1, '企业微信管理后台获取', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0702', 'cfg_wechat_kefu_secret', 'wechat.kefu.secret', '客服应用Secret', '', 'String', 'password', '微信客服应用的Secret', NULL, NULL, 'wechat', 'mod_workcase', 20, 1, '微信客服应用的密钥', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0703', 'cfg_wechat_kefu_token', 'wechat.kefu.token', '回调Token', '', 'String', 'input', '消息回调的Token', NULL, NULL, 'wechat', 'mod_workcase', 30, 1, '用于验证消息回调的Token', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0704', 'cfg_wechat_kefu_aeskey', 'wechat.kefu.encodingAesKey','回调加密密钥', '', 'String', 'password', '消息回调的EncodingAESKey', NULL, NULL, 'wechat', 'mod_workcase', 40, 1, '用于解密消息回调的AES密钥', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0705', 'cfg_wechat_kefu_openkfid', 'wechat.kefu.openKfid', '客服账号ID', '', 'String', 'input', '微信客服账号的open_kfid', NULL, NULL, 'wechat', 'mod_workcase', 50, 1, '用于发送消息的客服账号ID', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||||
|
('CFG-0706', 'cfg_wechat_kefu_welcome', 'wechat.kefu.welcomeTemplate','欢迎语模板', '您好,您的工单已创建。\n工单编号:{workcaseId}\n问题类型:{type}\n设备:{device}\n我们将尽快为您处理。', 'String', 'textarea', '客服欢迎语消息模板', NULL, NULL, 'wechat', 'mod_workcase', 60, 1, '支持变量:{workcaseId},{type},{device},{username}', 'system', NULL, NULL, now(), NULL, NULL, false);
|
||||||
|
|
||||||
|
|
||||||
118
docker/urbanLifeline/postgres/init/sql/initDataMessage.sql
Normal file
118
docker/urbanLifeline/postgres/init/sql/initDataMessage.sql
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
-- 初始化消息渠道配置(与 message schema 对应)
|
||||||
|
-- 配置常用消息发送渠道
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 1. 初始化消息渠道
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO message.tb_message_channel (
|
||||||
|
optsn, channel_id, channel_code, channel_name, channel_desc,
|
||||||
|
config, status, priority, creator, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
-- 应用内消息(默认渠道,优先级最高)
|
||||||
|
('CH-0001', 'channel_app', 'app', '应用内消息', '系统内部消息通知',
|
||||||
|
'{"enabled": true, "realtime": true}'::json,
|
||||||
|
'enabled', 100, 'system', now(), false),
|
||||||
|
|
||||||
|
-- 短信通知
|
||||||
|
('CH-0002', 'channel_sms', 'sms', '短信通知', '短信发送服务',
|
||||||
|
'{
|
||||||
|
"enabled": false,
|
||||||
|
"provider": "",
|
||||||
|
"apiKey": "",
|
||||||
|
"apiSecret": "",
|
||||||
|
"signName": "",
|
||||||
|
"templateCode": ""
|
||||||
|
}'::json,
|
||||||
|
'disabled', 80, 'system', now(), false),
|
||||||
|
|
||||||
|
-- 邮件通知
|
||||||
|
('CH-0003', 'channel_email', 'email', '邮件通知', '电子邮件发送服务',
|
||||||
|
'{
|
||||||
|
"enabled": false,
|
||||||
|
"smtpHost": "",
|
||||||
|
"smtpPort": 465,
|
||||||
|
"username": "",
|
||||||
|
"password": "",
|
||||||
|
"fromAddress": "",
|
||||||
|
"useSsl": true
|
||||||
|
}'::json,
|
||||||
|
'disabled', 70, 'system', now(), false),
|
||||||
|
|
||||||
|
-- 微信公众号
|
||||||
|
('CH-0004', 'channel_wechat_mp', 'wechat_official_account', '微信公众号', '微信公众号模板消息',
|
||||||
|
'{
|
||||||
|
"enabled": false,
|
||||||
|
"appId": "",
|
||||||
|
"appSecret": "",
|
||||||
|
"templateId": ""
|
||||||
|
}'::json,
|
||||||
|
'disabled', 60, 'system', now(), false),
|
||||||
|
|
||||||
|
-- 微信小程序
|
||||||
|
('CH-0005', 'channel_wechat_mini', 'wechat_applet', '微信小程序', '微信小程序订阅消息',
|
||||||
|
'{
|
||||||
|
"enabled": false,
|
||||||
|
"appId": "",
|
||||||
|
"appSecret": "",
|
||||||
|
"templateId": ""
|
||||||
|
}'::json,
|
||||||
|
'disabled', 50, 'system', now(), false),
|
||||||
|
|
||||||
|
-- 钉钉通知
|
||||||
|
('CH-0006', 'channel_dingtalk', 'dingtalk', '钉钉通知', '钉钉工作通知',
|
||||||
|
'{
|
||||||
|
"enabled": false,
|
||||||
|
"agentId": "",
|
||||||
|
"appKey": "",
|
||||||
|
"appSecret": "",
|
||||||
|
"robotToken": ""
|
||||||
|
}'::json,
|
||||||
|
'disabled', 40, 'system', now(), false);
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 2. 初始化消息模板(系统通用模板)
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO message.tb_message_template (
|
||||||
|
optsn, template_id, template_code, template_name, template_type,
|
||||||
|
title_template, content_template, variables, service,
|
||||||
|
creator, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
-- 用户注册欢迎消息
|
||||||
|
('TPL-0001', 'tpl_user_welcome', 'USER_WELCOME', '用户注册欢迎', 'system',
|
||||||
|
'欢迎加入 {{platformName}}',
|
||||||
|
'您好,{{username}}!\n\n欢迎加入 {{platformName}} 平台。您的账号已成功创建。\n\n账号信息:\n- 用户名:{{usercode}}\n- 邮箱:{{email}}\n- 注册时间:{{registerTime}}\n\n祝您使用愉快!',
|
||||||
|
'["platformName", "username", "usercode", "email", "registerTime"]'::jsonb,
|
||||||
|
'system',
|
||||||
|
'system', now(), false),
|
||||||
|
|
||||||
|
-- 密码重置通知
|
||||||
|
('TPL-0002', 'tpl_password_reset', 'PASSWORD_RESET', '密码重置通知', 'system',
|
||||||
|
'密码重置验证码',
|
||||||
|
'您好,{{username}}!\n\n您正在重置密码,验证码为:{{code}}\n\n验证码有效期为 {{expireMinutes}} 分钟,请尽快完成操作。\n\n如非本人操作,请忽略此消息。',
|
||||||
|
'["username", "code", "expireMinutes"]'::jsonb,
|
||||||
|
'system',
|
||||||
|
'system', now(), false),
|
||||||
|
|
||||||
|
-- 系统维护通知
|
||||||
|
('TPL-0003', 'tpl_system_maintenance', 'SYSTEM_MAINTENANCE', '系统维护通知', 'system',
|
||||||
|
'系统维护通知',
|
||||||
|
'尊敬的用户:\n\n系统将于 {{startTime}} 至 {{endTime}} 进行维护升级。\n\n维护内容:{{content}}\n\n维护期间系统将暂停服务,请您提前做好相关安排。\n\n给您带来不便,敬请谅解!',
|
||||||
|
'["startTime", "endTime", "content"]'::jsonb,
|
||||||
|
'system',
|
||||||
|
'system', now(), false),
|
||||||
|
|
||||||
|
-- 工单创建通知
|
||||||
|
('TPL-0101', 'tpl_ticket_created', 'TICKET_CREATED', '工单创建通知', 'business',
|
||||||
|
'新工单通知',
|
||||||
|
'您好,{{username}}!\n\n您有一条新的工单需要处理:\n\n工单编号:{{ticketNo}}\n工单标题:{{title}}\n优先级:{{priority}}\n创建时间:{{createTime}}\n\n请及时登录系统查看处理。',
|
||||||
|
'["username", "ticketNo", "title", "priority", "createTime"]'::jsonb,
|
||||||
|
'customer_service',
|
||||||
|
'system', now(), false),
|
||||||
|
|
||||||
|
-- 招标公告发布通知
|
||||||
|
('TPL-0201', 'tpl_bidding_published', 'BIDDING_PUBLISHED', '招标公告发布', 'business',
|
||||||
|
'招标公告发布通知',
|
||||||
|
'您好!\n\n新的招标项目已发布:\n\n项目名称:{{projectName}}\n项目编号:{{projectNo}}\n发布时间:{{publishTime}}\n截止时间:{{deadlineTime}}\n\n详情请登录系统查看。',
|
||||||
|
'["projectName", "projectNo", "publishTime", "deadlineTime"]'::jsonb,
|
||||||
|
'bidding',
|
||||||
|
'system', now(), false);
|
||||||
471
docker/urbanLifeline/postgres/init/sql/initDataPermission.sql
Normal file
471
docker/urbanLifeline/postgres/init/sql/initDataPermission.sql
Normal file
@@ -0,0 +1,471 @@
|
|||||||
|
-- 初始化权限相关基础数据(与 sys schema 对应)
|
||||||
|
-- 包含:部门、角色、模块、权限、视图及其关联关系
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 1. 初始化根部门
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO sys.tb_sys_dept (
|
||||||
|
optsn, dept_id, name, parent_id, dept_path, description,
|
||||||
|
creator, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
('DEPT-0001', 'dept_root', '根部门', NULL, '/dept_root/', '系统根部门',
|
||||||
|
'system', now(), false);
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 2. 初始化全局角色
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO sys.tb_sys_role (
|
||||||
|
optsn, role_id, name, description, scope, owner_dept_id,
|
||||||
|
status, creator, dept_path, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
-- 超级管理员(全局)
|
||||||
|
('ROLE-0001', 'role_super_admin', '超级管理员', '拥有系统所有权限的最高管理员',
|
||||||
|
'global', NULL, true, 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 系统管理员(全局)
|
||||||
|
('ROLE-0002', 'role_system_admin', '系统管理员', '负责系统配置和用户管理',
|
||||||
|
'global', NULL, true, 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 普通用户(全局)
|
||||||
|
('ROLE-0003', 'role_user', '普通用户', '系统普通用户角色',
|
||||||
|
'global', NULL, true, 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 访客(全局)- 注册用户默认角色,具备客服聊天和工单的所有接口权限
|
||||||
|
('ROLE-0004', 'role_guest', '访客', '访客角色,具备客服聊天和工单的所有接口权限',
|
||||||
|
'global', NULL, true, 'system', NULL, now(), false);
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 3. 初始化系统模块
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO sys.tb_sys_module (
|
||||||
|
optsn, module_id, name, description, creator, dept_path, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
('MODULE-0001', 'module_system', '系统管理', '用户、角色、权限、部门管理', 'system', NULL, now(), false),
|
||||||
|
('MODULE-0002', 'module_file', '文件管理', '文件上传、下载、关联管理', 'system', NULL, now(), false),
|
||||||
|
('MODULE-0003', 'module_message', '消息通知', '消息发送、接收、模板管理', 'system', NULL, now(), false),
|
||||||
|
('MODULE-0004', 'module_config', '配置管理', '系统配置参数管理', 'system', NULL, now(), false),
|
||||||
|
('MODULE-0008', 'module_agent', '智能体', '智能体管理', 'system', NULL, now(), false),
|
||||||
|
('MODULE-0005', 'module_knowledge', '知识库', '知识文档管理', 'system', NULL, now(), false),
|
||||||
|
('MODULE-0006', 'module_bidding', '招投标', '招投标业务管理', 'system', NULL, now(), false),
|
||||||
|
('MODULE-0007', 'module_workcase', '智能客服', '客服工单管理', 'system', NULL, now(), false),
|
||||||
|
('MODULE-0009', 'module_meeting', '视频会议', 'Jitsi Meet视频会议管理', 'system', NULL, now(), false);
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 4. 初始化系统权限
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO sys.tb_sys_permission (
|
||||||
|
optsn, permission_id, name, code, description, module_id, status, creator, dept_path, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
-- 系统管理模块权限
|
||||||
|
('PERM-0001', 'perm_user_view', '用户查看', 'system:user:view', '查看用户列表和详情', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0002', 'perm_user_create', '用户创建', 'system:user:create', '创建新用户', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0003', 'perm_user_edit', '用户编辑', 'system:user:edit', '编辑用户信息', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0004', 'perm_user_delete', '用户删除', 'system:user:delete', '删除用户', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0011', 'perm_role_view', '角色查看', 'system:role:view', '查看角色列表和详情', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0012', 'perm_role_create', '角色创建', 'system:role:create', '创建新角色', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0013', 'perm_role_edit', '角色编辑', 'system:role:edit', '编辑角色信息', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0014', 'perm_role_delete', '角色删除', 'system:role:delete', '删除角色', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0021', 'perm_dept_view', '部门查看', 'system:dept:view', '查看部门列表和详情', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0022', 'perm_dept_create', '部门创建', 'system:dept:create', '创建新部门', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0023', 'perm_dept_edit', '部门编辑', 'system:dept:edit', '编辑部门信息', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0024', 'perm_dept_delete', '部门删除', 'system:dept:delete', '删除部门', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0031', 'perm_permission_view', '权限查看', 'system:permission:view', '查看权限列表', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0032', 'perm_permission_manage', '权限管理', 'system:permission:manage', '管理权限配置', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 系统管理模块导出权限
|
||||||
|
('PERM-0041', 'perm_user_export', '用户导出', 'system:user:export', '导出用户数据', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0042', 'perm_role_export', '角色导出', 'system:role:export', '导出角色数据', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0043', 'perm_dept_export', '部门导出', 'system:dept:export', '导出部门数据', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 文件管理模块权限
|
||||||
|
('PERM-0101', 'perm_file_view', '文件查看', 'file:file:view', '查看文件列表', 'module_file', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0102', 'perm_file_upload', '文件上传', 'file:file:upload', '上传文件', 'module_file', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0103', 'perm_file_download', '文件下载', 'file:file:download', '下载文件', 'module_file', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0104', 'perm_file_delete', '文件删除', 'file:file:delete', '删除文件', 'module_file', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0105', 'perm_file_export', '文件导出', 'file:file:export', '导出文件列表数据', 'module_file', true, 'system', NULL, now(), false),
|
||||||
|
-- 智能体权限
|
||||||
|
('PERM-0120', 'perm_ai_create', '智能体创建', 'ai:agent:create', '创建智能体', 'module_agent', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0121', 'perm_ai_update', '智能体更新', 'ai:agent:update', '更新智能体', 'module_agent', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0122', 'perm_ai_delete', '智能体删除', 'ai:agent:delete', '删除智能体', 'module_agent', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0123', 'perm_ai_view', '智能体查询', 'ai:agent:view', '查询智能体', 'module_agent', true, 'system', NULL, now(), false),
|
||||||
|
-- 智能体对话权限 没有,因为所有人都可以
|
||||||
|
-- Dify代理功能权限(知识库分段管理)
|
||||||
|
('PERM-0130', 'perm_dify_segment_view', '分段查看', 'ai:dify:segment:view', '查看文档分段列表', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0131', 'perm_dify_segment_create', '分段创建', 'ai:dify:segment:create', '创建文档分段', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0132', 'perm_dify_segment_update', '分段更新', 'ai:dify:segment:update', '更新文档分段', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0133', 'perm_dify_segment_delete', '分段删除', 'ai:dify:segment:delete', '删除文档分段', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0134', 'perm_dify_document_status', '文档状态管理', 'ai:dify:document:status', '更新文档状态(启用/禁用/归档)', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
-- 知识库管理权限
|
||||||
|
('PERM-0140', 'perm_knowledge_create', '知识库创建', 'ai:knowledge:create', '创建知识库', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0141', 'perm_knowledge_update', '知识库更新', 'ai:knowledge:update', '更新知识库', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0142', 'perm_knowledge_delete', '知识库删除', 'ai:knowledge:delete', '删除知识库', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0143', 'perm_knowledge_view', '知识库查看', 'ai:knowledge:view', '查看知识库列表和详情', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
-- 知识库文件管理权限
|
||||||
|
('PERM-0150', 'perm_knowledge_file_upload', '知识库文件上传', 'ai:knowledge:file:upload', '上传文件到知识库', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0151', 'perm_knowledge_file_update', '知识库文件更新', 'ai:knowledge:file:update', '更新知识库文件信息', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0152', 'perm_knowledge_file_delete', '知识库文件删除', 'ai:knowledge:file:delete', '删除知识库文件', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0153', 'perm_knowledge_file_view', '知识库文件查看', 'ai:knowledge:file:view', '查看知识库文件历史', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 消息通知模块权限
|
||||||
|
('PERM-0201', 'perm_message_view', '消息查看', 'message:message:view', '查看消息列表', 'module_message', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0202', 'perm_message_send', '消息发送', 'message:message:send', '发送消息通知', 'module_message', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0203', 'perm_message_manage', '消息管理', 'message:message:manage', '管理消息模板和配置', 'module_message', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0204', 'perm_message_export', '消息导出', 'message:message:export', '导出消息数据', 'module_message', true, 'system', NULL, now(), false),
|
||||||
|
-- 配置管理模块权限
|
||||||
|
('PERM-0301', 'perm_config_view', '配置查看', 'config:config:view', '查看系统配置', 'module_config', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0302', 'perm_config_edit', '配置编辑', 'config:config:edit', '修改系统配置', 'module_config', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0303', 'perm_config_export', '配置导出', 'config:config:export', '导出系统配置数据', 'module_config', true, 'system', NULL, now(), false),
|
||||||
|
-- 日志模块权限
|
||||||
|
('PERM-0401', 'perm_log_view', '日志查看', 'log:log:view', '查看系统日志', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0402', 'perm_log_export', '日志导出', 'log:log:export', '导出系统日志数据', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
-- 平台基础菜单访问权限(所有登录用户都有)
|
||||||
|
('PERM-0501', 'perm_platform_home', '工作台访问', 'platform:home:view', '访问平台工作台', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0502', 'perm_platform_chat', 'AI助手访问', 'platform:chat:view', '访问AI助手', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0503', 'perm_platform_bidding', '招标助手访问', 'platform:bidding:view', '访问招标助手(iframe)', 'module_bidding', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0504', 'perm_platform_workcase', '泰豪小电访问', 'platform:workcase:view', '访问泰豪小电客服(iframe)', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0505', 'perm_platform_workflow', '智能体编排访问', 'platform:workflow:view', '访问智能体编排(iframe)', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
-- Platform 管理后台功能权限
|
||||||
|
('PERM-0601', 'perm_platform_admin', '平台管理后台', 'platform:admin:view', '访问平台管理后台', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0602', 'perm_platform_admin_overview', '平台数据概览', 'platform:admin:overview', '访问平台数据概览', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0603', 'perm_platform_admin_user', '平台用户管理', 'platform:admin:user', '访问平台用户管理', 'module_system', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0604', 'perm_platform_admin_knowledge', '平台知识库', 'platform:admin:knowledge', '访问平台知识库', 'module_knowledge', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0605', 'perm_platform_admin_config', '平台系统配置', 'platform:admin:config', '访问平台系统配置', 'module_config', true, 'system', NULL, now(), false),
|
||||||
|
-- Bidding 管理后台功能权限
|
||||||
|
('PERM-0611', 'perm_bidding_admin', '招标管理后台', 'bidding:admin:view', '访问招标管理后台', 'module_bidding', true, 'system', NULL, now(), false),
|
||||||
|
-- Workcase 管理后台功能权限
|
||||||
|
('PERM-0621', 'perm_workcase_admin', '客服管理后台', 'workcase:admin:view', '访问客服管理后台', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0622', 'perm_workcase_overview', '数据概览', 'workcase:overview:view', '访问泰豪小电数据概览', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0623', 'perm_workcase_knowledge', '知识库管理', 'workcase:knowledge:view', '访问知识库管理', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0624', 'perm_workcase_tickets', '工单管理', 'workcase:tickets:view', '访问工单管理', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0625', 'perm_workcase_conversation', '对话数据', 'workcase:conversation:view', '访问对话数据管理', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0626', 'perm_workcase_agent', '智能体管理', 'workcase:agent:view', '访问智能体管理', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0627', 'perm_workcase_log', '日志管理', 'workcase:log:view', '访问日志管理', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0628', 'perm_workcase_chatroom', '聊天室控制台', 'workcase:chatroom:view', '访问聊天室控制台', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- Workcase 接口权限(访客用户可用)
|
||||||
|
-- AI对话接口权限
|
||||||
|
('PERM-0701', 'perm_workcase_chat_create', 'AI对话创建', 'workcase:chat:create', '创建对话', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0702', 'perm_workcase_chat_update', 'AI对话更新', 'workcase:chat:update', '更新对话', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0703', 'perm_workcase_chat_list', 'AI对话查询', 'workcase:chat:list', '查询对话列表', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0704', 'perm_workcase_chat_message', 'AI对话消息', 'workcase:chat:message', '获取对话消息列表', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0705', 'perm_workcase_chat_stream', 'AI流式对话', 'workcase:chat:stream', '流式对话接口', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0706', 'perm_workcase_chat_analyze', 'AI对话分析', 'workcase:chat:analyze', '分析对话生成工单信息', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
-- 聊天室接口权限
|
||||||
|
('PERM-0711', 'perm_workcase_room_create', '聊天室创建', 'workcase:room:create', '创建聊天室', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0712', 'perm_workcase_room_update', '聊天室更新', 'workcase:room:update', '更新聊天室', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0713', 'perm_workcase_room_close', '聊天室关闭', 'workcase:room:close', '关闭聊天室', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0714', 'perm_workcase_room_view', '聊天室查看', 'workcase:room:view', '查看聊天室', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0715', 'perm_workcase_room_member', '聊天室成员', 'workcase:room:member', '管理聊天室成员', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0716', 'perm_workcase_room_message', '聊天室消息', 'workcase:room:message', '发送和查看聊天室消息', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
-- 工单接口权限
|
||||||
|
('PERM-0721', 'perm_workcase_ticket_create', '工单创建', 'workcase:ticket:create', '创建工单', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0722', 'perm_workcase_ticket_update', '工单更新', 'workcase:ticket:update', '更新工单', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0723', 'perm_workcase_ticket_view', '工单查看', 'workcase:ticket:view', '查看工单详情和列表', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0724', 'perm_workcase_ticket_process', '工单处理', 'workcase:ticket:process', '工单处理过程管理', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0725', 'perm_workcase_ticket_device', '工单设备', 'workcase:ticket:device', '工单设备管理', 'module_workcase', true, 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 视频会议模块权限(Jitsi Meet)
|
||||||
|
('PERM-0730', 'perm_meeting_create', '创建会议', 'meeting:create:own', '创建视频会议', 'module_meeting', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0731', 'perm_meeting_join', '加入会议', 'meeting:join:any', '加入视频会议', 'module_meeting', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0732', 'perm_meeting_url', '获取会议链接', 'meeting:url:any', '获取会议加入链接', 'module_meeting', true, 'system', NULL, now(), false),
|
||||||
|
('PERM-0733', 'perm_meeting_token', '获取会议令牌', 'meeting:token:any', '获取会议参与令牌', 'module_meeting', true, 'system', NULL, now(), false);
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 5. 初始化视图(菜单)
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO sys.tb_sys_view (
|
||||||
|
optsn, view_id, name, parent_id, url, component, icon, type,
|
||||||
|
view_type, iframe_url, service, layout, order_num, description,
|
||||||
|
creator, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
-- =========================
|
||||||
|
-- 平台应用菜单 (platform)
|
||||||
|
-- =========================
|
||||||
|
-- 一级菜单 (图标使用 lucide-vue-next)
|
||||||
|
('VIEW-P002', 'view_platform_chat', '泰豪AI助手', NULL, '/aichat', 'public/Chat/AIChatView.vue', 'MessageCircle', 1,
|
||||||
|
'route', NULL, 'platform', 'SidebarLayout', 10, '泰豪AI助手-直接智能体对话', 'system', now(), false),
|
||||||
|
('VIEW-P001', 'view_platform_home', '全部应用', NULL, '/agents', 'public/Agents/AgentPlatformView.vue', 'LayoutGrid', 1,
|
||||||
|
'route', NULL, 'platform', 'SidebarLayout', 20, '全部智能体', 'system', now(), false),
|
||||||
|
-- iframe 嵌入菜单
|
||||||
|
-- url: platform中的路由路径(用于sidebar定位和路由跳转)
|
||||||
|
-- iframe_url: iframe的src地址(实际内容的URL)
|
||||||
|
('VIEW-P005', 'view_platform_workflow', '智能体编排', NULL, '/app/workflow', NULL, 'Workflow', 1,
|
||||||
|
'iframe', 'http://localhost:3000', 'platform', 'SidebarLayout', 30, 'Dify智能体编排(iframe)', 'system', now(), false),
|
||||||
|
('VIEW-P003', 'view_platform_bidding', '招标助手', NULL, '/app/bidding', NULL, 'FileText', 1,
|
||||||
|
'iframe', '/bidding/', 'platform', 'SidebarLayout', 40, '招标应用(iframe)', 'system', now(), false),
|
||||||
|
('VIEW-P004', 'view_platform_workcase', '泰豪小电', NULL, '/app/workcase', NULL, 'Headphones', 1,
|
||||||
|
'iframe', '/workcase/', 'platform', 'SidebarLayout', 50, '客服应用(iframe)', 'system', now(), false),
|
||||||
|
|
||||||
|
|
||||||
|
-- 平台管理后台内部视图(SubSidebarLayout布局,在platform服务内)
|
||||||
|
('VIEW-P201', 'view_platform_admin_overview', '数据概览', NULL, '/admin/overview', 'admin/overview/OverviewView.vue', 'BarChart3', 1,
|
||||||
|
'route', NULL, 'platform', 'SubSidebarLayout', 210, '平台数据概览', 'system', now(), false),
|
||||||
|
('VIEW-P202', 'view_platform_admin_user', '用户管理', NULL, '/admin/userManagement', 'admin/userManagement/UserManagementView.vue', 'Users', 1,
|
||||||
|
'route', NULL, 'platform', 'SubSidebarLayout', 220, '平台用户管理', 'system', now(), false),
|
||||||
|
('VIEW-P203', 'view_platform_admin_knowledge', '知识库', NULL, '/admin/knowledge', 'admin/knowledge/KnowledgeView.vue', 'FileText', 1,
|
||||||
|
'route', NULL, 'platform', 'SubSidebarLayout', 230, '平台知识库管理', 'system', now(), false),
|
||||||
|
('VIEW-P204', 'view_platform_admin_config', '系统配置', NULL, '/admin/config', 'admin/config/ConfigView.vue', 'Settings', 1,
|
||||||
|
'route', NULL, 'platform', 'SubSidebarLayout', 240, '平台系统配置', 'system', now(), false),
|
||||||
|
|
||||||
|
-- -- 系统管理目录
|
||||||
|
-- ('VIEW-P100', 'view_system', '系统管理', NULL, '/system', NULL, 'Settings', 0,
|
||||||
|
-- 'route', NULL, 'platform', 'SidebarLayout', 100, '系统管理目录', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- -- 系统管理子菜单
|
||||||
|
-- ('VIEW-P101', 'view_user', '用户管理', 'view_system', '/system/user', 'system/UserList', 'Users', 1,
|
||||||
|
-- 'route', NULL, 'platform', 'SidebarLayout', 10, '用户管理页面', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- ('VIEW-P102', 'view_role', '角色管理', 'view_system', '/system/role', 'system/RoleList', 'Shield', 1,
|
||||||
|
-- 'route', NULL, 'platform', 'SidebarLayout', 20, '角色管理页面', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- ('VIEW-P103', 'view_dept', '部门管理', 'view_system', '/system/dept', 'system/DeptList', 'Building', 1,
|
||||||
|
-- 'route', NULL, 'platform', 'SidebarLayout', 30, '部门管理页面', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- ('VIEW-P104', 'view_permission', '权限管理', 'view_system', '/system/permission', 'system/PermissionList', 'Lock', 1,
|
||||||
|
-- 'route', NULL, 'platform', 'SidebarLayout', 40, '权限管理页面', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- ('VIEW-P105', 'view_config', '配置管理', 'view_system', '/system/config', 'system/ConfigList', 'Settings', 1,
|
||||||
|
-- 'route', NULL, 'platform', 'SidebarLayout', 50, '配置管理页面', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- ('VIEW-P106', 'view_file', '文件管理', 'view_system', '/system/file', 'system/FileList', 'FileText', 1,
|
||||||
|
-- 'route', NULL, 'platform', 'SidebarLayout', 60, '文件管理页面', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- ('VIEW-P107', 'view_message', '消息管理', 'view_system', '/system/message', 'system/MessageList', 'Mail', 1,
|
||||||
|
-- 'route', NULL, 'platform', 'SidebarLayout', 70, '消息管理页面', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- -- =========================
|
||||||
|
-- -- 招标应用菜单 (bidding)
|
||||||
|
-- -- =========================
|
||||||
|
-- ('VIEW-B001', 'view_bidding_home', '首页', NULL, '/home', 'Home', 'House', 1,
|
||||||
|
-- 'route', NULL, 'bidding', 'DefaultLayout', 10, '招标应用首页', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- ('VIEW-B002', 'view_bidding_list', '招标列表', NULL, '/bidding/list', 'bidding/List', 'List', 1,
|
||||||
|
-- 'route', NULL, 'bidding', 'DefaultLayout', 20, '招标项目列表', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- ('VIEW-B003', 'view_bidding_detail', '招标详情', NULL, '/bidding/detail', 'bidding/Detail', 'Document', 1,
|
||||||
|
-- 'route', NULL, 'bidding', 'DefaultLayout', 30, '招标项目详情', 'system', now(), false),
|
||||||
|
--
|
||||||
|
-- ('VIEW-B004', 'view_bidding_offer', '投标管理', NULL, '/bidding/offer', 'bidding/Offer', 'Edit', 1,
|
||||||
|
-- 'route', NULL, 'bidding', 'DefaultLayout', 40, '投标管理页面', 'system', now(), false),
|
||||||
|
|
||||||
|
-- =========================
|
||||||
|
-- 客服应用菜单 (workcase) - 图标使用 lucide-vue-next
|
||||||
|
-- =========================
|
||||||
|
-- 用户端视图
|
||||||
|
('VIEW-W001', 'view_workcase_home', '智能客服', NULL, '/aichat', 'public/AIChat/AIChatView.vue', 'Home', 1,
|
||||||
|
'route', NULL, 'workcase', 'SubSidebarLayout', 10, '智能客服首页', 'system', now(), false),
|
||||||
|
|
||||||
|
('VIEW-W002', 'view_workcase_chatroom', '聊天室控制台', NULL, '/chatroom', 'public/ChatRoom/ChatRoomView.vue', 'MessageSquare', 1,
|
||||||
|
'route', NULL, 'workcase', 'SubSidebarLayout', 20, '实时聊天室控制台', 'system', now(), false),
|
||||||
|
|
||||||
|
-- 管理端视图(使用 SubSidebarLayout 布局)
|
||||||
|
('VIEW-W101', 'view_workcase_admin_overview', '数据概览', NULL, '/admin/overview', 'admin/overview/OverviewView.vue', 'BarChart3', 1,
|
||||||
|
'route', NULL, 'workcase', 'SubSidebarLayout', 110, '泰豪小电数据概览', 'system', now(), false),
|
||||||
|
|
||||||
|
('VIEW-W102', 'view_workcase_admin_knowledge', '知识库管理', NULL, '/admin/knowledge', 'admin/knowledge/KnowLedgeView.vue', 'FileText', 1,
|
||||||
|
'route', NULL, 'workcase', 'SubSidebarLayout', 120, '知识库文档管理', 'system', now(), false),
|
||||||
|
|
||||||
|
('VIEW-W103', 'view_workcase_admin_tickets', '工单管理', NULL, '/admin/workcase', 'admin/workcase/WorkcaseView.vue', 'Ticket', 1,
|
||||||
|
'route', NULL, 'workcase', 'SubSidebarLayout', 130, '客服工单管理', 'system', now(), false),
|
||||||
|
|
||||||
|
('VIEW-W104', 'view_workcase_admin_conversation', '对话数据', NULL, '/admin/customerChat', 'admin/customerChat/CustomerChatView.vue', 'MessageCircle', 1,
|
||||||
|
'route', NULL, 'workcase', 'SubSidebarLayout', 140, '客户对话数据管理', 'system', now(), false),
|
||||||
|
|
||||||
|
('VIEW-W105', 'view_workcase_admin_agent', '智能体管理', NULL, '/admin/agent', 'admin/agent/AgentView.vue', 'Bot', 1,
|
||||||
|
'route', NULL, 'workcase', 'SubSidebarLayout', 150, '智能体配置管理', 'system', now(), false),
|
||||||
|
|
||||||
|
-- 日志管理(带子级的目录)
|
||||||
|
('VIEW-W106', 'view_workcase_admin_log', '日志管理', NULL, '/admin/log', NULL, 'ScrollText', 1,
|
||||||
|
'route', NULL, 'workcase', 'SubSidebarLayout', 160, '日志管理目录', 'system', now(), false),
|
||||||
|
|
||||||
|
('VIEW-W107', 'view_workcase_admin_log_knowledge', '知识库日志', 'view_workcase_admin_log', '/admin/log/knowledge', 'admin/log/knowledgeLog/KnowledgeLogView.vue', 'FileText', 1,
|
||||||
|
'route', NULL, 'workcase', NULL, 161, '知识库操作日志', 'system', now(), false),
|
||||||
|
|
||||||
|
('VIEW-W108', 'view_workcase_admin_log_workcase', '工单日志', 'view_workcase_admin_log', '/admin/log/workcase', 'admin/log/workcaseLog/WorkcaseLogView.vue', 'Ticket', 1,
|
||||||
|
'route', NULL, 'workcase', NULL, 162, '工单操作日志', 'system', now(), false),
|
||||||
|
|
||||||
|
('VIEW-W109', 'view_workcase_admin_log_system', '系统日志', 'view_workcase_admin_log', '/admin/log/system', 'admin/log/systemLog/SystemLogView.vue', 'Settings', 1,
|
||||||
|
'route', NULL, 'workcase', NULL, 163, '系统运行日志', 'system', now(), false);
|
||||||
|
-- =============================
|
||||||
|
-- 6. 角色权限关联(超级管理员拥有所有权限)
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO sys.tb_sys_role_permission (
|
||||||
|
optsn, role_id, permission_id, creator, dept_path, create_time, deleted
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'RP-' || LPAD(ROW_NUMBER() OVER (ORDER BY permission_id)::TEXT, 4, '0'),
|
||||||
|
'role_super_admin',
|
||||||
|
permission_id,
|
||||||
|
'system',
|
||||||
|
NULL,
|
||||||
|
now(),
|
||||||
|
false
|
||||||
|
FROM sys.tb_sys_permission
|
||||||
|
WHERE deleted = false;
|
||||||
|
|
||||||
|
-- 系统管理员权限(除了用户删除外的系统管理权限 + 所有平台基础菜单)
|
||||||
|
INSERT INTO sys.tb_sys_role_permission (
|
||||||
|
optsn, role_id, permission_id, creator, dept_path, create_time, deleted
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'RP-SA-' || LPAD(ROW_NUMBER() OVER (ORDER BY permission_id)::TEXT, 4, '0'),
|
||||||
|
'role_system_admin',
|
||||||
|
permission_id,
|
||||||
|
'system',
|
||||||
|
NULL,
|
||||||
|
now(),
|
||||||
|
false
|
||||||
|
FROM sys.tb_sys_permission
|
||||||
|
WHERE deleted = false
|
||||||
|
AND code NOT IN ('system:user:delete', 'system:role:delete', 'system:dept:delete')
|
||||||
|
AND (
|
||||||
|
module_id IN ('module_system', 'module_file', 'module_message', 'module_config', 'module_bidding', 'module_workcase')
|
||||||
|
OR code LIKE 'platform:%:view' -- 包含所有平台基础菜单权限
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 普通用户权限(基础查看和文件操作 + 平台基础菜单访问)
|
||||||
|
INSERT INTO sys.tb_sys_role_permission (
|
||||||
|
optsn, role_id, permission_id, creator, dept_path, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
-- 平台基础菜单访问权限
|
||||||
|
('RP-U-0001', 'role_user', 'perm_platform_home', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0002', 'role_user', 'perm_platform_chat', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0003', 'role_user', 'perm_platform_bidding', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0004', 'role_user', 'perm_platform_workcase', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0005', 'role_user', 'perm_platform_workflow', 'system', NULL, now(), false),
|
||||||
|
-- 系统功能权限
|
||||||
|
('RP-U-0011', 'role_user', 'perm_user_view', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0012', 'role_user', 'perm_file_view', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0013', 'role_user', 'perm_file_upload', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0014', 'role_user', 'perm_file_download', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0015', 'role_user', 'perm_message_view', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0016', 'role_user', 'perm_config_view', 'system', NULL, now(), false),
|
||||||
|
--- 视频会议权限
|
||||||
|
('RP-U-0050', 'role_user', 'perm_meeting_create', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0051', 'role_user', 'perm_meeting_join', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0052', 'role_user', 'perm_meeting_url', 'system', NULL, now(), false),
|
||||||
|
('RP-U-0053', 'role_user', 'perm_meeting_token', 'system', NULL, now(), false);
|
||||||
|
|
||||||
|
-- 访客权限(基础菜单 + workcase聊天和工单全部接口权限)
|
||||||
|
INSERT INTO sys.tb_sys_role_permission (
|
||||||
|
optsn, role_id, permission_id, creator, dept_path, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
-- 平台基础菜单访问权限
|
||||||
|
('RP-G-0001', 'role_guest', 'perm_platform_home', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0002', 'role_guest', 'perm_platform_chat', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0003', 'role_guest', 'perm_platform_workcase', 'system', NULL, now(), false),
|
||||||
|
-- 系统功能权限(仅查看)
|
||||||
|
('RP-G-0011', 'role_guest', 'perm_user_view', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0012', 'role_guest', 'perm_file_view', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0013', 'role_guest', 'perm_message_view', 'system', NULL, now(), false),
|
||||||
|
-- Workcase AI对话接口权限
|
||||||
|
('RP-G-0021', 'role_guest', 'perm_workcase_chat_create', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0022', 'role_guest', 'perm_workcase_chat_update', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0023', 'role_guest', 'perm_workcase_chat_list', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0024', 'role_guest', 'perm_workcase_chat_message', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0025', 'role_guest', 'perm_workcase_chat_stream', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0026', 'role_guest', 'perm_workcase_chat_analyze', 'system', NULL, now(), false),
|
||||||
|
-- Workcase 聊天室接口权限
|
||||||
|
('RP-G-0031', 'role_guest', 'perm_workcase_room_create', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0032', 'role_guest', 'perm_workcase_room_update', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0033', 'role_guest', 'perm_workcase_room_close', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0034', 'role_guest', 'perm_workcase_room_view', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0035', 'role_guest', 'perm_workcase_room_member', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0036', 'role_guest', 'perm_workcase_room_message', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0037', 'role_guest', 'perm_workcase_chatroom', 'system', NULL, now(), false),
|
||||||
|
-- Workcase 工单接口权限
|
||||||
|
('RP-G-0041', 'role_guest', 'perm_workcase_ticket_create', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0042', 'role_guest', 'perm_workcase_ticket_update', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0043', 'role_guest', 'perm_workcase_ticket_view', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0044', 'role_guest', 'perm_workcase_ticket_process', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0045', 'role_guest', 'perm_workcase_ticket_device', 'system', NULL, now(), false),
|
||||||
|
--- 视频会议权限
|
||||||
|
('RP-G-0050', 'role_guest', 'perm_meeting_create', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0051', 'role_guest', 'perm_meeting_join', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0052', 'role_guest', 'perm_meeting_url', 'system', NULL, now(), false),
|
||||||
|
('RP-G-0053', 'role_guest', 'perm_meeting_token', 'system', NULL, now(), false);
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 7. 视图权限关联
|
||||||
|
-- =============================
|
||||||
|
-- 将视图与对应模块的权限关联(使用真正的 view_id,不是 optsn)
|
||||||
|
INSERT INTO sys.tb_sys_view_permission (
|
||||||
|
optsn, view_id, permission_id, creator, dept_path, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
-- 平台基础菜单权限关联(所有登录用户都可访问)
|
||||||
|
('VP-P001', 'view_platform_home', 'perm_platform_home', 'system', NULL, now(), false),
|
||||||
|
('VP-P002', 'view_platform_chat', 'perm_platform_chat', 'system', NULL, now(), false),
|
||||||
|
('VP-P003', 'view_platform_bidding', 'perm_platform_bidding', 'system', NULL, now(), false),
|
||||||
|
('VP-P004', 'view_platform_workcase', 'perm_platform_workcase', 'system', NULL, now(), false),
|
||||||
|
('VP-P005', 'view_platform_workflow', 'perm_platform_workflow', 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 管理后台入口权限关联(iframe入口)
|
||||||
|
('VP-P101', 'view_platform_admin_entry', 'perm_platform_admin', 'system', NULL, now(), false),
|
||||||
|
('VP-P102', 'view_bidding_admin_entry', 'perm_bidding_admin', 'system', NULL, now(), false),
|
||||||
|
('VP-P103', 'view_workcase_admin_entry', 'perm_workcase_admin', 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 平台管理后台内部视图权限关联(SubSidebarLayout)
|
||||||
|
('VP-P201', 'view_platform_admin_overview', 'perm_platform_admin_overview', 'system', NULL, now(), false),
|
||||||
|
('VP-P202', 'view_platform_admin_user', 'perm_platform_admin_user', 'system', NULL, now(), false),
|
||||||
|
('VP-P203', 'view_platform_admin_knowledge', 'perm_platform_admin_knowledge', 'system', NULL, now(), false),
|
||||||
|
('VP-P204', 'view_platform_admin_config', 'perm_platform_admin_config', 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- Workcase服务用户端视图关联
|
||||||
|
('VP-W001', 'view_workcase_home', 'perm_platform_workcase', 'system', NULL, now(), false),
|
||||||
|
('VP-W002', 'view_workcase_chatroom', 'perm_workcase_chatroom', 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- Workcase服务管理端视图关联
|
||||||
|
('VP-W101', 'view_workcase_admin_overview', 'perm_workcase_overview', 'system', NULL, now(), false),
|
||||||
|
('VP-W102', 'view_workcase_admin_knowledge', 'perm_workcase_knowledge', 'system', NULL, now(), false),
|
||||||
|
('VP-W103', 'view_workcase_admin_tickets', 'perm_workcase_tickets', 'system', NULL, now(), false),
|
||||||
|
('VP-W104', 'view_workcase_admin_conversation', 'perm_workcase_conversation', 'system', NULL, now(), false),
|
||||||
|
('VP-W105', 'view_workcase_admin_agent', 'perm_workcase_agent', 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- 日志管理视图关联(包括父级和子级)
|
||||||
|
('VP-W106', 'view_workcase_admin_log', 'perm_workcase_log', 'system', NULL, now(), false),
|
||||||
|
('VP-W107', 'view_workcase_admin_log_knowledge', 'perm_workcase_log', 'system', NULL, now(), false),
|
||||||
|
('VP-W108', 'view_workcase_admin_log_workcase', 'perm_workcase_log', 'system', NULL, now(), false),
|
||||||
|
('VP-W109', 'view_workcase_admin_log_system', 'perm_workcase_log', 'system', NULL, now(), false),
|
||||||
|
|
||||||
|
-- -- 用户管理视图关联用户权限(已注释,因为view_user被注释掉了)
|
||||||
|
-- -- ('VP-0001', 'view_user', 'perm_user_view', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0002', 'view_user', 'perm_user_create', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0003', 'view_user', 'perm_user_edit', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0004', 'view_user', 'perm_user_delete', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0005', 'view_user', 'perm_user_export', 'system', NULL, now(), false),
|
||||||
|
-- --
|
||||||
|
-- -- -- 角色管理视图关联角色权限
|
||||||
|
-- -- ('VP-0011', 'view_role', 'perm_role_view', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0012', 'view_role', 'perm_role_create', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0013', 'view_role', 'perm_role_edit', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0014', 'view_role', 'perm_role_delete', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0015', 'view_role', 'perm_role_export', 'system', NULL, now(), false),
|
||||||
|
-- --
|
||||||
|
-- -- -- 部门管理视图关联部门权限
|
||||||
|
-- -- ('VP-0021', 'view_dept', 'perm_dept_view', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0022', 'view_dept', 'perm_dept_create', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0023', 'view_dept', 'perm_dept_edit', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0024', 'view_dept', 'perm_dept_delete', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0025', 'view_dept', 'perm_dept_export', 'system', NULL, now(), false),
|
||||||
|
-- --
|
||||||
|
-- -- -- 权限管理视图关联权限管理权限
|
||||||
|
-- -- ('VP-0031', 'view_permission', 'perm_permission_view', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0032', 'view_permission', 'perm_permission_manage', 'system', NULL, now(), false),
|
||||||
|
-- --
|
||||||
|
-- -- -- 配置管理视图关联配置权限
|
||||||
|
-- -- ('VP-0041', 'view_config', 'perm_config_view', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0042', 'view_config', 'perm_config_edit', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0043', 'view_config', 'perm_config_export', 'system', NULL, now(), false),
|
||||||
|
-- --
|
||||||
|
-- -- -- 文件管理视图关联文件权限
|
||||||
|
-- -- ('VP-0051', 'view_file', 'perm_file_view', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0052', 'view_file', 'perm_file_upload', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0053', 'view_file', 'perm_file_download', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0054', 'view_file', 'perm_file_delete', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0055', 'view_file', 'perm_file_export', 'system', NULL, now(), false),
|
||||||
|
-- --
|
||||||
|
-- -- -- 消息管理视图关联消息权限
|
||||||
|
-- -- ('VP-0061', 'view_message', 'perm_message_view', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0062', 'view_message', 'perm_message_send', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0063', 'view_message', 'perm_message_manage', 'system', NULL, now(), false),
|
||||||
|
-- -- ('VP-0064', 'view_message', 'perm_message_export', 'system', NULL, now(), false);
|
||||||
64
docker/urbanLifeline/postgres/init/sql/initDataUser.sql
Normal file
64
docker/urbanLifeline/postgres/init/sql/initDataUser.sql
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
-- 初始化用户数据(与 sys schema 对应)
|
||||||
|
-- 创建系统管理员账户和示例用户
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 1. 创建超级管理员用户
|
||||||
|
-- =============================
|
||||||
|
-- 注意:密码需要使用 bcrypt 加密,这里使用的是 'admin123' 的 bcrypt hash
|
||||||
|
-- 实际部署时应该修改为安全的密码
|
||||||
|
INSERT INTO sys.tb_sys_user (
|
||||||
|
optsn, user_id, usercode, password, email, phone, phone_hash,
|
||||||
|
create_time, status, deleted
|
||||||
|
) VALUES
|
||||||
|
('USER-0001', 'user_admin', 'admin',
|
||||||
|
'$2a$10$XAe0TE2p0ym94bKJ8LJ52el3M4oYyiExVH/kNCh.pWLLGDZWNM9Yu', -- admin123
|
||||||
|
'admin@urbanlifeline.com', 'DAWTIvnCQI/KmtwkBYI5WP2NpnSKTq4kStJpOJKahOeJLNhAQ0s1', '7503bbfc6171077b737cdc4f76e781893a9a474c9ead05b6b946ac936e5a0288',
|
||||||
|
now(), 0, false);
|
||||||
|
|
||||||
|
-- 超级管理员用户信息
|
||||||
|
INSERT INTO sys.tb_sys_user_info (
|
||||||
|
optsn, user_id, username, avatar, gender, level, remark,
|
||||||
|
create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
('UINFO-0001', 'user_admin', '系统管理员',
|
||||||
|
'/static/avatar/admin.png', 1, 10, '系统超级管理员账户',
|
||||||
|
now(), false);
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 2. 关联超级管理员角色
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO sys.tb_sys_user_role (
|
||||||
|
optsn, user_id, role_id, dept_id, dept_path,
|
||||||
|
creator, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
('UR-0001', 'user_admin', 'role_super_admin', 'dept_root', '/dept_root/',
|
||||||
|
'system', now(), false);
|
||||||
|
|
||||||
|
-- =============================
|
||||||
|
-- 3. 创建示例普通用户(可选)
|
||||||
|
-- =============================
|
||||||
|
INSERT INTO sys.tb_sys_user (
|
||||||
|
optsn, user_id, usercode, password, email, phone, phone_hash,
|
||||||
|
create_time, status, deleted
|
||||||
|
) VALUES
|
||||||
|
('USER-0002', 'user_demo', 'demo',
|
||||||
|
'$2a$10$XAe0TE2p0ym94bKJ8LJ52el3M4oYyiExVH/kNCh.pWLLGDZWNM9Yu', -- admin123
|
||||||
|
'demo@urbanlifeline.com', 'Y9tsAZOppzsxmKvI7iqqRBMDHzvWym2DE5FX1KgEGVBC5Ii1UG68', '4e98ffd0e02a7f746291bff77c6c497225e8884758d503bde2efad64e45ad44b',
|
||||||
|
now(), 0, false);
|
||||||
|
|
||||||
|
-- 示例用户信息
|
||||||
|
INSERT INTO sys.tb_sys_user_info (
|
||||||
|
optsn, user_id, username, avatar, gender, level, remark,
|
||||||
|
create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
('UINFO-0002', 'user_demo', '演示用户',
|
||||||
|
'/static/avatar/demo.png', 0, 1, '系统演示账户',
|
||||||
|
now(), false);
|
||||||
|
|
||||||
|
-- 关联普通用户角色
|
||||||
|
INSERT INTO sys.tb_sys_user_role (
|
||||||
|
optsn, user_id, role_id, dept_id, dept_path,
|
||||||
|
creator, create_time, deleted
|
||||||
|
) VALUES
|
||||||
|
('UR-0002', 'user_demo', 'role_user', 'dept_root', '/dept_root/',
|
||||||
|
'system', now(), false);
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- 初始化聊天室人员
|
||||||
|
-- user_admin
|
||||||
|
INSERT INTO workcase.tb_chat_room_member(
|
||||||
|
optsn, member_id, room_id, user_id, user_type, user_name, status, unread_count, last_read_time, last_read_msg_id, join_time, leave_time, creator, create_time, update_time
|
||||||
|
) VALUES
|
||||||
|
('MEM-0001', 'member_admin', 'room_0001', 'user_admin', 'staff', '系统管理员', 'active', 0, null, null, now(), null, 'system', now(), null);
|
||||||
39
docker/urbanLifeline/serv/.env.example
Normal file
39
docker/urbanLifeline/serv/.env.example
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# ================================================
|
||||||
|
# Urban Lifeline 后端服务配置
|
||||||
|
# 复制此文件为 .env 并修改配置
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# 镜像版本
|
||||||
|
# ------------------------------
|
||||||
|
IMAGE_VERSION=latest
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# 端口配置
|
||||||
|
# ------------------------------
|
||||||
|
GATEWAY_PORT=8080
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# Spring 配置
|
||||||
|
# ------------------------------
|
||||||
|
SPRING_PROFILES_ACTIVE=prod
|
||||||
|
NACOS_SERVER_ADDR=nacos:8848
|
||||||
|
NACOS_NAMESPACE=
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# 挂载目录配置
|
||||||
|
# ------------------------------
|
||||||
|
# 配置文件目录 (存放各服务的 yml 配置)
|
||||||
|
CONFIG_ROOT=./volumes/config
|
||||||
|
|
||||||
|
# 日志目录
|
||||||
|
LOG_ROOT=./volumes/logs
|
||||||
|
|
||||||
|
# 数据目录 (上传文件、临时文件等)
|
||||||
|
DATA_ROOT=./volumes/data
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# 资源限制
|
||||||
|
# ------------------------------
|
||||||
|
MEMORY_LIMIT=4G
|
||||||
|
MEMORY_RESERVATION=2G
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# ================================================
|
||||||
|
# Urban Lifeline - All-in-One 后端服务镜像
|
||||||
|
# 单容器运行所有微服务,通过脚本管理
|
||||||
|
#
|
||||||
|
# 构建: docker build -t urban-lifeline-serv:latest -f Dockerfile.serv .
|
||||||
|
# ================================================
|
||||||
|
FROM urban-lifeline-base-serv:latest
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
RUN mkdir -p /app/jars /app/logs /app/pids /app/config
|
||||||
|
|
||||||
|
# 复制管理脚本
|
||||||
|
COPY docker/urbanLifeline/serv/service-manager.sh /app/service-manager.sh
|
||||||
|
RUN chmod +x /app/service-manager.sh
|
||||||
|
|
||||||
|
# 复制所有服务 JAR 包
|
||||||
|
COPY urbanLifelineServ/gateway/target/*.jar /app/jars/gateway.jar
|
||||||
|
COPY urbanLifelineServ/system/target/*.jar /app/jars/system.jar
|
||||||
|
COPY urbanLifelineServ/auth/target/*.jar /app/jars/auth.jar
|
||||||
|
COPY urbanLifelineServ/file/target/*.jar /app/jars/file.jar
|
||||||
|
COPY urbanLifelineServ/log/target/*.jar /app/jars/log.jar
|
||||||
|
COPY urbanLifelineServ/message/target/*.jar /app/jars/message.jar
|
||||||
|
COPY urbanLifelineServ/crontab/target/*.jar /app/jars/crontab.jar
|
||||||
|
COPY urbanLifelineServ/ai/target/*.jar /app/jars/ai.jar
|
||||||
|
COPY urbanLifelineServ/bidding/target/*.jar /app/jars/bidding.jar
|
||||||
|
COPY urbanLifelineServ/platform/target/*.jar /app/jars/platform.jar
|
||||||
|
COPY urbanLifelineServ/workcase/target/*.jar /app/jars/workcase.jar
|
||||||
|
|
||||||
|
# 配置目录 (可外挂)
|
||||||
|
VOLUME ["/app/config", "/app/logs"]
|
||||||
|
|
||||||
|
EXPOSE 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=180s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:8080/actuator/health || exit 1
|
||||||
|
|
||||||
|
ENTRYPOINT ["/app/service-manager.sh"]
|
||||||
|
CMD ["start-all"]
|
||||||
|
|||||||
41
docker/urbanLifeline/serv/config/application-ai.yml
Normal file
41
docker/urbanLifeline/serv/config/application-ai.yml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# ================== AI 服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8090
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: ai-service
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
enabled: true
|
||||||
|
max-file-size: 500MB
|
||||||
|
max-request-size: 500MB
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: true
|
||||||
|
gateway-mode: true
|
||||||
|
whitelist:
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /swagger-ui.html
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
- /ai/chat/**
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
display-name: 'AI代理服务 API'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: urban-lifeline-agent
|
||||||
|
qos-enable: false
|
||||||
|
protocol:
|
||||||
|
payload: 110100480
|
||||||
|
scan:
|
||||||
|
base-packages: org.xyzh.ai.service.impl
|
||||||
31
docker/urbanLifeline/serv/config/application-auth.yml
Normal file
31
docker/urbanLifeline/serv/config/application-auth.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# ================== Auth 认证服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: auth-service
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: false
|
||||||
|
gateway-mode: false
|
||||||
|
whitelist:
|
||||||
|
- /**
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
display-name: '认证服务 API'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: urban-lifeline-auth
|
||||||
|
qos-enable: false
|
||||||
|
scan:
|
||||||
|
base-packages: org.xyzh.auth.service.impl
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
secret: ${JWT_SECRET:urban-lifeline-secret-key-2025-xyzh}
|
||||||
|
expiration: 86400
|
||||||
|
refresh-expiration: 604800
|
||||||
33
docker/urbanLifeline/serv/config/application-bidding.yml
Normal file
33
docker/urbanLifeline/serv/config/application-bidding.yml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# ================== Bidding 招投标服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8087
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: bidding-service
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: true
|
||||||
|
gateway-mode: true
|
||||||
|
whitelist:
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /swagger-ui.html
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
display-name: '招投标服务 API'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: urban-lifeline-bidding
|
||||||
|
qos-enable: false
|
||||||
|
scan:
|
||||||
|
base-packages: org.xyzh.bidding.service.impl
|
||||||
32
docker/urbanLifeline/serv/config/application-crontab.yml
Normal file
32
docker/urbanLifeline/serv/config/application-crontab.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# ================== Crontab 定时任务服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8086
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: crontab-service
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: false
|
||||||
|
whitelist:
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /swagger-ui.html
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
display-name: '定时任务服务 API'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: urban-lifeline-crontab
|
||||||
|
qos-enable: false
|
||||||
|
scan:
|
||||||
|
base-packages: org.xyzh.crontab.service.impl
|
||||||
41
docker/urbanLifeline/serv/config/application-file.yml
Normal file
41
docker/urbanLifeline/serv/config/application-file.yml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# ================== File 文件服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8084
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: file-service
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
enabled: true
|
||||||
|
max-file-size: 500MB
|
||||||
|
max-request-size: 500MB
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: true
|
||||||
|
gateway-mode: true
|
||||||
|
whitelist:
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /swagger-ui.html
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
- /file/download/**
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
display-name: '文件服务 API'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: urban-lifeline-file
|
||||||
|
qos-enable: false
|
||||||
|
protocol:
|
||||||
|
payload: 110100480
|
||||||
|
scan:
|
||||||
|
base-packages: org.xyzh.file.service.impl
|
||||||
154
docker/urbanLifeline/serv/config/application-gateway.yml
Normal file
154
docker/urbanLifeline/serv/config/application-gateway.yml
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
# ================== Gateway 服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: gateway-service
|
||||||
|
|
||||||
|
main:
|
||||||
|
web-application-type: reactive
|
||||||
|
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
config:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
gateway:
|
||||||
|
discovery:
|
||||||
|
locator:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
routes:
|
||||||
|
- id: auth-service
|
||||||
|
uri: lb://auth-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/auth/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
- name: RequestRateLimiter
|
||||||
|
args:
|
||||||
|
redis-rate-limiter.replenishRate: 100
|
||||||
|
redis-rate-limiter.burstCapacity: 200
|
||||||
|
|
||||||
|
- id: system-service
|
||||||
|
uri: lb://system-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/system/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
- id: log-service
|
||||||
|
uri: lb://log-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/log/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
- id: file-service
|
||||||
|
uri: lb://file-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/file/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
- id: message-service
|
||||||
|
uri: lb://message-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/message/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
- id: bidding-service
|
||||||
|
uri: lb://bidding-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/bidding/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
- id: platform-service
|
||||||
|
uri: lb://platform-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/platform/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
- id: workcase-websocket
|
||||||
|
uri: lb:ws://workcase-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/workcase/ws/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
- id: workcase-service
|
||||||
|
uri: lb://workcase-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/workcase/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
- id: crontab-service
|
||||||
|
uri: lb://crontab-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/crontab/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
- id: ai-service
|
||||||
|
uri: lb://ai-service
|
||||||
|
predicates:
|
||||||
|
- Path=/urban-lifeline/ai/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
|
||||||
|
globalcors:
|
||||||
|
cors-configurations:
|
||||||
|
'[/**]':
|
||||||
|
allowedOriginPatterns: "*"
|
||||||
|
allowedMethods: [GET, POST, PUT, DELETE, OPTIONS]
|
||||||
|
allowedHeaders: "*"
|
||||||
|
allowCredentials: true
|
||||||
|
maxAge: 3600
|
||||||
|
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
timeout: 5000ms
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: 20
|
||||||
|
max-wait: -1ms
|
||||||
|
max-idle: 10
|
||||||
|
min-idle: 5
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: true
|
||||||
|
token-header: Authorization
|
||||||
|
token-prefix: "Bearer "
|
||||||
|
login-path: /urban-lifeline/auth/login
|
||||||
|
logout-path: /urban-lifeline/auth/logout
|
||||||
|
captcha-path: /urban-lifeline/auth/captcha
|
||||||
|
refresh-path: /urban-lifeline/auth/refresh
|
||||||
|
whitelist:
|
||||||
|
- /actuator/**
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /swagger-resources/**
|
||||||
|
- /webjars/**
|
||||||
|
- /doc.html
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /urban-lifeline/*/v3/api-docs/**
|
||||||
|
- /urban-lifeline/*/swagger-ui/**
|
||||||
|
- /urban-lifeline/file/download/**
|
||||||
|
- /urban-lifeline/ai/chat/**
|
||||||
|
- /urban-lifeline/system/guest/identify
|
||||||
|
- /urban-lifeline/workcase/meeting/*/entry
|
||||||
|
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include: health,info,gateway
|
||||||
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: always
|
||||||
33
docker/urbanLifeline/serv/config/application-message.yml
Normal file
33
docker/urbanLifeline/serv/config/application-message.yml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# ================== Message 消息服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8085
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: message-service
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: true
|
||||||
|
gateway-mode: true
|
||||||
|
whitelist:
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /swagger-ui.html
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
display-name: '消息服务 API'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: urban-lifeline-message
|
||||||
|
qos-enable: false
|
||||||
|
scan:
|
||||||
|
base-packages: org.xyzh.message.service.impl
|
||||||
33
docker/urbanLifeline/serv/config/application-platform.yml
Normal file
33
docker/urbanLifeline/serv/config/application-platform.yml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# ================== Platform 平台服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8089
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: platform-service
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: true
|
||||||
|
gateway-mode: true
|
||||||
|
whitelist:
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /swagger-ui.html
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
display-name: '平台服务 API'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: urban-lifeline-platform
|
||||||
|
qos-enable: false
|
||||||
|
scan:
|
||||||
|
base-packages: org.xyzh.platform.service.impl
|
||||||
41
docker/urbanLifeline/serv/config/application-system.yml
Normal file
41
docker/urbanLifeline/serv/config/application-system.yml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# ================== System 系统服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8082
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: system-service
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: true
|
||||||
|
gateway-mode: true
|
||||||
|
whitelist:
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /swagger-ui.html
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
- /system/guest/identify
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
swagger-ui:
|
||||||
|
try-it-out-enabled: true
|
||||||
|
show-common-extensions: true
|
||||||
|
show-extensions: true
|
||||||
|
filter: true
|
||||||
|
tags-sorter: alpha
|
||||||
|
operations-sorter: alpha
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
display-name: '系统服务 API'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: urban-lifeline-system
|
||||||
|
qos-enable: false
|
||||||
|
scan:
|
||||||
|
base-packages: org.xyzh.system.service.impl
|
||||||
51
docker/urbanLifeline/serv/config/application-workcase.yml
Normal file
51
docker/urbanLifeline/serv/config/application-workcase.yml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# ================== Workcase 工单服务配置 (Docker) ==================
|
||||||
|
server:
|
||||||
|
port: 8088
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: workcase-service
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
enabled: true
|
||||||
|
max-file-size: 500MB
|
||||||
|
max-request-size: 500MB
|
||||||
|
|
||||||
|
auth:
|
||||||
|
enabled: true
|
||||||
|
gateway-mode: true
|
||||||
|
whitelist:
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /swagger-ui.html
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
- /workcase/chat/kefu/callback
|
||||||
|
- /workcase/receive/crm
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
display-name: '工单服务 API'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: urban-lifeline-workcase
|
||||||
|
qos-enable: false
|
||||||
|
protocol:
|
||||||
|
payload: 110100480
|
||||||
|
scan:
|
||||||
|
base-packages: org.xyzh.workcase.service.impl
|
||||||
|
|
||||||
|
jitsi:
|
||||||
|
app:
|
||||||
|
id: ${JITSI_APP_ID:urbanLifeline}
|
||||||
|
secret: ${JITSI_APP_SECRET:urbanLifeline-jitsi-secret-key-2025-production-safe-hs256}
|
||||||
|
server:
|
||||||
|
url: ${JITSI_SERVER_URL:https://meet.example.com}
|
||||||
|
token:
|
||||||
|
expiration: 7200000
|
||||||
62
docker/urbanLifeline/serv/config/bootstrap.yml
Normal file
62
docker/urbanLifeline/serv/config/bootstrap.yml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# ================================================
|
||||||
|
# Urban Lifeline - 通用 Bootstrap 配置 (Docker)
|
||||||
|
# 所有微服务共享的基础配置
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
# ================== Spring Cloud Nacos ==================
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:nacos:8848}
|
||||||
|
namespace: ${NACOS_NAMESPACE:}
|
||||||
|
group: ${NACOS_GROUP:DEFAULT_GROUP}
|
||||||
|
|
||||||
|
# ================== DataSource ==================
|
||||||
|
datasource:
|
||||||
|
url: ${DB_URL:jdbc:postgresql://postgres:5432/urban_lifeline}
|
||||||
|
username: ${DB_USERNAME:postgres}
|
||||||
|
password: ${DB_PASSWORD:postgres}
|
||||||
|
driver-class-name: org.postgresql.Driver
|
||||||
|
|
||||||
|
# ================== Redis ==================
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: ${REDIS_HOST:redis}
|
||||||
|
port: ${REDIS_PORT:6379}
|
||||||
|
database: ${REDIS_DATABASE:0}
|
||||||
|
password: ${REDIS_PASSWORD:}
|
||||||
|
|
||||||
|
# ================== Security AES ==================
|
||||||
|
security:
|
||||||
|
aes:
|
||||||
|
secret-key: ${AES_SECRET_KEY:MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=}
|
||||||
|
|
||||||
|
# ================== Dubbo ==================
|
||||||
|
dubbo:
|
||||||
|
protocol:
|
||||||
|
name: dubbo
|
||||||
|
port: -1
|
||||||
|
registry:
|
||||||
|
address: nacos://${NACOS_SERVER_ADDR:nacos:8848}
|
||||||
|
|
||||||
|
# ================== MyBatis-Plus ==================
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath:mapper/**/*.xml
|
||||||
|
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
||||||
|
|
||||||
|
# ================== SpringDoc 基础配置 ==================
|
||||||
|
springdoc:
|
||||||
|
api-docs:
|
||||||
|
enabled: true
|
||||||
|
path: /v3/api-docs
|
||||||
|
swagger-ui:
|
||||||
|
enabled: true
|
||||||
|
path: /swagger-ui.html
|
||||||
|
|
||||||
|
# ================== Logging ==================
|
||||||
|
logging:
|
||||||
|
config: classpath:log4j2.xml
|
||||||
|
charset:
|
||||||
|
console: UTF-8
|
||||||
|
file: UTF-8
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# ================================================
|
# ================================================
|
||||||
# Urban Lifeline - All-in-One 部署
|
# Urban Lifeline - All-in-One 后端部署
|
||||||
# 单容器运行所有后端服务
|
# 单容器运行所有后端服务
|
||||||
# ================================================
|
# ================================================
|
||||||
|
|
||||||
@@ -8,34 +8,30 @@ services:
|
|||||||
image: urban-lifeline-serv:${IMAGE_VERSION:-latest}
|
image: urban-lifeline-serv:${IMAGE_VERSION:-latest}
|
||||||
container_name: urban-lifeline-serv
|
container_name: urban-lifeline-serv
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
networks:
|
networks:
|
||||||
- urban-lifeline
|
- urban-lifeline
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080" # gateway
|
- "${GATEWAY_PORT:-8080}:8080"
|
||||||
- "8081:8081" # auth
|
|
||||||
- "8082:8082" # system
|
|
||||||
- "8083:8083" # log
|
|
||||||
- "8084:8084" # file
|
|
||||||
- "8085:8085" # message
|
|
||||||
- "8086:8086" # crontab
|
|
||||||
- "8087:8087" # bidding
|
|
||||||
- "8088:8088" # workcase
|
|
||||||
- "8089:8089" # platform
|
|
||||||
- "8090:8090" # ai
|
|
||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
|
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
|
||||||
NACOS_SERVER_ADDR: ${NACOS_SERVER_ADDR:-nacos:8848}
|
NACOS_SERVER_ADDR: ${NACOS_SERVER_ADDR:-nacos:8848}
|
||||||
NACOS_NAMESPACE: ${NACOS_NAMESPACE:-}
|
NACOS_NAMESPACE: ${NACOS_NAMESPACE:-}
|
||||||
volumes:
|
volumes:
|
||||||
- ${LOG_ROOT:-../../volumes/logs}:/app/logs
|
# 配置文件目录
|
||||||
# 内存限制 (根据服务器配置调整)
|
- ${CONFIG_ROOT:-./volumes/config}:/app/config:ro
|
||||||
|
# 日志目录
|
||||||
|
- ${LOG_ROOT:-./volumes/logs}:/app/logs
|
||||||
|
# 数据目录 (上传文件等)
|
||||||
|
- ${DATA_ROOT:-./volumes/data}:/app/data
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
memory: 4G
|
memory: ${MEMORY_LIMIT:-4G}
|
||||||
reservations:
|
reservations:
|
||||||
memory: 2G
|
memory: ${MEMORY_RESERVATION:-2G}
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
|
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
@@ -45,4 +41,4 @@ services:
|
|||||||
|
|
||||||
networks:
|
networks:
|
||||||
urban-lifeline:
|
urban-lifeline:
|
||||||
external: true
|
name: urban-lifeline
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ set -e
|
|||||||
JAR_DIR="/app/jars"
|
JAR_DIR="/app/jars"
|
||||||
LOG_DIR="/app/logs"
|
LOG_DIR="/app/logs"
|
||||||
PID_DIR="/app/pids"
|
PID_DIR="/app/pids"
|
||||||
|
CONFIG_DIR="/app/config"
|
||||||
|
|
||||||
# 服务配置: 服务名=端口:内存
|
# 服务配置: 服务名=端口:内存
|
||||||
declare -A SERVICES=(
|
declare -A SERVICES=(
|
||||||
@@ -98,6 +99,8 @@ start_service() {
|
|||||||
local jar_file="${JAR_DIR}/${service}.jar"
|
local jar_file="${JAR_DIR}/${service}.jar"
|
||||||
local log_file="${LOG_DIR}/${service}.log"
|
local log_file="${LOG_DIR}/${service}.log"
|
||||||
local pid_file="${PID_DIR}/${service}.pid"
|
local pid_file="${PID_DIR}/${service}.pid"
|
||||||
|
local bootstrap_file="${CONFIG_DIR}/bootstrap.yml"
|
||||||
|
local app_config_file="${CONFIG_DIR}/application-${service}.yml"
|
||||||
|
|
||||||
if [ ! -f "$jar_file" ]; then
|
if [ ! -f "$jar_file" ]; then
|
||||||
log_error "JAR 文件不存在: $jar_file"
|
log_error "JAR 文件不存在: $jar_file"
|
||||||
@@ -127,6 +130,24 @@ start_service() {
|
|||||||
java_opts="$java_opts -Dspring.cloud.nacos.config.namespace=$NACOS_NAMESPACE"
|
java_opts="$java_opts -Dspring.cloud.nacos.config.namespace=$NACOS_NAMESPACE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 外挂配置文件: bootstrap.yml + application-{service}.yml
|
||||||
|
local config_locations=""
|
||||||
|
if [ -f "$bootstrap_file" ]; then
|
||||||
|
config_locations="file:${bootstrap_file}"
|
||||||
|
log_info " 加载通用配置: ${bootstrap_file}"
|
||||||
|
fi
|
||||||
|
if [ -f "$app_config_file" ]; then
|
||||||
|
if [ -n "$config_locations" ]; then
|
||||||
|
config_locations="${config_locations},file:${app_config_file}"
|
||||||
|
else
|
||||||
|
config_locations="file:${app_config_file}"
|
||||||
|
fi
|
||||||
|
log_info " 加载服务配置: ${app_config_file}"
|
||||||
|
fi
|
||||||
|
if [ -n "$config_locations" ]; then
|
||||||
|
java_opts="$java_opts -Dspring.config.additional-location=${config_locations}"
|
||||||
|
fi
|
||||||
|
|
||||||
# 启动服务
|
# 启动服务
|
||||||
nohup java $java_opts -jar "$jar_file" > "$log_file" 2>&1 &
|
nohup java $java_opts -jar "$jar_file" > "$log_file" 2>&1 &
|
||||||
local pid=$!
|
local pid=$!
|
||||||
|
|||||||
41
docker/urbanLifeline/web/.env.example
Normal file
41
docker/urbanLifeline/web/.env.example
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# ================================================
|
||||||
|
# Urban Lifeline - 前端环境变量配置
|
||||||
|
#
|
||||||
|
# 使用方法:
|
||||||
|
# 1. 复制此文件为 .env
|
||||||
|
# 2. 修改配置值
|
||||||
|
# 3. docker-compose 会自动加载
|
||||||
|
#
|
||||||
|
# 应用配置:
|
||||||
|
# 修改 config/app-config-*.js 文件,重启容器生效
|
||||||
|
# - config/app-config-platform.js
|
||||||
|
# - config/app-config-workcase.js
|
||||||
|
# - config/app-config-bidding.js
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 目录配置
|
||||||
|
# ============================================
|
||||||
|
CONFIG_ROOT=./config
|
||||||
|
LOG_ROOT=./volumes/logs
|
||||||
|
DATA_ROOT=./volumes/data
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 镜像版本
|
||||||
|
# ============================================
|
||||||
|
IMAGE_VERSION=latest
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 端口配置
|
||||||
|
# ============================================
|
||||||
|
SHARED_PORT=8000
|
||||||
|
PLATFORM_PORT=8001
|
||||||
|
WORKCASE_PORT=8002
|
||||||
|
BIDDING_PORT=8003
|
||||||
|
WORKCASE_WECHAT_PORT=8004
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 资源限制
|
||||||
|
# ============================================
|
||||||
|
MEMORY_LIMIT=512M
|
||||||
|
MEMORY_RESERVATION=128M
|
||||||
@@ -8,7 +8,7 @@ FROM node:20-alpine
|
|||||||
|
|
||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
RUN apk add --no-cache tzdata curl bash \
|
RUN apk add --no-cache tzdata curl bash sed \
|
||||||
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
|
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
|
||||||
&& echo "Asia/Shanghai" > /etc/timezone
|
&& echo "Asia/Shanghai" > /etc/timezone
|
||||||
|
|
||||||
@@ -30,13 +30,18 @@ COPY urbanLifelineWeb/packages/workcase/dist/ /app/sites/workcase/
|
|||||||
COPY urbanLifelineWeb/packages/bidding/dist/ /app/sites/bidding/
|
COPY urbanLifelineWeb/packages/bidding/dist/ /app/sites/bidding/
|
||||||
COPY urbanLifelineWeb/packages/workcase_wechat/dist/ /app/sites/workcase_wechat/
|
COPY urbanLifelineWeb/packages/workcase_wechat/dist/ /app/sites/workcase_wechat/
|
||||||
|
|
||||||
# 默认端口 (可通过环境变量覆盖)
|
# ============================================
|
||||||
|
# 端口配置 (可通过环境变量覆盖)
|
||||||
|
# ============================================
|
||||||
ENV SHARED_PORT=8000 \
|
ENV SHARED_PORT=8000 \
|
||||||
PLATFORM_PORT=8001 \
|
PLATFORM_PORT=8001 \
|
||||||
WORKCASE_PORT=8002 \
|
WORKCASE_PORT=8002 \
|
||||||
BIDDING_PORT=8003 \
|
BIDDING_PORT=8003 \
|
||||||
WORKCASE_WECHAT_PORT=8004
|
WORKCASE_WECHAT_PORT=8004
|
||||||
|
|
||||||
|
# 配置和日志目录 (可外挂)
|
||||||
|
VOLUME ["/app/config", "/app/logs"]
|
||||||
|
|
||||||
EXPOSE 8000 8001 8002 8003 8004
|
EXPOSE 8000 8001 8002 8003 8004
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
||||||
|
|||||||
53
docker/urbanLifeline/web/config/app-config-bidding.js
Normal file
53
docker/urbanLifeline/web/config/app-config-bidding.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @description Bidding 运行时配置 (Docker 部署用)
|
||||||
|
*
|
||||||
|
* 域名: https://demo-urbanlifeline.tensorgrove.com
|
||||||
|
* 修改此文件后重启容器生效
|
||||||
|
*/
|
||||||
|
|
||||||
|
window.APP_RUNTIME_CONFIG = {
|
||||||
|
env: 'production',
|
||||||
|
|
||||||
|
api: {
|
||||||
|
baseUrl: '/api',
|
||||||
|
timeout: 30000
|
||||||
|
},
|
||||||
|
|
||||||
|
baseUrl: '/',
|
||||||
|
|
||||||
|
file: {
|
||||||
|
downloadUrl: '/api/urban-lifeline/file/download/',
|
||||||
|
uploadUrl: '/api/urban-lifeline/file/upload',
|
||||||
|
maxSize: {
|
||||||
|
image: 5,
|
||||||
|
video: 100,
|
||||||
|
document: 10
|
||||||
|
},
|
||||||
|
acceptTypes: {
|
||||||
|
image: 'image/*',
|
||||||
|
video: 'video/*',
|
||||||
|
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
token: {
|
||||||
|
key: 'token',
|
||||||
|
refreshThreshold: 300000
|
||||||
|
},
|
||||||
|
|
||||||
|
publicImgPath: '/img',
|
||||||
|
publicWebPath: '/',
|
||||||
|
|
||||||
|
sso: {
|
||||||
|
platformUrl: 'https://demo-urbanlifeline.tensorgrove.com/',
|
||||||
|
workcaseUrl: 'https://demo-urbanlifeline.tensorgrove.com/workcase',
|
||||||
|
biddingUrl: 'https://demo-urbanlifeline.tensorgrove.com/bidding'
|
||||||
|
},
|
||||||
|
|
||||||
|
aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=',
|
||||||
|
|
||||||
|
features: {
|
||||||
|
enableDebug: false,
|
||||||
|
enableMockData: false
|
||||||
|
}
|
||||||
|
};
|
||||||
53
docker/urbanLifeline/web/config/app-config-platform.js
Normal file
53
docker/urbanLifeline/web/config/app-config-platform.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @description Platform 运行时配置 (Docker 部署用)
|
||||||
|
*
|
||||||
|
* 域名: https://demo-urbanlifeline.tensorgrove.com
|
||||||
|
* 修改此文件后重启容器生效
|
||||||
|
*/
|
||||||
|
|
||||||
|
window.APP_RUNTIME_CONFIG = {
|
||||||
|
env: 'production',
|
||||||
|
|
||||||
|
api: {
|
||||||
|
baseUrl: '/api',
|
||||||
|
timeout: 30000
|
||||||
|
},
|
||||||
|
|
||||||
|
baseUrl: '/',
|
||||||
|
|
||||||
|
file: {
|
||||||
|
downloadUrl: '/api/urban-lifeline/file/download/',
|
||||||
|
uploadUrl: '/api/urban-lifeline/file/upload',
|
||||||
|
maxSize: {
|
||||||
|
image: 5,
|
||||||
|
video: 100,
|
||||||
|
document: 10
|
||||||
|
},
|
||||||
|
acceptTypes: {
|
||||||
|
image: 'image/*',
|
||||||
|
video: 'video/*',
|
||||||
|
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
token: {
|
||||||
|
key: 'token',
|
||||||
|
refreshThreshold: 300000
|
||||||
|
},
|
||||||
|
|
||||||
|
publicImgPath: '/img',
|
||||||
|
publicWebPath: '/',
|
||||||
|
|
||||||
|
sso: {
|
||||||
|
platformUrl: 'https://demo-urbanlifeline.tensorgrove.com/',
|
||||||
|
workcaseUrl: 'https://demo-urbanlifeline.tensorgrove.com/workcase',
|
||||||
|
biddingUrl: 'https://demo-urbanlifeline.tensorgrove.com/bidding'
|
||||||
|
},
|
||||||
|
|
||||||
|
aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=',
|
||||||
|
|
||||||
|
features: {
|
||||||
|
enableDebug: false,
|
||||||
|
enableMockData: false
|
||||||
|
}
|
||||||
|
};
|
||||||
57
docker/urbanLifeline/web/config/app-config-workcase.js
Normal file
57
docker/urbanLifeline/web/config/app-config-workcase.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* @description Workcase 运行时配置 (Docker 部署用)
|
||||||
|
*
|
||||||
|
* 域名: https://demo-urbanlifeline.tensorgrove.com
|
||||||
|
* 修改此文件后重启容器生效
|
||||||
|
*/
|
||||||
|
|
||||||
|
window.APP_RUNTIME_CONFIG = {
|
||||||
|
env: 'production',
|
||||||
|
|
||||||
|
api: {
|
||||||
|
baseUrl: '/api',
|
||||||
|
timeout: 30000
|
||||||
|
},
|
||||||
|
|
||||||
|
baseUrl: '/',
|
||||||
|
|
||||||
|
file: {
|
||||||
|
downloadUrl: '/api/urban-lifeline/file/download/',
|
||||||
|
uploadUrl: '/api/urban-lifeline/file/upload',
|
||||||
|
maxSize: {
|
||||||
|
image: 5,
|
||||||
|
video: 100,
|
||||||
|
document: 10
|
||||||
|
},
|
||||||
|
acceptTypes: {
|
||||||
|
image: 'image/*',
|
||||||
|
video: 'video/*',
|
||||||
|
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
token: {
|
||||||
|
key: 'token',
|
||||||
|
refreshThreshold: 300000
|
||||||
|
},
|
||||||
|
|
||||||
|
publicImgPath: '/img',
|
||||||
|
publicWebPath: '/',
|
||||||
|
|
||||||
|
sso: {
|
||||||
|
platformUrl: 'https://demo-urbanlifeline.tensorgrove.com/',
|
||||||
|
workcaseUrl: 'https://demo-urbanlifeline.tensorgrove.com/workcase',
|
||||||
|
biddingUrl: 'https://demo-urbanlifeline.tensorgrove.com/bidding'
|
||||||
|
},
|
||||||
|
|
||||||
|
aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=',
|
||||||
|
|
||||||
|
jitsi: {
|
||||||
|
serverUrl: 'https://demo-jitsi.tensorgrove.com'
|
||||||
|
},
|
||||||
|
|
||||||
|
features: {
|
||||||
|
enableDebug: false,
|
||||||
|
enableMockData: false
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -8,29 +8,38 @@ services:
|
|||||||
image: urban-lifeline-web:${IMAGE_VERSION:-latest}
|
image: urban-lifeline-web:${IMAGE_VERSION:-latest}
|
||||||
container_name: urban-lifeline-web
|
container_name: urban-lifeline-web
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
networks:
|
networks:
|
||||||
- urban-lifeline
|
- urban-lifeline
|
||||||
ports:
|
ports:
|
||||||
- "${PLATFORM_PORT:-8001}:${PLATFORM_PORT:-8001}"
|
- "${SHARED_PORT:-8000}:8000"
|
||||||
- "${WORKCASE_PORT:-8002}:${WORKCASE_PORT:-8002}"
|
- "${PLATFORM_PORT:-8001}:8001"
|
||||||
- "${BIDDING_PORT:-8003}:${BIDDING_PORT:-8003}"
|
- "${WORKCASE_PORT:-8002}:8002"
|
||||||
- "${WORKCASE_WECHAT_PORT:-8004}:${WORKCASE_WECHAT_PORT:-8004}"
|
- "${BIDDING_PORT:-8003}:8003"
|
||||||
|
- "${WORKCASE_WECHAT_PORT:-8004}:8004"
|
||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
|
SHARED_PORT: ${SHARED_PORT:-8000}
|
||||||
PLATFORM_PORT: ${PLATFORM_PORT:-8001}
|
PLATFORM_PORT: ${PLATFORM_PORT:-8001}
|
||||||
WORKCASE_PORT: ${WORKCASE_PORT:-8002}
|
WORKCASE_PORT: ${WORKCASE_PORT:-8002}
|
||||||
BIDDING_PORT: ${BIDDING_PORT:-8003}
|
BIDDING_PORT: ${BIDDING_PORT:-8003}
|
||||||
WORKCASE_WECHAT_PORT: ${WORKCASE_WECHAT_PORT:-8004}
|
WORKCASE_WECHAT_PORT: ${WORKCASE_WECHAT_PORT:-8004}
|
||||||
volumes:
|
volumes:
|
||||||
- ${LOG_ROOT:-../../volumes/logs}/web:/app/logs
|
# 配置文件目录 (app-config-*.js)
|
||||||
|
- ${CONFIG_ROOT:-./config}:/app/config:ro
|
||||||
|
# 日志目录
|
||||||
|
- ${LOG_ROOT:-./volumes/logs}:/app/logs
|
||||||
|
# 数据目录 (静态资源等)
|
||||||
|
- ${DATA_ROOT:-./volumes/data}:/app/data
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
memory: 512M
|
memory: ${MEMORY_LIMIT:-512M}
|
||||||
reservations:
|
reservations:
|
||||||
memory: 128M
|
memory: ${MEMORY_RESERVATION:-128M}
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:${PLATFORM_PORT:-8001}/"]
|
test: ["CMD", "curl", "-f", "http://localhost:8000/"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
@@ -38,4 +47,4 @@ services:
|
|||||||
|
|
||||||
networks:
|
networks:
|
||||||
urban-lifeline:
|
urban-lifeline:
|
||||||
external: true
|
name: urban-lifeline
|
||||||
|
|||||||
@@ -15,9 +15,43 @@ set -e
|
|||||||
SITES_DIR="/app/sites"
|
SITES_DIR="/app/sites"
|
||||||
PID_DIR="/app/pids"
|
PID_DIR="/app/pids"
|
||||||
LOG_DIR="/app/logs"
|
LOG_DIR="/app/logs"
|
||||||
|
CONFIG_DIR="/app/config"
|
||||||
|
|
||||||
mkdir -p "$PID_DIR" "$LOG_DIR"
|
mkdir -p "$PID_DIR" "$LOG_DIR"
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 配置处理函数
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
# 同步挂载的配置文件到站点目录
|
||||||
|
sync_mounted_config() {
|
||||||
|
local web=$1
|
||||||
|
local mounted_config="${CONFIG_DIR}/app-config-${web}.js"
|
||||||
|
local site_config="${SITES_DIR}/${web}/app-config.js"
|
||||||
|
|
||||||
|
if [ -f "$mounted_config" ]; then
|
||||||
|
log_info "同步挂载配置: $mounted_config -> $site_config"
|
||||||
|
cp "$mounted_config" "$site_config"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_warn "$web 没有挂载配置文件,使用构建默认配置"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 处理所有前端配置
|
||||||
|
sync_all_configs() {
|
||||||
|
log_info "=========================================="
|
||||||
|
log_info " 同步前端配置文件"
|
||||||
|
log_info "=========================================="
|
||||||
|
|
||||||
|
for web in "${BOOT_ORDER[@]}"; do
|
||||||
|
sync_mounted_config "$web"
|
||||||
|
done
|
||||||
|
|
||||||
|
log_info "配置同步完成"
|
||||||
|
}
|
||||||
|
|
||||||
# 前端配置: 名称=端口环境变量名:默认端口
|
# 前端配置: 名称=端口环境变量名:默认端口
|
||||||
declare -A WEBS=(
|
declare -A WEBS=(
|
||||||
["shared"]="SHARED_PORT:8000"
|
["shared"]="SHARED_PORT:8000"
|
||||||
@@ -83,6 +117,7 @@ wait_for_web() {
|
|||||||
# 启动单个前端
|
# 启动单个前端
|
||||||
start_web() {
|
start_web() {
|
||||||
local web=$1
|
local web=$1
|
||||||
|
local skip_config=$2
|
||||||
local port=$(get_port "$web")
|
local port=$(get_port "$web")
|
||||||
local site_dir="${SITES_DIR}/${web}"
|
local site_dir="${SITES_DIR}/${web}"
|
||||||
local pid_file="${PID_DIR}/${web}.pid"
|
local pid_file="${PID_DIR}/${web}.pid"
|
||||||
@@ -98,6 +133,11 @@ start_web() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 同步配置 (除非已经批量同步过)
|
||||||
|
if [ "$skip_config" != "skip_config" ]; then
|
||||||
|
sync_mounted_config "$web"
|
||||||
|
fi
|
||||||
|
|
||||||
log_info "启动 $web (端口: $port)..."
|
log_info "启动 $web (端口: $port)..."
|
||||||
|
|
||||||
# 使用 serve 启动静态服务
|
# 使用 serve 启动静态服务
|
||||||
@@ -151,8 +191,11 @@ start_all() {
|
|||||||
log_info " Urban Lifeline - 启动所有前端"
|
log_info " Urban Lifeline - 启动所有前端"
|
||||||
log_info "=========================================="
|
log_info "=========================================="
|
||||||
|
|
||||||
|
# 同步所有挂载的配置文件
|
||||||
|
sync_all_configs
|
||||||
|
|
||||||
for web in "${BOOT_ORDER[@]}"; do
|
for web in "${BOOT_ORDER[@]}"; do
|
||||||
start_web "$web"
|
start_web "$web" "skip_config"
|
||||||
|
|
||||||
log_info "等待 $web 就绪..."
|
log_info "等待 $web 就绪..."
|
||||||
if wait_for_web "$web"; then
|
if wait_for_web "$web"; then
|
||||||
|
|||||||
9
docker/域名.md
Normal file
9
docker/域名.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
- dify: https://demo-dify.tensorgrove.com
|
||||||
|
|
||||||
|
- minio: https://demo-minio.tensorgrove.com
|
||||||
|
|
||||||
|
- jitsi: https://demo-jitsi.tensorgrove.com
|
||||||
|
|
||||||
|
- nacos: https://demo-nacos.tensorgrove.com
|
||||||
|
|
||||||
|
- urbanLifeline: https://demo-urbanlifeline.tensorgrove.com
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
# 管理后台路由架构说明
|
|
||||||
|
|
||||||
## 三层架构设计
|
|
||||||
|
|
||||||
### 第一层:外层主 Sidebar (platform 服务)
|
|
||||||
显示在平台主界面的侧边栏,包含用户应用和管理后台入口。
|
|
||||||
|
|
||||||
**布局**: `SidebarLayout`
|
|
||||||
**服务**: `platform`
|
|
||||||
|
|
||||||
#### 用户应用入口
|
|
||||||
- 泰豪AI助手 (`/aichat`)
|
|
||||||
- 全部应用 (`/agents`)
|
|
||||||
- 智能体编排 (`/app/workflow`) - iframe
|
|
||||||
- 招标助手 (`/app/bidding`) - iframe
|
|
||||||
- 泰豪小电 (`/app/workcase`) - iframe
|
|
||||||
|
|
||||||
#### 管理后台入口(iframe类型)
|
|
||||||
1. **平台管理后台** (`/admin/platform`)
|
|
||||||
- iframe_url: `/platform/admin`
|
|
||||||
- 权限: `perm_platform_admin`
|
|
||||||
|
|
||||||
2. **智能标书管理后台** (`/admin/bidding`)
|
|
||||||
- iframe_url: `/bidding/admin`
|
|
||||||
- 权限: `perm_bidding_admin`
|
|
||||||
|
|
||||||
3. **泰豪小电管理后台** (`/admin/workcase`)
|
|
||||||
- iframe_url: `/workcase/admin`
|
|
||||||
- 权限: `perm_workcase_admin`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 第二层:SubSidebarLayout (各服务内部)
|
|
||||||
每个管理后台的内部二级菜单,使用 `SubSidebarLayout` 布局。
|
|
||||||
|
|
||||||
**布局**: `SubSidebarLayout`
|
|
||||||
**类型**: `route`(非 iframe)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Platform 管理后台(第二层)
|
|
||||||
|
|
||||||
**服务**: `platform`
|
|
||||||
**布局**: `SubSidebarLayout`
|
|
||||||
|
|
||||||
### 视图列表
|
|
||||||
|
|
||||||
| 序号 | 视图名称 | URL | 组件路径 | 权限 |
|
|
||||||
|------|---------|-----|----------|------|
|
|
||||||
| 1 | 数据概览 | `/admin/overview` | `admin/overview/OverviewView.vue` | `perm_platform_admin_overview` |
|
|
||||||
| 2 | 用户管理 | `/admin/user` | `admin/user/UserView.vue` | `perm_platform_admin_user` |
|
|
||||||
| 3 | 知识库 | `/admin/knowledge` | `admin/knowledge/KnowledgeView.vue` | `perm_platform_admin_knowledge` |
|
|
||||||
| 4 | 系统配置 | `/admin/config` | `admin/config/ConfigView.vue` | `perm_platform_admin_config` |
|
|
||||||
|
|
||||||
### 权限配置
|
|
||||||
```sql
|
|
||||||
-- 管理后台入口权限
|
|
||||||
PERM-0601: perm_platform_admin (platform:admin:view)
|
|
||||||
|
|
||||||
-- 内部功能权限
|
|
||||||
PERM-0602: perm_platform_admin_overview (platform:admin:overview)
|
|
||||||
PERM-0603: perm_platform_admin_user (platform:admin:user)
|
|
||||||
PERM-0604: perm_platform_admin_knowledge (platform:admin:knowledge)
|
|
||||||
PERM-0605: perm_platform_admin_config (platform:admin:config)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bidding 管理后台(第二层)
|
|
||||||
|
|
||||||
**服务**: `bidding`
|
|
||||||
**布局**: `SubSidebarLayout`
|
|
||||||
|
|
||||||
### 权限配置
|
|
||||||
```sql
|
|
||||||
-- 管理后台入口权限
|
|
||||||
PERM-0611: perm_bidding_admin (bidding:admin:view)
|
|
||||||
```
|
|
||||||
|
|
||||||
*注: bidding 管理后台的具体视图需要后续配置*
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Workcase 管理后台(第二层)
|
|
||||||
|
|
||||||
**服务**: `workcase`
|
|
||||||
**布局**: `SubSidebarLayout`
|
|
||||||
|
|
||||||
### 视图列表
|
|
||||||
|
|
||||||
| 序号 | 视图名称 | URL | 组件路径 | 权限 |
|
|
||||||
|------|---------|-----|----------|------|
|
|
||||||
| 1 | 数据概览 | `/admin/overview` | `admin/overview/OverviewView.vue` | `perm_workcase_overview` |
|
|
||||||
| 2 | 知识库管理 | `/admin/knowledge` | `admin/knowledge/KnowLedgeView.vue` | `perm_workcase_knowledge` |
|
|
||||||
| 3 | 工单管理 | `/admin/workcase` | `admin/workcase/WorkcaseView.vue` | `perm_workcase_tickets` |
|
|
||||||
| 4 | 对话数据 | `/admin/customerChat` | `admin/customerChat/CustomerChatView.vue` | `perm_workcase_conversation` |
|
|
||||||
| 5 | 智能体管理 | `/admin/agent` | `admin/agent/AgentView.vue` | `perm_workcase_agent` |
|
|
||||||
| 6 | 日志管理 | `/admin/log` | *(目录)* | `perm_workcase_log` |
|
|
||||||
| 6.1 | └ 知识库日志 | `/admin/log/knowledge` | `admin/log/knowledgeLog/KnowledgeLogView.vue` | `perm_workcase_log` |
|
|
||||||
| 6.2 | └ 工单日志 | `/admin/log/workcase` | `admin/log/workcaseLog/WorkcaseLogView.vue` | `perm_workcase_log` |
|
|
||||||
| 6.3 | └ 系统日志 | `/admin/log/system` | `admin/log/systemLog/SystemLogView.vue` | `perm_workcase_log` |
|
|
||||||
|
|
||||||
### 权限配置
|
|
||||||
```sql
|
|
||||||
-- 管理后台入口权限
|
|
||||||
PERM-0621: perm_workcase_admin (workcase:admin:view)
|
|
||||||
|
|
||||||
-- 内部功能权限
|
|
||||||
PERM-0622: perm_workcase_overview (workcase:overview:view)
|
|
||||||
PERM-0623: perm_workcase_knowledge (workcase:knowledge:view)
|
|
||||||
PERM-0624: perm_workcase_tickets (workcase:tickets:view)
|
|
||||||
PERM-0625: perm_workcase_conversation (workcase:conversation:view)
|
|
||||||
PERM-0626: perm_workcase_agent (workcase:agent:view)
|
|
||||||
PERM-0627: perm_workcase_log (workcase:log:view)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 路由过滤规则
|
|
||||||
|
|
||||||
### 外层主 Sidebar (platform/SidebarLayout)
|
|
||||||
显示所有 `service='platform'` 且 `layout='SidebarLayout'` 的视图:
|
|
||||||
- 用户应用入口(普通路由和iframe)
|
|
||||||
- 管理后台入口(iframe类型)
|
|
||||||
|
|
||||||
### 内层 SubSidebarLayout
|
|
||||||
各服务内部,显示 `layout='SubSidebarLayout'` 且 `url.startsWith('/admin')` 的视图:
|
|
||||||
|
|
||||||
#### Platform AdminSidebar
|
|
||||||
```typescript
|
|
||||||
service === 'platform' &&
|
|
||||||
layout === 'SubSidebarLayout' &&
|
|
||||||
url.startsWith('/admin')
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Bidding AdminSidebar
|
|
||||||
```typescript
|
|
||||||
service === 'bidding' &&
|
|
||||||
layout === 'SubSidebarLayout' &&
|
|
||||||
url.startsWith('/admin')
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Workcase AdminSidebar
|
|
||||||
```typescript
|
|
||||||
service === 'workcase' &&
|
|
||||||
layout === 'SubSidebarLayout' &&
|
|
||||||
url.startsWith('/admin')
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 数据库表关系
|
|
||||||
|
|
||||||
### 视图类型说明
|
|
||||||
| type | view_type | 说明 | 示例 |
|
|
||||||
|------|-----------|------|------|
|
|
||||||
| 1 | route | 普通路由视图 | 数据概览、用户管理 |
|
|
||||||
| 1 | iframe | iframe嵌入视图 | 管理后台入口、Dify编排 |
|
|
||||||
| 0 | route | 目录(不可点击) | 日志管理 |
|
|
||||||
| 3 | route | 默认首页(隐藏) | 智能客服首页 |
|
|
||||||
|
|
||||||
### 视图权限关联
|
|
||||||
每个视图通过 `tb_sys_view_permission` 表关联到对应权限:
|
|
||||||
- 一个视图可以关联多个权限(AND 逻辑)
|
|
||||||
- 用户需要拥有所有关联权限才能访问该视图
|
|
||||||
|
|
||||||
### 角色权限继承
|
|
||||||
- **超级管理员**: 自动拥有所有权限
|
|
||||||
- **系统管理员**: 拥有所有 module 的管理权限(除删除外)
|
|
||||||
- **普通用户**: 基础查看权限 + 平台基础菜单访问
|
|
||||||
- **访客**: 仅查看权限 + 部分平台菜单访问
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 前端实现注意事项
|
|
||||||
|
|
||||||
### 1. Layout 组件
|
|
||||||
- **SidebarLayout**: 外层主侧边栏(platform 主界面)
|
|
||||||
- **SubSidebarLayout**: 内层管理侧边栏(各管理后台内部)
|
|
||||||
- **BlankLayout**: 空白布局(如智能客服首页)
|
|
||||||
|
|
||||||
### 2. iframe 嵌套
|
|
||||||
- 外层 platform 的 iframe 菜单 → 加载各服务的管理后台
|
|
||||||
- 各服务内部使用 SubSidebarLayout 渲染二级菜单
|
|
||||||
- iframe_url 必须正确指向实际服务地址
|
|
||||||
|
|
||||||
### 3. 路由配置
|
|
||||||
所有 `/admin/*` 路径统一用于管理后台:
|
|
||||||
- platform: `/admin/overview`, `/admin/user` 等
|
|
||||||
- bidding: `/admin/*` (待定义)
|
|
||||||
- workcase: `/admin/overview`, `/admin/knowledge` 等
|
|
||||||
|
|
||||||
### 4. 权限验证
|
|
||||||
前端需要根据 `loginDomain.userViews` 动态渲染菜单:
|
|
||||||
- 检查 `layout` 字段匹配当前布局
|
|
||||||
- 检查 `service` 字段匹配当前服务
|
|
||||||
- 检查用户是否拥有关联的权限
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 迁移说明
|
|
||||||
|
|
||||||
如果从旧的单层架构迁移到三层架构:
|
|
||||||
|
|
||||||
1. **视图迁移**
|
|
||||||
- 将原 platform 的管理视图改为 `layout='SubSidebarLayout'`
|
|
||||||
- URL 统一改为 `/admin/*` 格式
|
|
||||||
- 在 platform 主侧边栏添加 iframe 入口
|
|
||||||
|
|
||||||
2. **权限迁移**
|
|
||||||
- 保留原有权限定义
|
|
||||||
- 新增管理后台入口权限(如 `perm_platform_admin`)
|
|
||||||
- 更新视图权限关联
|
|
||||||
|
|
||||||
3. **前端组件**
|
|
||||||
- 创建 SubSidebarLayout 组件(参考 workcase 实现)
|
|
||||||
- 更新 platform 路由配置支持 `/admin/*` 路径
|
|
||||||
- 配置 iframe 路由指向各服务管理后台
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 总结
|
|
||||||
|
|
||||||
这个三层架构设计实现了:
|
|
||||||
- ✅ **统一入口**: 所有管理后台统一在 platform 主侧边栏
|
|
||||||
- ✅ **独立管理**: 各服务管理后台相互独立,便于维护
|
|
||||||
- ✅ **权限细分**: 入口权限 + 功能权限双重控制
|
|
||||||
- ✅ **灵活扩展**: 新增服务只需添加 iframe 入口和内部视图
|
|
||||||
- ✅ **用户体验**: 统一的导航风格,清晰的层级结构
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
# Workcase 管理端路由配置总结
|
|
||||||
|
|
||||||
## 已配置的管理端视图
|
|
||||||
|
|
||||||
### 1. 数据概览 (Overview)
|
|
||||||
- **view_id**: `view_workcase_admin_overview`
|
|
||||||
- **URL**: `/admin/overview`
|
|
||||||
- **组件**: `admin/overview/OverviewView.vue`
|
|
||||||
- **图标**: DataLine
|
|
||||||
- **权限**: `perm_workcase_overview` (workcase:overview:view)
|
|
||||||
- **描述**: 泰豪小电数据概览
|
|
||||||
|
|
||||||
### 2. 知识库管理 (Knowledge)
|
|
||||||
- **view_id**: `view_workcase_admin_knowledge`
|
|
||||||
- **URL**: `/admin/knowledge`
|
|
||||||
- **组件**: `admin/knowledge/KnowLedgeView.vue`
|
|
||||||
- **图标**: Document
|
|
||||||
- **权限**: `perm_workcase_knowledge` (workcase:knowledge:view)
|
|
||||||
- **描述**: 知识库文档管理
|
|
||||||
|
|
||||||
### 3. 工单管理 (Tickets)
|
|
||||||
- **view_id**: `view_workcase_admin_tickets`
|
|
||||||
- **URL**: `/admin/workcase`
|
|
||||||
- **组件**: `admin/workcase/WorkcaseView.vue`
|
|
||||||
- **图标**: Tickets
|
|
||||||
- **权限**: `perm_workcase_tickets` (workcase:tickets:view)
|
|
||||||
- **描述**: 客服工单管理
|
|
||||||
|
|
||||||
### 4. 对话数据 (Conversation)
|
|
||||||
- **view_id**: `view_workcase_admin_conversation`
|
|
||||||
- **URL**: `/admin/customerChat`
|
|
||||||
- **组件**: `admin/customerChat/CustomerChatView.vue`
|
|
||||||
- **图标**: ChatDotRound
|
|
||||||
- **权限**: `perm_workcase_conversation` (workcase:conversation:view)
|
|
||||||
- **描述**: 客户对话数据管理
|
|
||||||
|
|
||||||
### 5. 智能体管理 (Agent)
|
|
||||||
- **view_id**: `view_workcase_admin_agent`
|
|
||||||
- **URL**: `/admin/agent`
|
|
||||||
- **组件**: `admin/agent/AgentView.vue`
|
|
||||||
- **图标**: Service
|
|
||||||
- **权限**: `perm_workcase_agent` (workcase:agent:view)
|
|
||||||
- **描述**: 智能体配置管理
|
|
||||||
|
|
||||||
### 6. 日志管理 (Logs)
|
|
||||||
#### 6.1 日志管理目录
|
|
||||||
- **view_id**: `view_workcase_admin_log`
|
|
||||||
- **URL**: `/admin/log`
|
|
||||||
- **组件**: NULL (目录类型)
|
|
||||||
- **图标**: List
|
|
||||||
- **type**: 0 (目录)
|
|
||||||
- **权限**: `perm_workcase_log` (workcase:log:view)
|
|
||||||
- **描述**: 日志管理目录
|
|
||||||
|
|
||||||
#### 6.2 知识库日志
|
|
||||||
- **view_id**: `view_workcase_admin_log_knowledge`
|
|
||||||
- **parent_id**: `view_workcase_admin_log`
|
|
||||||
- **URL**: `/admin/log/knowledge`
|
|
||||||
- **组件**: `admin/log/knowledgeLog/KnowledgeLogView.vue`
|
|
||||||
- **图标**: Document
|
|
||||||
- **权限**: `perm_workcase_log` (workcase:log:view)
|
|
||||||
- **描述**: 知识库操作日志
|
|
||||||
|
|
||||||
#### 6.3 工单日志
|
|
||||||
- **view_id**: `view_workcase_admin_log_workcase`
|
|
||||||
- **parent_id**: `view_workcase_admin_log`
|
|
||||||
- **URL**: `/admin/log/workcase`
|
|
||||||
- **组件**: `admin/log/workcaseLog/WorkcaseLogView.vue`
|
|
||||||
- **图标**: Tickets
|
|
||||||
- **权限**: `perm_workcase_log` (workcase:log:view)
|
|
||||||
- **描述**: 工单操作日志
|
|
||||||
|
|
||||||
#### 6.4 系统日志
|
|
||||||
- **view_id**: `view_workcase_admin_log_system`
|
|
||||||
- **parent_id**: `view_workcase_admin_log`
|
|
||||||
- **URL**: `/admin/log/system`
|
|
||||||
- **组件**: `admin/log/systemLog/SystemLogView.vue`
|
|
||||||
- **图标**: Setting
|
|
||||||
- **权限**: `perm_workcase_log` (workcase:log:view)
|
|
||||||
- **描述**: 系统运行日志
|
|
||||||
|
|
||||||
## 权限配置
|
|
||||||
|
|
||||||
### 新增权限
|
|
||||||
1. **PERM-0601**: `perm_workcase_overview` - 数据概览
|
|
||||||
2. **PERM-0602**: `perm_workcase_knowledge` - 知识库管理
|
|
||||||
3. **PERM-0603**: `perm_workcase_tickets` - 工单管理
|
|
||||||
4. **PERM-0604**: `perm_workcase_conversation` - 对话数据
|
|
||||||
5. **PERM-0605**: `perm_workcase_agent` - 智能体管理
|
|
||||||
6. **PERM-0606**: `perm_workcase_log` - 日志管理
|
|
||||||
|
|
||||||
### 视图权限关联
|
|
||||||
- VP-W101 ~ VP-W105: 管理端主功能视图
|
|
||||||
- VP-W106 ~ VP-W109: 日志管理视图(含父级和3个子级)
|
|
||||||
|
|
||||||
## 布局配置
|
|
||||||
- **Layout**: `SubSidebarLayout`
|
|
||||||
- **Service**: `workcase`
|
|
||||||
- **Type**: 1 (菜单项) / 0 (目录)
|
|
||||||
- **View Type**: `route`
|
|
||||||
|
|
||||||
## Order Number 排序
|
|
||||||
- 110: 数据概览
|
|
||||||
- 120: 知识库管理
|
|
||||||
- 130: 工单管理
|
|
||||||
- 140: 对话数据
|
|
||||||
- 150: 智能体管理
|
|
||||||
- 160: 日志管理(父级)
|
|
||||||
- 161: 知识库日志
|
|
||||||
- 162: 工单日志
|
|
||||||
- 163: 系统日志
|
|
||||||
|
|
||||||
## 路由过滤规则
|
|
||||||
在 `SubSidebarLayout.vue` 的 `loadMenuFromStorage()` 中:
|
|
||||||
```typescript
|
|
||||||
const sidebarViews = userViews.filter((view: any) =>
|
|
||||||
view.layout === 'SidebarLayout' && // 使用 SidebarLayout 布局
|
|
||||||
!view.parentId && // 顶级菜单
|
|
||||||
view.type === 1 && // 菜单类型
|
|
||||||
view.service === 'workcase' && // workcase 服务
|
|
||||||
view.url?.startsWith('/admin') // admin 路由
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
1. 所有管理端路由都以 `/admin/` 开头
|
|
||||||
2. 日志管理使用父子级结构(type=0 的目录 + type=1 的子菜单)
|
|
||||||
3. 所有视图都使用 `SubSidebarLayout` 布局
|
|
||||||
4. 权限都归属于 `module_workcase` 模块
|
|
||||||
5. 超级管理员和系统管理员默认拥有所有 workcase 管理端权限
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
# ================== Server ==================
|
|
||||||
server:
|
|
||||||
port: 8090
|
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/agent
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
|
||||||
auth:
|
|
||||||
enabled: true
|
|
||||||
gateway-mode: true
|
|
||||||
whitelist:
|
|
||||||
- /swagger-ui/**
|
|
||||||
- /swagger-ui.html
|
|
||||||
- /v3/api-docs/**
|
|
||||||
- /webjars/**
|
|
||||||
- /favicon.ico
|
|
||||||
- /error
|
|
||||||
- /actuator/health
|
|
||||||
- /actuator/info
|
|
||||||
- /ai/chat/** # AI对话,有非系统用户对话的接口,无登录状态
|
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
# AES-256 密钥(Base64编码,必须与所有服务保持一致)
|
|
||||||
# 警告:这是开发环境密钥,生产环境请使用密钥管理系统
|
|
||||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: ai-service
|
|
||||||
# 文件上传配置
|
|
||||||
servlet:
|
|
||||||
multipart:
|
|
||||||
enabled: true
|
|
||||||
max-file-size: 500MB
|
|
||||||
max-request-size: 500MB
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
|
||||||
data:
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1
|
|
||||||
port: 6379
|
|
||||||
database: 0
|
|
||||||
# password: ""
|
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
|
||||||
springdoc:
|
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
group-configs:
|
|
||||||
- group: 'default'
|
|
||||||
display-name: 'AI代理服务 API'
|
|
||||||
paths-to-match: '/**'
|
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
|
||||||
dubbo:
|
|
||||||
application:
|
|
||||||
name: urban-lifeline-agent
|
|
||||||
qos-enable: false
|
|
||||||
protocol:
|
|
||||||
payload: 110100480
|
|
||||||
name: dubbo
|
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
|
||||||
base-packages: org.xyzh.ai.service.impl
|
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
@@ -1,10 +1,17 @@
|
|||||||
# ================== Server ==================
|
# ================== AI 服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8190
|
port: 8090
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/agent # 微服务架构下,context-path由Gateway管理
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
spring:
|
||||||
|
application:
|
||||||
|
name: ai-service
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
enabled: true
|
||||||
|
max-file-size: 500MB
|
||||||
|
max-request-size: 500MB
|
||||||
|
|
||||||
|
# ================== Auth ==================
|
||||||
auth:
|
auth:
|
||||||
enabled: true
|
enabled: true
|
||||||
gateway-mode: true
|
gateway-mode: true
|
||||||
@@ -17,79 +24,21 @@ auth:
|
|||||||
- /error
|
- /error
|
||||||
- /actuator/health
|
- /actuator/health
|
||||||
- /actuator/info
|
- /actuator/info
|
||||||
- /ai/chat/** # AI对话,有非系统用户对话的接口,无登录状态
|
- /ai/chat/**
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
# AES-256 密钥(Base64编码,必须与所有服务保持一致)
|
|
||||||
# 警告:这是开发环境密钥,生产环境请使用密钥管理系统
|
|
||||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: ai-service
|
|
||||||
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
|
||||||
data:
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
|
||||||
port: 6379
|
|
||||||
database: 0
|
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
# ================== SpringDoc ==================
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
group-configs:
|
group-configs:
|
||||||
- group: 'default'
|
- group: 'default'
|
||||||
display-name: 'AI代理服务 API'
|
display-name: 'AI代理服务 API'
|
||||||
paths-to-match: '/**'
|
paths-to-match: '/**'
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
# ================== Dubbo ==================
|
||||||
dubbo:
|
dubbo:
|
||||||
application:
|
application:
|
||||||
name: urban-lifeline-agent
|
name: urban-lifeline-agent
|
||||||
qos-enable: false
|
qos-enable: false
|
||||||
protocol:
|
protocol:
|
||||||
payload: 110100480
|
payload: 110100480
|
||||||
name: dubbo
|
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
scan:
|
||||||
base-packages: org.xyzh.ai.service.impl
|
base-packages: org.xyzh.ai.service.impl
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
|
|
||||||
# ================== Logging ==================
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
|
|||||||
@@ -1,97 +1,35 @@
|
|||||||
# ================== Server ==================
|
# ================== Auth 认证服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8181
|
port: 8081
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/auth # 微服务架构下,context-path由Gateway管理,服务本身不需要设置
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
|
||||||
auth:
|
|
||||||
enabled: false # 认证服务自己不需要认证
|
|
||||||
gateway-mode: false # 不使用gateway模式(auth服务作为独立服务)
|
|
||||||
whitelist:
|
|
||||||
- /** # 认证服务的所有接口都放行
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
# AES-256 密钥(Base64编码,必须与所有服务保持一致)
|
|
||||||
# 警告:这是开发环境密钥,生产环境请使用密钥管理系统
|
|
||||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: auth-service
|
name: auth-service
|
||||||
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
# ================== Auth ==================
|
||||||
data:
|
auth:
|
||||||
redis:
|
enabled: false # 认证服务自己不需要认证
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
gateway-mode: false
|
||||||
port: 6379
|
whitelist:
|
||||||
database: 0
|
- /**
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
# ================== SpringDoc ==================
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
try-it-out-enabled: true
|
|
||||||
show-common-extensions: true
|
|
||||||
show-extensions: true
|
|
||||||
show-request-duration: true
|
|
||||||
filter: true
|
|
||||||
tags-sorter: alpha
|
|
||||||
operations-sorter: alpha
|
|
||||||
group-configs:
|
group-configs:
|
||||||
- group: 'default'
|
- group: 'default'
|
||||||
display-name: '认证服务 API'
|
display-name: '认证服务 API'
|
||||||
paths-to-match: '/**'
|
paths-to-match: '/**'
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
# ================== Dubbo ==================
|
||||||
dubbo:
|
dubbo:
|
||||||
application:
|
application:
|
||||||
name: urban-lifeline-auth
|
name: urban-lifeline-auth
|
||||||
qos-enable: false
|
qos-enable: false
|
||||||
protocol:
|
|
||||||
name: dubbo
|
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
scan:
|
||||||
base-packages: org.xyzh.auth.service.impl
|
base-packages: org.xyzh.auth.service.impl
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
# ================== JWT ==================
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
|
|
||||||
# ================== JWT Configuration ==================
|
|
||||||
jwt:
|
jwt:
|
||||||
secret: urban-lifeline-secret-key-2025-xyzh
|
secret: ${JWT_SECRET:urban-lifeline-secret-key-2025-xyzh}
|
||||||
expiration: 86400 # 24小时(秒)
|
expiration: 86400 # 24小时(秒)
|
||||||
refresh-expiration: 604800 # 7天(秒)
|
refresh-expiration: 604800 # 7天(秒)
|
||||||
|
|
||||||
# ================== Logging ==================
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
|
|||||||
@@ -1,89 +1,36 @@
|
|||||||
# ================== Server ==================
|
# ================== Bidding 招投标服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8186
|
port: 8087
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/bidding # 微服务架构下,context-path由Gateway管理
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
|
||||||
urban-lifeline:
|
|
||||||
auth:
|
|
||||||
enabled: true
|
|
||||||
whitelist:
|
|
||||||
- /swagger-ui/**
|
|
||||||
- /swagger-ui.html
|
|
||||||
- /v3/api-docs/**
|
|
||||||
- /webjars/**
|
|
||||||
- /favicon.ico
|
|
||||||
- /error
|
|
||||||
- /actuator/health
|
|
||||||
- /actuator/info
|
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
secret-key: 1234567890qwer
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: bidding-service
|
name: bidding-service
|
||||||
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
# ================== Auth ==================
|
||||||
data:
|
auth:
|
||||||
redis:
|
enabled: true
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
gateway-mode: true
|
||||||
port: 6379
|
whitelist:
|
||||||
database: 0
|
- /swagger-ui/**
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
- /swagger-ui.html
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
# ================== SpringDoc ==================
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
group-configs:
|
group-configs:
|
||||||
- group: 'default'
|
- group: 'default'
|
||||||
display-name: '招投标服务 API'
|
display-name: '招投标服务 API'
|
||||||
paths-to-match: '/**'
|
paths-to-match: '/**'
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
# ================== Dubbo ==================
|
||||||
dubbo:
|
dubbo:
|
||||||
application:
|
application:
|
||||||
name: urban-lifeline-bidding
|
name: urban-lifeline-bidding
|
||||||
qos-enable: false
|
qos-enable: false
|
||||||
protocol:
|
|
||||||
name: dubbo
|
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
scan:
|
||||||
base-packages: org.xyzh.bidding.service.impl
|
base-packages: org.xyzh.bidding.service.impl
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
|
|
||||||
# ================== Logging ==================
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# ================================================
|
||||||
|
# Urban Lifeline - 通用 Bootstrap 配置
|
||||||
|
# 所有微服务共享的基础配置
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
# ================== Spring Cloud Nacos ==================
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
|
namespace: ${NACOS_NAMESPACE:dev}
|
||||||
|
group: ${NACOS_GROUP:DEFAULT_GROUP}
|
||||||
|
|
||||||
|
# ================== DataSource ==================
|
||||||
|
datasource:
|
||||||
|
url: ${DB_URL:jdbc:postgresql://127.0.0.1:5432/urban_lifeline}
|
||||||
|
username: ${DB_USERNAME:postgres}
|
||||||
|
password: ${DB_PASSWORD:postgres}
|
||||||
|
driver-class-name: org.postgresql.Driver
|
||||||
|
|
||||||
|
# ================== Redis ==================
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: ${REDIS_HOST:127.0.0.1}
|
||||||
|
port: ${REDIS_PORT:6379}
|
||||||
|
database: ${REDIS_DATABASE:0}
|
||||||
|
password: ${REDIS_PASSWORD:}
|
||||||
|
|
||||||
|
# ================== Security AES ==================
|
||||||
|
security:
|
||||||
|
aes:
|
||||||
|
# AES-256 密钥(Base64编码,必须与所有服务保持一致)
|
||||||
|
# 警告:这是开发环境密钥,生产环境请使用密钥管理系统
|
||||||
|
secret-key: ${AES_SECRET_KEY:MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=}
|
||||||
|
|
||||||
|
# ================== Dubbo ==================
|
||||||
|
dubbo:
|
||||||
|
protocol:
|
||||||
|
name: dubbo
|
||||||
|
port: -1
|
||||||
|
registry:
|
||||||
|
address: nacos://${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
|
|
||||||
|
# ================== MyBatis-Plus ==================
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath:mapper/**/*.xml
|
||||||
|
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
||||||
|
|
||||||
|
# ================== SpringDoc 基础配置 ==================
|
||||||
|
springdoc:
|
||||||
|
api-docs:
|
||||||
|
enabled: true
|
||||||
|
path: /v3/api-docs
|
||||||
|
swagger-ui:
|
||||||
|
enabled: true
|
||||||
|
path: /swagger-ui.html
|
||||||
|
|
||||||
|
# ================== Logging ==================
|
||||||
|
logging:
|
||||||
|
config: classpath:log4j2.xml
|
||||||
|
charset:
|
||||||
|
console: UTF-8
|
||||||
|
file: UTF-8
|
||||||
@@ -1,80 +1,35 @@
|
|||||||
# ================== Server ==================
|
# ================== Crontab 定时任务服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8189
|
port: 8086
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/crontab # 微服务架构下,context-path由Gateway管理
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
|
||||||
urban-lifeline:
|
|
||||||
auth:
|
|
||||||
enabled: false # 定时任务服务通常不需要认证
|
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
secret-key: 1234567890qwer
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: crontab-service
|
name: crontab-service
|
||||||
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
# ================== Auth ==================
|
||||||
data:
|
auth:
|
||||||
redis:
|
enabled: false # 定时任务服务不需要认证
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
whitelist:
|
||||||
port: 6379
|
- /swagger-ui/**
|
||||||
database: 0
|
- /swagger-ui.html
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
- /v3/api-docs/**
|
||||||
|
- /webjars/**
|
||||||
|
- /favicon.ico
|
||||||
|
- /error
|
||||||
|
- /actuator/health
|
||||||
|
- /actuator/info
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
# ================== SpringDoc ==================
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
group-configs:
|
group-configs:
|
||||||
- group: 'default'
|
- group: 'default'
|
||||||
display-name: '定时任务服务 API'
|
display-name: '定时任务服务 API'
|
||||||
paths-to-match: '/**'
|
paths-to-match: '/**'
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
# ================== Dubbo ==================
|
||||||
dubbo:
|
dubbo:
|
||||||
application:
|
application:
|
||||||
name: urban-lifeline-crontab
|
name: urban-lifeline-crontab
|
||||||
qos-enable: false
|
qos-enable: false
|
||||||
protocol:
|
|
||||||
name: dubbo
|
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
scan:
|
||||||
base-packages: org.xyzh.crontab.service.impl
|
base-packages: org.xyzh.crontab.service.impl
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
|
|
||||||
# ================== Logging ==================
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
# ================== Server ==================
|
# ================== File 文件服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8184
|
port: 8084
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/file # 微服务架构下,context-path由Gateway管理
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
spring:
|
||||||
|
application:
|
||||||
|
name: file-service
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
enabled: true
|
||||||
|
max-file-size: 500MB
|
||||||
|
max-request-size: 500MB
|
||||||
|
|
||||||
|
# ================== Auth ==================
|
||||||
auth:
|
auth:
|
||||||
enabled: true
|
enabled: true
|
||||||
gateway-mode: true
|
gateway-mode: true
|
||||||
@@ -19,83 +26,19 @@ auth:
|
|||||||
- /actuator/info
|
- /actuator/info
|
||||||
- /file/download/**
|
- /file/download/**
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
# AES-256 密钥(Base64编码,必须与所有服务保持一致)
|
|
||||||
# 警告:这是开发环境密钥,生产环境请使用密钥管理系统
|
|
||||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: file-service
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
|
||||||
data:
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
|
||||||
port: 6379
|
|
||||||
database: 0
|
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
|
||||||
|
|
||||||
# ================== 文件上传配置 ==================
|
|
||||||
servlet:
|
|
||||||
multipart:
|
|
||||||
enabled: true
|
|
||||||
max-file-size: 500MB
|
|
||||||
max-request-size: 500MB
|
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
# ================== SpringDoc ==================
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
group-configs:
|
group-configs:
|
||||||
- group: 'default'
|
- group: 'default'
|
||||||
display-name: '文件服务 API'
|
display-name: '文件服务 API'
|
||||||
paths-to-match: '/**'
|
paths-to-match: '/**'
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
# ================== Dubbo ==================
|
||||||
dubbo:
|
dubbo:
|
||||||
application:
|
application:
|
||||||
name: urban-lifeline-file
|
name: urban-lifeline-file
|
||||||
qos-enable: false
|
qos-enable: false
|
||||||
protocol:
|
protocol:
|
||||||
payload: 110100480
|
payload: 110100480
|
||||||
name: dubbo
|
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
scan:
|
||||||
base-packages: org.xyzh.file.service.impl
|
base-packages: org.xyzh.file.service.impl
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
|
|
||||||
# ================== Logging ==================
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
# 开发环境专用配置
|
|
||||||
# 注意:不要在这里配置routes,会覆盖application.yml的配置
|
|
||||||
# 路由配置统一在application.yml中管理
|
|
||||||
|
|
||||||
# 开发环境日志
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
@@ -1,50 +1,40 @@
|
|||||||
|
# ================== Gateway 服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8180
|
port: 8080
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: gateway-service
|
name: gateway-service
|
||||||
|
|
||||||
# Gateway 必须使用 reactive 模式(WebFlux),不能使用 Spring MVC
|
# Gateway 必须使用 reactive 模式
|
||||||
main:
|
main:
|
||||||
web-application-type: reactive
|
web-application-type: reactive
|
||||||
|
|
||||||
# 配置中心
|
|
||||||
cloud:
|
cloud:
|
||||||
nacos:
|
nacos:
|
||||||
discovery:
|
|
||||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
config:
|
config:
|
||||||
enabled: false # 禁用Nacos配置中心,使用本地配置
|
enabled: false
|
||||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
|
||||||
file-extension: yml
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# Gateway 路由配置
|
# Gateway 路由配置
|
||||||
gateway:
|
gateway:
|
||||||
# 服务发现路由(自动路由)
|
|
||||||
discovery:
|
discovery:
|
||||||
locator:
|
locator:
|
||||||
enabled: false # 关闭自动路由,使用手动配置
|
enabled: false
|
||||||
|
|
||||||
# 手动配置路由
|
|
||||||
routes:
|
routes:
|
||||||
# ==================== 认证服务路由 ====================
|
# 认证服务
|
||||||
- id: auth-service
|
- id: auth-service
|
||||||
uri: lb://auth-service
|
uri: lb://auth-service
|
||||||
predicates:
|
predicates:
|
||||||
- Path=/urban-lifeline/auth/**
|
- Path=/urban-lifeline/auth/**
|
||||||
filters:
|
filters:
|
||||||
- StripPrefix=1 # 去掉前缀:/urban-lifeline/auth/login → /auth/login
|
- StripPrefix=1
|
||||||
- name: RequestRateLimiter
|
- name: RequestRateLimiter
|
||||||
args:
|
args:
|
||||||
redis-rate-limiter.replenishRate: 100
|
redis-rate-limiter.replenishRate: 100
|
||||||
redis-rate-limiter.burstCapacity: 200
|
redis-rate-limiter.burstCapacity: 200
|
||||||
|
|
||||||
# ==================== 系统服务路由 ====================
|
# 系统服务
|
||||||
- id: system-service
|
- id: system-service
|
||||||
uri: lb://system-service
|
uri: lb://system-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -52,7 +42,7 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
|
||||||
# ==================== 日志服务路由 ====================
|
# 日志服务
|
||||||
- id: log-service
|
- id: log-service
|
||||||
uri: lb://log-service
|
uri: lb://log-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -60,7 +50,7 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
|
||||||
# ==================== 文件服务路由 ====================
|
# 文件服务
|
||||||
- id: file-service
|
- id: file-service
|
||||||
uri: lb://file-service
|
uri: lb://file-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -68,7 +58,7 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
|
||||||
# ==================== 消息服务路由 ====================
|
# 消息服务
|
||||||
- id: message-service
|
- id: message-service
|
||||||
uri: lb://message-service
|
uri: lb://message-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -76,7 +66,7 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
|
||||||
# ==================== 招投标服务路由 ====================
|
# 招投标服务
|
||||||
- id: bidding-service
|
- id: bidding-service
|
||||||
uri: lb://bidding-service
|
uri: lb://bidding-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -84,7 +74,7 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
|
||||||
# ==================== 平台服务路由 ====================
|
# 平台服务
|
||||||
- id: platform-service
|
- id: platform-service
|
||||||
uri: lb://platform-service
|
uri: lb://platform-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -92,7 +82,7 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
|
||||||
# ==================== 工单服务 WebSocket 路由 ====================
|
# 工单服务 WebSocket
|
||||||
- id: workcase-websocket
|
- id: workcase-websocket
|
||||||
uri: lb:ws://workcase-service
|
uri: lb:ws://workcase-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -100,7 +90,7 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
|
||||||
# ==================== 工单服务路由 ====================
|
# 工单服务
|
||||||
- id: workcase-service
|
- id: workcase-service
|
||||||
uri: lb://workcase-service
|
uri: lb://workcase-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -108,7 +98,7 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
|
||||||
# ==================== 定时任务服务路由 ====================
|
# 定时任务服务
|
||||||
- id: crontab-service
|
- id: crontab-service
|
||||||
uri: lb://crontab-service
|
uri: lb://crontab-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -116,7 +106,7 @@ spring:
|
|||||||
filters:
|
filters:
|
||||||
- StripPrefix=1
|
- StripPrefix=1
|
||||||
|
|
||||||
# ==================== AI 服务路由 ====================
|
# AI 服务
|
||||||
- id: ai-service
|
- id: ai-service
|
||||||
uri: lb://ai-service
|
uri: lb://ai-service
|
||||||
predicates:
|
predicates:
|
||||||
@@ -129,28 +119,14 @@ spring:
|
|||||||
cors-configurations:
|
cors-configurations:
|
||||||
'[/**]':
|
'[/**]':
|
||||||
allowedOriginPatterns: "*"
|
allowedOriginPatterns: "*"
|
||||||
allowedMethods:
|
allowedMethods: [GET, POST, PUT, DELETE, OPTIONS]
|
||||||
- GET
|
|
||||||
- POST
|
|
||||||
- PUT
|
|
||||||
- DELETE
|
|
||||||
- OPTIONS
|
|
||||||
allowedHeaders: "*"
|
allowedHeaders: "*"
|
||||||
allowCredentials: true
|
allowCredentials: true
|
||||||
maxAge: 3600
|
maxAge: 3600
|
||||||
datasource:
|
|
||||||
# 按你的实际库名改一下,比如 urban-lifeline_system
|
# Redis 连接池配置(Gateway 限流用)
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline # 换成你的 PG 库名
|
|
||||||
username: postgres # PG 用户
|
|
||||||
password: postgres # PG 密码
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
# Redis 配置(用于限流、缓存)
|
|
||||||
data:
|
data:
|
||||||
redis:
|
redis:
|
||||||
host: ${REDIS_HOST:localhost}
|
|
||||||
port: ${REDIS_PORT:6379}
|
|
||||||
password: 123456
|
|
||||||
database: 0
|
|
||||||
timeout: 5000ms
|
timeout: 5000ms
|
||||||
lettuce:
|
lettuce:
|
||||||
pool:
|
pool:
|
||||||
@@ -159,18 +135,15 @@ spring:
|
|||||||
max-idle: 10
|
max-idle: 10
|
||||||
min-idle: 5
|
min-idle: 5
|
||||||
|
|
||||||
# 认证配置
|
# ================== Gateway 认证配置 ==================
|
||||||
auth:
|
auth:
|
||||||
enabled: true
|
enabled: true
|
||||||
# gateway-mode 是给下游微服务用的,gateway本身不需要此配置
|
|
||||||
token-header: Authorization
|
token-header: Authorization
|
||||||
token-prefix: "Bearer "
|
token-prefix: "Bearer "
|
||||||
# 认证接口白名单(login/logout/captcha/refresh)
|
|
||||||
login-path: /urban-lifeline/auth/login
|
login-path: /urban-lifeline/auth/login
|
||||||
logout-path: /urban-lifeline/auth/logout
|
logout-path: /urban-lifeline/auth/logout
|
||||||
captcha-path: /urban-lifeline/auth/captcha
|
captcha-path: /urban-lifeline/auth/captcha
|
||||||
refresh-path: /urban-lifeline/auth/refresh
|
refresh-path: /urban-lifeline/auth/refresh
|
||||||
# 通用白名单(Swagger、健康检查等)
|
|
||||||
whitelist:
|
whitelist:
|
||||||
- /actuator/**
|
- /actuator/**
|
||||||
- /v3/api-docs/**
|
- /v3/api-docs/**
|
||||||
@@ -180,20 +153,14 @@ auth:
|
|||||||
- /doc.html
|
- /doc.html
|
||||||
- /favicon.ico
|
- /favicon.ico
|
||||||
- /error
|
- /error
|
||||||
# 各服务的 Swagger 文档
|
|
||||||
- /urban-lifeline/*/v3/api-docs/**
|
- /urban-lifeline/*/v3/api-docs/**
|
||||||
- /urban-lifeline/*/swagger-ui/**
|
- /urban-lifeline/*/swagger-ui/**
|
||||||
# file 服务白名单
|
|
||||||
- /urban-lifeline/file/download/**
|
- /urban-lifeline/file/download/**
|
||||||
# ai 服务白名单
|
|
||||||
- /urban-lifeline/ai/chat/**
|
- /urban-lifeline/ai/chat/**
|
||||||
- /urban-lifeline/system/guest/identify
|
- /urban-lifeline/system/guest/identify
|
||||||
# workcase 会议入口白名单(支持URL参数token认证)
|
|
||||||
- /urban-lifeline/workcase/meeting/*/entry
|
- /urban-lifeline/workcase/meeting/*/entry
|
||||||
security:
|
|
||||||
aes:
|
# ================== Actuator ==================
|
||||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI= # Base64 编码,32字节(256位)
|
|
||||||
# Actuator 监控端点
|
|
||||||
management:
|
management:
|
||||||
endpoints:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
@@ -202,12 +169,3 @@ management:
|
|||||||
endpoint:
|
endpoint:
|
||||||
health:
|
health:
|
||||||
show-details: always
|
show-details: always
|
||||||
|
|
||||||
# 日志配置(详细配置见 log4j2.xml)
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
# ================== Server ==================
|
# ================== Message 消息服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8185
|
port: 8085
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/message # 微服务架构下,context-path由Gateway管理
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
spring:
|
||||||
|
application:
|
||||||
|
name: message-service
|
||||||
|
|
||||||
|
# ================== Auth ==================
|
||||||
auth:
|
auth:
|
||||||
enabled: true
|
enabled: true
|
||||||
gateway-mode: true
|
gateway-mode: true
|
||||||
@@ -18,74 +19,18 @@ auth:
|
|||||||
- /error
|
- /error
|
||||||
- /actuator/health
|
- /actuator/health
|
||||||
- /actuator/info
|
- /actuator/info
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
secret-key: 1234567890qwer
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: message-service
|
|
||||||
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
|
||||||
data:
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
|
||||||
port: 6379
|
|
||||||
database: 0
|
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
# ================== SpringDoc ==================
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
group-configs:
|
group-configs:
|
||||||
- group: 'default'
|
- group: 'default'
|
||||||
display-name: '消息服务 API'
|
display-name: '消息服务 API'
|
||||||
paths-to-match: '/**'
|
paths-to-match: '/**'
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
# ================== Dubbo ==================
|
||||||
dubbo:
|
dubbo:
|
||||||
application:
|
application:
|
||||||
name: urban-lifeline-message
|
name: urban-lifeline-message
|
||||||
qos-enable: false
|
qos-enable: false
|
||||||
protocol:
|
|
||||||
name: dubbo
|
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
scan:
|
||||||
base-packages: org.xyzh.message.service.impl
|
base-packages: org.xyzh.message.service.impl
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
|
|
||||||
# ================== Logging ==================
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
# ================== Server ==================
|
# ================== Platform 平台服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8187
|
port: 8089
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/platform # 微服务架构下,context-path由Gateway管理
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
spring:
|
||||||
|
application:
|
||||||
|
name: platform-service
|
||||||
|
|
||||||
|
# ================== Auth ==================
|
||||||
auth:
|
auth:
|
||||||
enabled: true
|
enabled: true
|
||||||
gateway-mode: true
|
gateway-mode: true
|
||||||
@@ -19,74 +20,17 @@ auth:
|
|||||||
- /actuator/health
|
- /actuator/health
|
||||||
- /actuator/info
|
- /actuator/info
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
secret-key: 1234567890qwer
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: platform-service
|
|
||||||
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
|
||||||
data:
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
|
||||||
port: 6379
|
|
||||||
database: 0
|
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
# ================== SpringDoc ==================
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
group-configs:
|
group-configs:
|
||||||
- group: 'default'
|
- group: 'default'
|
||||||
display-name: '平台服务 API'
|
display-name: '平台服务 API'
|
||||||
paths-to-match: '/**'
|
paths-to-match: '/**'
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
# ================== Dubbo ==================
|
||||||
dubbo:
|
dubbo:
|
||||||
application:
|
application:
|
||||||
name: urban-lifeline-platform
|
name: urban-lifeline-platform
|
||||||
qos-enable: false
|
qos-enable: false
|
||||||
protocol:
|
|
||||||
name: dubbo
|
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
scan:
|
||||||
base-packages: org.xyzh.platform.service.impl
|
base-packages: org.xyzh.platform.service.impl
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
|
|
||||||
# ================== Logging ==================
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
# ================== Server ==================
|
|
||||||
server:
|
|
||||||
port: 8182
|
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/system # 微服务架构下,context-path由Gateway管理
|
|
||||||
# ================== Auth ====================
|
|
||||||
|
|
||||||
auth:
|
|
||||||
enabled: true
|
|
||||||
gateway-mode: true
|
|
||||||
# 认证接口:可以按服务自定义
|
|
||||||
login-path: /urban-lifeline/auth/login
|
|
||||||
logout-path: /urban-lifeline/auth/logout
|
|
||||||
captcha-path: /urban-lifeline/auth/captcha
|
|
||||||
refresh-path: /urban-lifeline/auth/refresh
|
|
||||||
|
|
||||||
# 通用白名单(非认证接口)
|
|
||||||
whitelist:
|
|
||||||
# Swagger/OpenAPI 文档相关(建议不带 context-path)
|
|
||||||
- /swagger-ui/**
|
|
||||||
- /swagger-ui.html
|
|
||||||
- /v3/api-docs/**
|
|
||||||
- /webjars/**
|
|
||||||
|
|
||||||
# 静态资源
|
|
||||||
- /favicon.ico
|
|
||||||
- /error
|
|
||||||
|
|
||||||
# 健康检查
|
|
||||||
- /actuator/health
|
|
||||||
- /actuator/info
|
|
||||||
- /system/guest/identify
|
|
||||||
# 其他需要放行的路径
|
|
||||||
# - /public/**
|
|
||||||
# - /api/public/**
|
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
# AES-256 密钥(Base64编码)
|
|
||||||
# 警告:这是开发环境密钥,生产环境请使用密钥管理系统
|
|
||||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: system-service
|
|
||||||
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
# 按你的实际库名改一下,比如 urban-lifeline_system
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline # 换成你的 PG 库名
|
|
||||||
username: postgres # PG 用户
|
|
||||||
password: postgres # PG 密码
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
|
||||||
data:
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
|
||||||
port: 6379
|
|
||||||
database: 0
|
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
|
||||||
# ================== SpringDoc ==================
|
|
||||||
springdoc:
|
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
try-it-out-enabled: true
|
|
||||||
show-common-extensions: true
|
|
||||||
show-extensions: true
|
|
||||||
show-request-duration: true
|
|
||||||
filter: true
|
|
||||||
tags-sorter: alpha
|
|
||||||
operations-sorter: alpha
|
|
||||||
group-configs:
|
|
||||||
- group: 'default'
|
|
||||||
display-name: '系统服务 API'
|
|
||||||
paths-to-match: '/**'
|
|
||||||
|
|
||||||
# ================== Dubbo + Nacos 注册中心 ==================
|
|
||||||
dubbo:
|
|
||||||
application:
|
|
||||||
name: urban-lifeline-system
|
|
||||||
qos-enable: false
|
|
||||||
|
|
||||||
protocol:
|
|
||||||
name: dubbo
|
|
||||||
port: -1 # -1 表示随机端口,避免端口冲突;也可以写死一个端口
|
|
||||||
|
|
||||||
registry:
|
|
||||||
# Nacos 注册中心地址:使用 docker-compose 中映射到宿主机的 8848 端口
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
# 如果 Nacos 有用户名密码,可以加上:
|
|
||||||
# username: nacos
|
|
||||||
# password: nacos
|
|
||||||
|
|
||||||
# Dubbo 服务扫描包(你 @DubboService 标注的位置)
|
|
||||||
scan:
|
|
||||||
base-packages: org.xyzh.system.service.impl
|
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
|
|
||||||
# ================== Logging ==================
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
@@ -1,83 +1,32 @@
|
|||||||
# ================== Server ==================
|
# ================== System 系统服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8182
|
port: 8082
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/system # 微服务架构下,context-path由Gateway管理
|
|
||||||
# ================== Auth ====================
|
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: system-service
|
||||||
|
|
||||||
|
# ================== Auth ==================
|
||||||
auth:
|
auth:
|
||||||
enabled: true
|
enabled: true
|
||||||
gateway-mode: true
|
gateway-mode: true
|
||||||
# 认证接口:可以按服务自定义
|
|
||||||
login-path: /urban-lifeline/auth/login
|
|
||||||
logout-path: /urban-lifeline/auth/logout
|
|
||||||
captcha-path: /urban-lifeline/auth/captcha
|
|
||||||
refresh-path: /urban-lifeline/auth/refresh
|
|
||||||
|
|
||||||
# 通用白名单(非认证接口)
|
|
||||||
whitelist:
|
whitelist:
|
||||||
# Swagger/OpenAPI 文档相关(建议不带 context-path)
|
|
||||||
- /swagger-ui/**
|
- /swagger-ui/**
|
||||||
- /swagger-ui.html
|
- /swagger-ui.html
|
||||||
- /v3/api-docs/**
|
- /v3/api-docs/**
|
||||||
- /webjars/**
|
- /webjars/**
|
||||||
|
|
||||||
# 静态资源
|
|
||||||
- /favicon.ico
|
- /favicon.ico
|
||||||
- /error
|
- /error
|
||||||
|
|
||||||
# 健康检查
|
|
||||||
- /actuator/health
|
- /actuator/health
|
||||||
- /actuator/info
|
- /actuator/info
|
||||||
- /system/guest/identify
|
- /system/guest/identify
|
||||||
# 其他需要放行的路径
|
|
||||||
# - /public/**
|
|
||||||
# - /api/public/**
|
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: system-service
|
|
||||||
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
# 按你的实际库名改一下,比如 urban-lifeline_system
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline # 换成你的 PG 库名
|
|
||||||
username: postgres # PG 用户
|
|
||||||
password: postgres # PG 密码
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
|
||||||
data:
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
|
||||||
port: 6379
|
|
||||||
database: 0
|
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
|
||||||
# ================== SpringDoc ==================
|
# ================== SpringDoc ==================
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
swagger-ui:
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
try-it-out-enabled: true
|
try-it-out-enabled: true
|
||||||
show-common-extensions: true
|
show-common-extensions: true
|
||||||
show-extensions: true
|
show-extensions: true
|
||||||
show-request-duration: true
|
|
||||||
filter: true
|
filter: true
|
||||||
tags-sorter: alpha
|
tags-sorter: alpha
|
||||||
operations-sorter: alpha
|
operations-sorter: alpha
|
||||||
@@ -86,37 +35,10 @@ springdoc:
|
|||||||
display-name: '系统服务 API'
|
display-name: '系统服务 API'
|
||||||
paths-to-match: '/**'
|
paths-to-match: '/**'
|
||||||
|
|
||||||
# ================== Dubbo + Nacos 注册中心 ==================
|
# ================== Dubbo ==================
|
||||||
dubbo:
|
dubbo:
|
||||||
application:
|
application:
|
||||||
name: urban-lifeline-system
|
name: urban-lifeline-system
|
||||||
qos-enable: false
|
qos-enable: false
|
||||||
|
|
||||||
protocol:
|
|
||||||
name: dubbo
|
|
||||||
port: -1 # -1 表示随机端口,避免端口冲突;也可以写死一个端口
|
|
||||||
|
|
||||||
registry:
|
|
||||||
# Nacos 注册中心地址:使用 docker-compose 中映射到宿主机的 8848 端口
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
# 如果 Nacos 有用户名密码,可以加上:
|
|
||||||
# username: nacos
|
|
||||||
# password: nacos
|
|
||||||
|
|
||||||
# Dubbo 服务扫描包(你 @DubboService 标注的位置)
|
|
||||||
scan:
|
scan:
|
||||||
base-packages: org.xyzh.system.service.impl
|
base-packages: org.xyzh.system.service.impl
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
|
|
||||||
# ================== Logging ==================
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
# ================== Server ==================
|
|
||||||
server:
|
|
||||||
port: 8088
|
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/workcase
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
|
||||||
auth:
|
|
||||||
enabled: true
|
|
||||||
gate-way: true
|
|
||||||
whitelist:
|
|
||||||
- /swagger-ui/**
|
|
||||||
- /swagger-ui.html
|
|
||||||
- /v3/api-docs/**
|
|
||||||
- /webjars/**
|
|
||||||
- /favicon.ico
|
|
||||||
- /error
|
|
||||||
- /actuator/health
|
|
||||||
- /actuator/info
|
|
||||||
# 微信客服回调接口(无需鉴权)
|
|
||||||
- /workcase/chat/kefu/callback
|
|
||||||
# CRM回调接口(无需鉴权,但需签名验证)
|
|
||||||
- /workcase/receive/crm
|
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
# AES-256 密钥(Base64编码,必须与所有服务保持一致)
|
|
||||||
# 警告:这是开发环境密钥,生产环境请使用密钥管理系统
|
|
||||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: workcase-service
|
|
||||||
# 文件上传配置
|
|
||||||
servlet:
|
|
||||||
multipart:
|
|
||||||
enabled: true
|
|
||||||
max-file-size: 500MB
|
|
||||||
max-request-size: 500MB
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
|
||||||
data:
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1
|
|
||||||
port: 6379
|
|
||||||
database: 0
|
|
||||||
# password: ""
|
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
|
||||||
springdoc:
|
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
group-configs:
|
|
||||||
- group: 'default'
|
|
||||||
display-name: '工单服务 API'
|
|
||||||
paths-to-match: '/**'
|
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
|
||||||
dubbo:
|
|
||||||
application:
|
|
||||||
name: urban-lifeline-workcase
|
|
||||||
qos-enable: false
|
|
||||||
protocol:
|
|
||||||
payload: 110100480
|
|
||||||
name: dubbo
|
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
|
||||||
base-packages: org.xyzh.workcase.service.impl
|
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
|
||||||
logging:
|
|
||||||
config: classpath:log4j2.xml
|
|
||||||
charset:
|
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
|
|
||||||
# ================== Jitsi Meet 视频会议配置 ==================
|
|
||||||
jitsi:
|
|
||||||
app:
|
|
||||||
# 应用ID(必须与Docker配置中的JWT_APP_ID一致)
|
|
||||||
id: urbanLifeline
|
|
||||||
# JWT密钥(必须与Docker配置中的JWT_APP_SECRET一致)
|
|
||||||
# 警告:生产环境请修改为强随机字符串,并妥善保管
|
|
||||||
# 注意:HS256算法要求密钥长度至少32字节(256 bits)
|
|
||||||
secret: urbanLifeline-jitsi-secret-key-2025-production-safe-hs256
|
|
||||||
server:
|
|
||||||
# Jitsi Meet服务器地址(独立子域名)
|
|
||||||
url: https://org.xyzh.yslg.jitsi
|
|
||||||
token:
|
|
||||||
# JWT Token有效期(毫秒)- 默认2小时
|
|
||||||
expiration: 7200000
|
|
||||||
@@ -1,10 +1,17 @@
|
|||||||
# ================== Server ==================
|
# ================== Workcase 工单服务配置 ==================
|
||||||
server:
|
server:
|
||||||
port: 8188
|
port: 8088
|
||||||
# servlet:
|
|
||||||
# context-path: /urban-lifeline/workcase # 微服务架构下,context-path由Gateway管理
|
|
||||||
|
|
||||||
# ================== Auth ====================
|
spring:
|
||||||
|
application:
|
||||||
|
name: workcase-service
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
enabled: true
|
||||||
|
max-file-size: 500MB
|
||||||
|
max-request-size: 500MB
|
||||||
|
|
||||||
|
# ================== Auth ==================
|
||||||
auth:
|
auth:
|
||||||
enabled: true
|
enabled: true
|
||||||
gateway-mode: true
|
gateway-mode: true
|
||||||
@@ -17,81 +24,32 @@ auth:
|
|||||||
- /error
|
- /error
|
||||||
- /actuator/health
|
- /actuator/health
|
||||||
- /actuator/info
|
- /actuator/info
|
||||||
# 微信客服回调接口(无需鉴权)
|
|
||||||
- /workcase/chat/kefu/callback
|
- /workcase/chat/kefu/callback
|
||||||
# CRM回调接口(无需鉴权,但需签名验证)
|
|
||||||
- /workcase/receive/crm
|
- /workcase/receive/crm
|
||||||
|
|
||||||
security:
|
|
||||||
aes:
|
|
||||||
# AES-256 密钥(Base64编码,必须与所有服务保持一致)
|
|
||||||
# 警告:这是开发环境密钥,生产环境请使用密钥管理系统
|
|
||||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
|
|
||||||
|
|
||||||
# ================== Spring ==================
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: workcase-service
|
|
||||||
|
|
||||||
# ================== Spring Cloud Nacos ==================
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
namespace: dev
|
|
||||||
group: DEFAULT_GROUP
|
|
||||||
|
|
||||||
# ================== DataSource ==================
|
|
||||||
datasource:
|
|
||||||
url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline
|
|
||||||
username: postgres
|
|
||||||
password: postgres
|
|
||||||
driver-class-name: org.postgresql.Driver
|
|
||||||
|
|
||||||
# ================== Redis ==================
|
|
||||||
data:
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改
|
|
||||||
port: 6379
|
|
||||||
database: 0
|
|
||||||
password: 123456 # 如果有密码就填上,没密码可以去掉这一行
|
|
||||||
|
|
||||||
# ================== SpringDoc ==================
|
# ================== SpringDoc ==================
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
path: /v3/api-docs
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
path: /swagger-ui.html
|
|
||||||
group-configs:
|
group-configs:
|
||||||
- group: 'default'
|
- group: 'default'
|
||||||
display-name: '工单服务 API'
|
display-name: '工单服务 API'
|
||||||
paths-to-match: '/**'
|
paths-to-match: '/**'
|
||||||
|
|
||||||
# ================== Dubbo + Nacos ==================
|
# ================== Dubbo ==================
|
||||||
dubbo:
|
dubbo:
|
||||||
application:
|
application:
|
||||||
name: urban-lifeline-workcase
|
name: urban-lifeline-workcase
|
||||||
qos-enable: false
|
qos-enable: false
|
||||||
protocol:
|
protocol:
|
||||||
name: dubbo
|
payload: 110100480
|
||||||
port: -1
|
|
||||||
registry:
|
|
||||||
address: nacos://127.0.0.1:8848
|
|
||||||
scan:
|
scan:
|
||||||
base-packages: org.xyzh.workcase.service.impl
|
base-packages: org.xyzh.workcase.service.impl
|
||||||
|
|
||||||
# ================== MyBatis ==================
|
# ================== Jitsi Meet 视频会议配置 ==================
|
||||||
mybatis-plus:
|
jitsi:
|
||||||
mapper-locations: classpath:mapper/**/*.xml
|
app:
|
||||||
type-aliases-package: org.xyzh.common.dto, org.xyzh.api
|
id: ${JITSI_APP_ID:urbanLifeline}
|
||||||
|
secret: ${JITSI_APP_SECRET:urbanLifeline-jitsi-secret-key-2025-production-safe-hs256}
|
||||||
# ================== Logging ==================
|
server:
|
||||||
logging:
|
url: ${JITSI_SERVER_URL:https://org.xyzh.yslg.jitsi}
|
||||||
config: classpath:log4j2.xml
|
token:
|
||||||
charset:
|
expiration: 7200000
|
||||||
console: UTF-8
|
|
||||||
file: UTF-8
|
|
||||||
level:
|
|
||||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
|
|
||||||
|
|||||||
@@ -1,24 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* @description 应用运行时配置文件
|
* @description 应用运行时配置文件 (支持 Docker 环境变量替换)
|
||||||
* @author yslg
|
|
||||||
* @since 2025-12-06
|
|
||||||
*
|
*
|
||||||
* 说明:
|
* 占位符说明:
|
||||||
* 1. 此文件在生产环境中被加载,用于覆盖内置配置
|
* - __PLACEHOLDER__ 格式的值会在 Docker 启动时被环境变量替换
|
||||||
* 2. Docker 部署时,可通过挂载此文件来修改配置,无需重新构建
|
* - 如果环境变量未设置,将使用默认值
|
||||||
* 3. 配置结构必须与 packages/shared/src/config/index.ts 中的 AppRuntimeConfig 保持一致
|
|
||||||
*
|
*
|
||||||
* 使用示例(Docker):
|
* Docker 部署:
|
||||||
* docker run -v /path/to/app-config.js:/app/public/app-config.js my-app:latest
|
* 1. 通过 volume 挂载覆盖此文件
|
||||||
|
* 2. 或通过启动脚本替换占位符
|
||||||
*/
|
*/
|
||||||
|
|
||||||
window.APP_RUNTIME_CONFIG = {
|
window.APP_RUNTIME_CONFIG = {
|
||||||
// 环境标识
|
// 环境标识
|
||||||
env: 'production',
|
env: '__APP_ENV__',
|
||||||
|
|
||||||
// API 配置
|
// API 配置
|
||||||
api: {
|
api: {
|
||||||
baseUrl: '/api',
|
baseUrl: '__API_BASE_URL__',
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -27,12 +25,12 @@ window.APP_RUNTIME_CONFIG = {
|
|||||||
|
|
||||||
// 文件配置
|
// 文件配置
|
||||||
file: {
|
file: {
|
||||||
downloadUrl: '/api/urban-lifeline/file/download/',
|
downloadUrl: '__API_BASE_URL__/urban-lifeline/file/download/',
|
||||||
uploadUrl: '/api/urban-lifeline/file/upload',
|
uploadUrl: '__API_BASE_URL__/urban-lifeline/file/upload',
|
||||||
maxSize: {
|
maxSize: {
|
||||||
image: 5, // MB
|
image: 5,
|
||||||
video: 100, // MB
|
video: 100,
|
||||||
document: 10 // MB
|
document: 10
|
||||||
},
|
},
|
||||||
acceptTypes: {
|
acceptTypes: {
|
||||||
image: 'image/*',
|
image: 'image/*',
|
||||||
@@ -44,20 +42,23 @@ window.APP_RUNTIME_CONFIG = {
|
|||||||
// Token 配置
|
// Token 配置
|
||||||
token: {
|
token: {
|
||||||
key: 'token',
|
key: 'token',
|
||||||
refreshThreshold: 300000 // 5分钟
|
refreshThreshold: 300000
|
||||||
},
|
},
|
||||||
|
|
||||||
// 公共资源路径
|
// 公共资源路径
|
||||||
publicImgPath: '/img',
|
publicImgPath: '__PUBLIC_PATH__/img',
|
||||||
publicWebPath: '/',
|
publicWebPath: '__PUBLIC_PATH__',
|
||||||
|
|
||||||
// 单点登录配置
|
// 单点登录配置
|
||||||
sso: {
|
sso: {
|
||||||
platformUrl: '/', // platform 平台地址
|
platformUrl: '__SSO_PLATFORM_URL__',
|
||||||
workcaseUrl: '/workcase', // workcase 服务地址
|
workcaseUrl: '__SSO_WORKCASE_URL__',
|
||||||
biddingUrl: '/bidding' // bidding 服务地址
|
biddingUrl: '__SSO_BIDDING_URL__'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// AES 加密密钥
|
||||||
|
aesSecretKey: '__AES_SECRET_KEY__',
|
||||||
|
|
||||||
// 功能开关
|
// 功能开关
|
||||||
features: {
|
features: {
|
||||||
enableDebug: false,
|
enableDebug: false,
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* @description Bidding 应用运行时配置
|
* @description 应用运行时配置
|
||||||
* @author yslg
|
|
||||||
* @since 2025-12-06
|
|
||||||
*
|
*
|
||||||
* 配置加载策略:
|
* 配置加载策略:
|
||||||
* 1. 开发环境:使用下面定义的开发配置
|
* 1. 开发环境:使用内置开发配置
|
||||||
* 2. 生产环境:从 window.APP_RUNTIME_CONFIG 读取(来自 app-config.js)
|
* 2. 生产环境:从 window.APP_RUNTIME_CONFIG 读取(来自 app-config.js)
|
||||||
* 3. Docker部署:替换 app-config.js 文件实现配置外挂
|
* 3. Docker部署:启动时替换 app-config.js 中的占位符
|
||||||
*
|
|
||||||
* 配置结构说明:
|
|
||||||
* 此文件的配置结构与 app-config.js 完全对应
|
|
||||||
* 修改 app-config.js 后,这里的配置会自动应用
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
@@ -43,12 +37,12 @@ export interface AppRuntimeConfig {
|
|||||||
};
|
};
|
||||||
publicImgPath: string;
|
publicImgPath: string;
|
||||||
publicWebPath: string;
|
publicWebPath: string;
|
||||||
// 单点登录配置
|
|
||||||
sso?: {
|
sso?: {
|
||||||
platformUrl: string; // platform 平台地址
|
platformUrl: string;
|
||||||
workcaseUrl: string; // workcase 服务地址
|
workcaseUrl: string;
|
||||||
biddingUrl: string; // bidding 服务地址
|
biddingUrl: string;
|
||||||
};
|
};
|
||||||
|
aesSecretKey?: string;
|
||||||
features?: {
|
features?: {
|
||||||
enableDebug?: boolean;
|
enableDebug?: boolean;
|
||||||
enableMockData?: boolean;
|
enableMockData?: boolean;
|
||||||
@@ -57,101 +51,80 @@ export interface AppRuntimeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 配置定义(与 app-config.js 结构一致)
|
// 环境检测
|
||||||
// ============================================
|
// ============================================
|
||||||
const isDev = (import.meta as any).env?.DEV ?? false;
|
const isDev = (import.meta as any).env?.DEV ?? false;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
// 开发环境配置
|
// 开发环境配置
|
||||||
|
// ============================================
|
||||||
const devConfig: AppRuntimeConfig = {
|
const devConfig: AppRuntimeConfig = {
|
||||||
env: 'development',
|
env: 'development',
|
||||||
|
|
||||||
api: {
|
api: {
|
||||||
// 开发环境通过 Vite 代理转发到后端,避免浏览器直接跨域
|
|
||||||
// 实际请求路径示例:/api/... → 由代理转发到实际后端
|
|
||||||
baseUrl: '/api',
|
baseUrl: '/api',
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
},
|
},
|
||||||
|
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
|
||||||
file: {
|
file: {
|
||||||
// 通过 Nginx → Gateway 访问文件服务,使用 /urban-lifeline 前缀
|
|
||||||
downloadUrl: '/api/urban-lifeline/file/download/',
|
downloadUrl: '/api/urban-lifeline/file/download/',
|
||||||
uploadUrl: '/api/urban-lifeline/file/upload',
|
uploadUrl: '/api/urban-lifeline/file/upload',
|
||||||
maxSize: {
|
maxSize: { image: 5, video: 100, document: 10 },
|
||||||
image: 5,
|
|
||||||
video: 100,
|
|
||||||
document: 10
|
|
||||||
},
|
|
||||||
acceptTypes: {
|
acceptTypes: {
|
||||||
image: 'image/*',
|
image: 'image/*',
|
||||||
video: 'video/*',
|
video: 'video/*',
|
||||||
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
token: {
|
token: {
|
||||||
key: 'token',
|
key: 'token',
|
||||||
refreshThreshold: 300000
|
refreshThreshold: 300000
|
||||||
},
|
},
|
||||||
|
publicImgPath: '/img',
|
||||||
publicImgPath: 'http://localhost:7002/img',
|
publicWebPath: '/',
|
||||||
publicWebPath: 'http://localhost:7002',
|
|
||||||
|
|
||||||
// 单点登录配置
|
|
||||||
sso: {
|
sso: {
|
||||||
platformUrl: '/', // 通过nginx访问platform
|
platformUrl: '/',
|
||||||
workcaseUrl: '/workcase', // 通过nginx访问workcase
|
workcaseUrl: '/workcase',
|
||||||
biddingUrl: '/bidding' // 通过nginx访问bidding
|
biddingUrl: '/bidding'
|
||||||
},
|
},
|
||||||
|
aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=',
|
||||||
features: {
|
features: {
|
||||||
enableDebug: true,
|
enableDebug: true,
|
||||||
enableMockData: false
|
enableMockData: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================
|
||||||
// 生产环境默认配置(兜底)
|
// 生产环境默认配置(兜底)
|
||||||
|
// ============================================
|
||||||
const prodDefaultConfig: AppRuntimeConfig = {
|
const prodDefaultConfig: AppRuntimeConfig = {
|
||||||
env: 'production',
|
env: 'production',
|
||||||
|
|
||||||
api: {
|
api: {
|
||||||
baseUrl: '/api',
|
baseUrl: '/api',
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
},
|
},
|
||||||
|
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
|
||||||
file: {
|
file: {
|
||||||
downloadUrl: '/api/urban-lifeline/file/download/',
|
downloadUrl: '/api/urban-lifeline/file/download/',
|
||||||
uploadUrl: '/api/urban-lifeline/file/upload',
|
uploadUrl: '/api/urban-lifeline/file/upload',
|
||||||
maxSize: {
|
maxSize: { image: 5, video: 100, document: 10 },
|
||||||
image: 5,
|
|
||||||
video: 100,
|
|
||||||
document: 10
|
|
||||||
},
|
|
||||||
acceptTypes: {
|
acceptTypes: {
|
||||||
image: 'image/*',
|
image: 'image/*',
|
||||||
video: 'video/*',
|
video: 'video/*',
|
||||||
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
token: {
|
token: {
|
||||||
key: 'token',
|
key: 'token',
|
||||||
refreshThreshold: 300000
|
refreshThreshold: 300000
|
||||||
},
|
},
|
||||||
|
|
||||||
publicImgPath: '/img',
|
publicImgPath: '/img',
|
||||||
publicWebPath: '/',
|
publicWebPath: '/',
|
||||||
|
|
||||||
// 单点登录配置(生产环境通过nginx代理)
|
|
||||||
sso: {
|
sso: {
|
||||||
platformUrl: '/',
|
platformUrl: '/',
|
||||||
workcaseUrl: '/workcase',
|
workcaseUrl: '/workcase',
|
||||||
biddingUrl: '/bidding'
|
biddingUrl: '/bidding'
|
||||||
},
|
},
|
||||||
|
aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=',
|
||||||
features: {
|
features: {
|
||||||
enableDebug: false,
|
enableDebug: false,
|
||||||
enableMockData: false
|
enableMockData: false
|
||||||
@@ -162,92 +135,82 @@ const prodDefaultConfig: AppRuntimeConfig = {
|
|||||||
// 配置加载
|
// 配置加载
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查值是否为未替换的占位符
|
||||||
|
*/
|
||||||
|
const isPlaceholder = (value: any): boolean => {
|
||||||
|
return typeof value === 'string' && value.startsWith('__') && value.endsWith('__');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 深度合并配置,跳过占位符值
|
||||||
|
*/
|
||||||
|
const mergeConfig = (target: any, source: any): any => {
|
||||||
|
const result = { ...target };
|
||||||
|
for (const key in source) {
|
||||||
|
const value = source[key];
|
||||||
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
||||||
|
result[key] = mergeConfig(target[key] || {}, value);
|
||||||
|
} else if (!isPlaceholder(value)) {
|
||||||
|
result[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取运行时配置
|
* 获取运行时配置
|
||||||
* 生产环境优先从 window.APP_RUNTIME_CONFIG 读取(app-config.js 注入)
|
|
||||||
*/
|
*/
|
||||||
const getRuntimeConfig = (): AppRuntimeConfig => {
|
const getRuntimeConfig = (): AppRuntimeConfig => {
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
console.log('[配置] 开发环境,使用内置配置');
|
console.log('[Config] 开发环境,使用内置配置');
|
||||||
return devConfig;
|
return devConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生产环境:尝试读取外部配置
|
|
||||||
try {
|
try {
|
||||||
const runtimeConfig = (window as any).APP_RUNTIME_CONFIG;
|
const runtimeConfig = (window as any).APP_RUNTIME_CONFIG;
|
||||||
if (runtimeConfig && typeof runtimeConfig === 'object') {
|
if (runtimeConfig && typeof runtimeConfig === 'object') {
|
||||||
console.log('[配置] 加载外部配置 app-config.js');
|
const merged = mergeConfig(prodDefaultConfig, runtimeConfig);
|
||||||
console.log('[配置] API地址:', runtimeConfig.api?.baseUrl);
|
console.log('[Config] 加载运行时配置', merged);
|
||||||
console.log('[配置] 环境:', runtimeConfig.env || 'production');
|
return merged;
|
||||||
return runtimeConfig as AppRuntimeConfig;
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[配置] 无法读取外部配置,使用默认配置', e);
|
console.warn('[Config] 无法读取外部配置', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[配置] 使用默认生产配置');
|
console.log('[Config] 使用默认生产配置');
|
||||||
return prodDefaultConfig;
|
return prodDefaultConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 当前应用配置
|
// 当前配置
|
||||||
const config = getRuntimeConfig();
|
const config = getRuntimeConfig();
|
||||||
console.log('[配置] 当前配置', config);
|
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 导出配置(向后兼容)
|
// 导出
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
// 单独导出常用配置项
|
// AES 密钥
|
||||||
|
export const AES_SECRET_KEY = config.aesSecretKey || 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=';
|
||||||
|
|
||||||
|
// 常用配置项
|
||||||
export const API_BASE_URL = config.api.baseUrl;
|
export const API_BASE_URL = config.api.baseUrl;
|
||||||
export const FILE_DOWNLOAD_URL = config.file.downloadUrl;
|
export const FILE_DOWNLOAD_URL = config.file.downloadUrl;
|
||||||
|
export const FILE_UPLOAD_URL = config.file.uploadUrl;
|
||||||
export const PUBLIC_IMG_PATH = config.publicImgPath;
|
export const PUBLIC_IMG_PATH = config.publicImgPath;
|
||||||
export const PUBLIC_WEB_PATH = config.publicWebPath;
|
export const PUBLIC_WEB_PATH = config.publicWebPath;
|
||||||
|
|
||||||
// 导出完整配置对象
|
// 完整配置对象
|
||||||
export const APP_CONFIG = {
|
export const APP_CONFIG = {
|
||||||
// 应用标题
|
|
||||||
title: '泰豪电源招投标系统',
|
title: '泰豪电源招投标系统',
|
||||||
|
|
||||||
// 环境标识
|
|
||||||
env: config.env || 'production',
|
env: config.env || 'production',
|
||||||
|
|
||||||
// 应用基础路径
|
|
||||||
baseUrl: config.baseUrl,
|
baseUrl: config.baseUrl,
|
||||||
|
api: config.api,
|
||||||
// API 配置
|
file: config.file,
|
||||||
api: {
|
token: config.token,
|
||||||
baseUrl: config.api.baseUrl,
|
|
||||||
timeout: config.api.timeout
|
|
||||||
},
|
|
||||||
|
|
||||||
// 文件配置
|
|
||||||
file: {
|
|
||||||
downloadUrl: config.file.downloadUrl,
|
|
||||||
uploadUrl: config.file.uploadUrl,
|
|
||||||
maxSize: config.file.maxSize,
|
|
||||||
acceptTypes: config.file.acceptTypes
|
|
||||||
},
|
|
||||||
|
|
||||||
// Token 配置
|
|
||||||
token: {
|
|
||||||
key: config.token.key,
|
|
||||||
refreshThreshold: config.token.refreshThreshold
|
|
||||||
},
|
|
||||||
|
|
||||||
// 公共路径
|
|
||||||
publicImgPath: config.publicImgPath,
|
publicImgPath: config.publicImgPath,
|
||||||
publicWebPath: config.publicWebPath,
|
publicWebPath: config.publicWebPath,
|
||||||
|
sso: config.sso || { platformUrl: '/', workcaseUrl: '/workcase', biddingUrl: '/bidding' },
|
||||||
// 单点登录配置
|
|
||||||
sso: config.sso || {
|
|
||||||
platformUrl: '/',
|
|
||||||
workcaseUrl: '/workcase',
|
|
||||||
biddingUrl: '/bidding'
|
|
||||||
},
|
|
||||||
|
|
||||||
// 功能开关
|
|
||||||
features: config.features || {}
|
features: config.features || {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 默认导出
|
|
||||||
export default APP_CONFIG;
|
export default APP_CONFIG;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
|
import { federation } from '@module-federation/vite'
|
||||||
import { resolve, dirname } from 'path'
|
import { resolve, dirname } from 'path'
|
||||||
import { fileURLToPath } from 'url'
|
import { fileURLToPath } from 'url'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
@@ -8,61 +9,95 @@ import fs from 'fs'
|
|||||||
const __filename = fileURLToPath(import.meta.url)
|
const __filename = fileURLToPath(import.meta.url)
|
||||||
const __dirname = dirname(__filename)
|
const __dirname = dirname(__filename)
|
||||||
|
|
||||||
export default defineConfig(({ mode }) => ({
|
// 开发环境 shared 模块地址
|
||||||
// 开发和生产环境都通过nginx代理访问/bidding
|
const DEV_SHARED_URL = 'https://localhost:7000/shared/mf-manifest.json'
|
||||||
base: '/bidding/',
|
// 生产环境使用相对路径,通过 Nginx 代理访问
|
||||||
|
const PROD_SHARED_URL = '/shared/mf-manifest.json'
|
||||||
plugins: [
|
|
||||||
vue({
|
export default defineConfig(({ mode }) => {
|
||||||
script: {
|
const isDev = mode === 'development'
|
||||||
defineModel: true,
|
const sharedEntry = isDev ? DEV_SHARED_URL : PROD_SHARED_URL
|
||||||
propsDestructure: true
|
|
||||||
}
|
return {
|
||||||
}),
|
base: '/bidding/',
|
||||||
vueJsx()
|
|
||||||
],
|
plugins: [
|
||||||
|
vue({
|
||||||
define: {
|
script: {
|
||||||
__VUE_OPTIONS_API__: true,
|
defineModel: true,
|
||||||
__VUE_PROD_DEVTOOLS__: true,
|
propsDestructure: true
|
||||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true
|
}
|
||||||
},
|
}),
|
||||||
|
vueJsx(),
|
||||||
resolve: {
|
federation({
|
||||||
alias: {
|
name: 'bidding',
|
||||||
'@': resolve(__dirname, 'src')
|
remotes: {
|
||||||
}
|
shared: {
|
||||||
},
|
type: 'module',
|
||||||
|
name: 'shared',
|
||||||
server: {
|
entry: sharedEntry
|
||||||
port: 7002,
|
}
|
||||||
host: true,
|
},
|
||||||
cors: true,
|
shared: {
|
||||||
open: '/bidding/', // 开发时自动打开到 /bidding/ 路径
|
vue: {},
|
||||||
// HTTPS 配置(使用 mkcert 生成的本地开发证书)
|
'vue-router': {},
|
||||||
https: {
|
'element-plus': {},
|
||||||
key: fs.readFileSync('C:/Users/FK05/443/localhost+3-key.pem'),
|
axios: {}
|
||||||
cert: fs.readFileSync('C:/Users/FK05/443/localhost+3.pem')
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
|
define: {
|
||||||
|
__VUE_OPTIONS_API__: true,
|
||||||
|
__VUE_PROD_DEVTOOLS__: true,
|
||||||
|
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true
|
||||||
},
|
},
|
||||||
proxy: {
|
|
||||||
'/api': {
|
resolve: {
|
||||||
target: 'http://localhost:8180',
|
alias: {
|
||||||
changeOrigin: true,
|
'@': resolve(__dirname, 'src')
|
||||||
rewrite: (path: string) => path.replace(/^\/api/, '')
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
|
server: {
|
||||||
build: {
|
port: 7002,
|
||||||
outDir: 'dist',
|
host: true,
|
||||||
sourcemap: true,
|
cors: true,
|
||||||
rollupOptions: {
|
open: '/bidding/',
|
||||||
output: {
|
https: (() => {
|
||||||
manualChunks: {
|
try {
|
||||||
'vue-vendor': ['vue', 'vue-router', 'pinia'],
|
return {
|
||||||
'element-plus': ['element-plus']
|
key: fs.readFileSync('C:/Users/FK05/443/localhost+3-key.pem'),
|
||||||
|
cert: fs.readFileSync('C:/Users/FK05/443/localhost+3.pem')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
})(),
|
||||||
|
hmr: {
|
||||||
|
path: '/@vite/client',
|
||||||
|
port: 7002
|
||||||
|
},
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'http://localhost:8180',
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path: string) => path.replace(/^\/api/, '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
build: {
|
||||||
|
outDir: 'dist',
|
||||||
|
sourcemap: true,
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks: {
|
||||||
|
'vue-vendor': ['vue', 'vue-router', 'pinia'],
|
||||||
|
'element-plus': ['element-plus']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
})
|
||||||
|
|||||||
@@ -1,24 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* @description 应用运行时配置文件
|
* @description 应用运行时配置文件 (支持 Docker 环境变量替换)
|
||||||
* @author yslg
|
|
||||||
* @since 2025-12-06
|
|
||||||
*
|
*
|
||||||
* 说明:
|
* 占位符说明:
|
||||||
* 1. 此文件在生产环境中被加载,用于覆盖内置配置
|
* - __PLACEHOLDER__ 格式的值会在 Docker 启动时被环境变量替换
|
||||||
* 2. Docker 部署时,可通过挂载此文件来修改配置,无需重新构建
|
* - 如果环境变量未设置,将使用默认值
|
||||||
* 3. 配置结构必须与 packages/shared/src/config/index.ts 中的 AppRuntimeConfig 保持一致
|
|
||||||
*
|
*
|
||||||
* 使用示例(Docker):
|
* Docker 部署:
|
||||||
* docker run -v /path/to/app-config.js:/app/public/app-config.js my-app:latest
|
* 1. 通过 volume 挂载覆盖此文件
|
||||||
|
* 2. 或通过启动脚本替换占位符
|
||||||
*/
|
*/
|
||||||
|
|
||||||
window.APP_RUNTIME_CONFIG = {
|
window.APP_RUNTIME_CONFIG = {
|
||||||
// 环境标识
|
// 环境标识
|
||||||
env: 'production',
|
env: '__APP_ENV__',
|
||||||
|
|
||||||
// API 配置
|
// API 配置
|
||||||
api: {
|
api: {
|
||||||
baseUrl: '/api',
|
baseUrl: '__API_BASE_URL__',
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -27,12 +25,12 @@ window.APP_RUNTIME_CONFIG = {
|
|||||||
|
|
||||||
// 文件配置
|
// 文件配置
|
||||||
file: {
|
file: {
|
||||||
downloadUrl: '/api/urban-lifeline/file/download/',
|
downloadUrl: '__API_BASE_URL__/urban-lifeline/file/download/',
|
||||||
uploadUrl: '/api/urban-lifeline/file/upload',
|
uploadUrl: '__API_BASE_URL__/urban-lifeline/file/upload',
|
||||||
maxSize: {
|
maxSize: {
|
||||||
image: 5, // MB
|
image: 5,
|
||||||
video: 100, // MB
|
video: 100,
|
||||||
document: 10 // MB
|
document: 10
|
||||||
},
|
},
|
||||||
acceptTypes: {
|
acceptTypes: {
|
||||||
image: 'image/*',
|
image: 'image/*',
|
||||||
@@ -44,20 +42,23 @@ window.APP_RUNTIME_CONFIG = {
|
|||||||
// Token 配置
|
// Token 配置
|
||||||
token: {
|
token: {
|
||||||
key: 'token',
|
key: 'token',
|
||||||
refreshThreshold: 300000 // 5分钟
|
refreshThreshold: 300000
|
||||||
},
|
},
|
||||||
|
|
||||||
// 公共资源路径
|
// 公共资源路径
|
||||||
publicImgPath: '/img',
|
publicImgPath: '__PUBLIC_PATH__/img',
|
||||||
publicWebPath: '/',
|
publicWebPath: '__PUBLIC_PATH__',
|
||||||
|
|
||||||
// 单点登录配置
|
// 单点登录配置
|
||||||
sso: {
|
sso: {
|
||||||
platformUrl: '/', // platform 平台地址
|
platformUrl: '__SSO_PLATFORM_URL__',
|
||||||
workcaseUrl: '/workcase', // workcase 服务地址
|
workcaseUrl: '__SSO_WORKCASE_URL__',
|
||||||
biddingUrl: '/bidding' // bidding 服务地址
|
biddingUrl: '__SSO_BIDDING_URL__'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// AES 加密密钥
|
||||||
|
aesSecretKey: '__AES_SECRET_KEY__',
|
||||||
|
|
||||||
// 功能开关
|
// 功能开关
|
||||||
features: {
|
features: {
|
||||||
enableDebug: false,
|
enableDebug: false,
|
||||||
|
|||||||
@@ -1,28 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* @description Platform 应用运行时配置
|
* @description 应用运行时配置
|
||||||
* @author yslg
|
|
||||||
* @since 2025-12-06
|
|
||||||
*
|
*
|
||||||
* 配置加载策略:
|
* 配置加载策略:
|
||||||
* 1. 开发环境:使用下面定义的开发配置
|
* 1. 开发环境:使用内置开发配置
|
||||||
* 2. 生产环境:从 window.APP_RUNTIME_CONFIG 读取(来自 app-config.js)
|
* 2. 生产环境:从 window.APP_RUNTIME_CONFIG 读取(来自 app-config.js)
|
||||||
* 3. Docker部署:替换 app-config.js 文件实现配置外挂
|
* 3. Docker部署:启动时替换 app-config.js 中的占位符
|
||||||
*
|
|
||||||
* 配置结构说明:
|
|
||||||
* 此文件的配置结构与 app-config.js 完全对应
|
|
||||||
* 修改 app-config.js 后,这里的配置会自动应用
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ============================================
|
|
||||||
// AES 加密密钥
|
|
||||||
// ============================================
|
|
||||||
/**
|
|
||||||
* AES 加密密钥(与后端保持一致)
|
|
||||||
* 对应后端配置:security.aes.secret-key
|
|
||||||
* Base64 编码的 32 字节密钥(256 位)
|
|
||||||
*/
|
|
||||||
export const AES_SECRET_KEY = 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=' // Base64 编码,解码后是 "12345678901234567890123456789012" (32字节)
|
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 类型定义
|
// 类型定义
|
||||||
// ============================================
|
// ============================================
|
||||||
@@ -53,12 +37,12 @@ export interface AppRuntimeConfig {
|
|||||||
};
|
};
|
||||||
publicImgPath: string;
|
publicImgPath: string;
|
||||||
publicWebPath: string;
|
publicWebPath: string;
|
||||||
// 单点登录配置
|
|
||||||
sso?: {
|
sso?: {
|
||||||
platformUrl: string; // platform 平台地址
|
platformUrl: string;
|
||||||
workcaseUrl: string; // workcase 服务地址
|
workcaseUrl: string;
|
||||||
biddingUrl: string; // bidding 服务地址
|
biddingUrl: string;
|
||||||
};
|
};
|
||||||
|
aesSecretKey?: string;
|
||||||
features?: {
|
features?: {
|
||||||
enableDebug?: boolean;
|
enableDebug?: boolean;
|
||||||
enableMockData?: boolean;
|
enableMockData?: boolean;
|
||||||
@@ -67,101 +51,80 @@ export interface AppRuntimeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 配置定义(与 app-config.js 结构一致)
|
// 环境检测
|
||||||
// ============================================
|
// ============================================
|
||||||
const isDev = (import.meta as any).env?.DEV ?? false;
|
const isDev = (import.meta as any).env?.DEV ?? false;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
// 开发环境配置
|
// 开发环境配置
|
||||||
|
// ============================================
|
||||||
const devConfig: AppRuntimeConfig = {
|
const devConfig: AppRuntimeConfig = {
|
||||||
env: 'development',
|
env: 'development',
|
||||||
|
|
||||||
api: {
|
api: {
|
||||||
// 开发环境通过 Vite 代理转发到后端,避免浏览器直接跨域
|
|
||||||
// 实际请求路径示例:/api/... → 由代理转发到实际后端
|
|
||||||
baseUrl: '/api',
|
baseUrl: '/api',
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
},
|
},
|
||||||
|
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
|
||||||
file: {
|
file: {
|
||||||
// 通过 Nginx → Gateway 访问文件服务,使用 /urban-lifeline 前缀
|
|
||||||
downloadUrl: '/api/urban-lifeline/file/download/',
|
downloadUrl: '/api/urban-lifeline/file/download/',
|
||||||
uploadUrl: '/api/urban-lifeline/file/upload',
|
uploadUrl: '/api/urban-lifeline/file/upload',
|
||||||
maxSize: {
|
maxSize: { image: 5, video: 100, document: 10 },
|
||||||
image: 5,
|
|
||||||
video: 100,
|
|
||||||
document: 10
|
|
||||||
},
|
|
||||||
acceptTypes: {
|
acceptTypes: {
|
||||||
image: 'image/*',
|
image: 'image/*',
|
||||||
video: 'video/*',
|
video: 'video/*',
|
||||||
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
token: {
|
token: {
|
||||||
key: 'token',
|
key: 'token',
|
||||||
refreshThreshold: 300000
|
refreshThreshold: 300000
|
||||||
},
|
},
|
||||||
|
publicImgPath: '/img',
|
||||||
publicImgPath: 'http://localhost:7001/img',
|
publicWebPath: '/',
|
||||||
publicWebPath: 'http://localhost:7001',
|
|
||||||
|
|
||||||
// 单点登录配置
|
|
||||||
sso: {
|
sso: {
|
||||||
platformUrl: '/', // 通过nginx访问platform
|
platformUrl: '/',
|
||||||
workcaseUrl: '/workcase', // 通过nginx访问workcase
|
workcaseUrl: '/workcase',
|
||||||
biddingUrl: '/bidding' // 通过nginx访问bidding
|
biddingUrl: '/bidding'
|
||||||
},
|
},
|
||||||
|
aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=',
|
||||||
features: {
|
features: {
|
||||||
enableDebug: true,
|
enableDebug: true,
|
||||||
enableMockData: false
|
enableMockData: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================
|
||||||
// 生产环境默认配置(兜底)
|
// 生产环境默认配置(兜底)
|
||||||
|
// ============================================
|
||||||
const prodDefaultConfig: AppRuntimeConfig = {
|
const prodDefaultConfig: AppRuntimeConfig = {
|
||||||
env: 'production',
|
env: 'production',
|
||||||
|
|
||||||
api: {
|
api: {
|
||||||
baseUrl: '/api',
|
baseUrl: '/api',
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
},
|
},
|
||||||
|
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
|
||||||
file: {
|
file: {
|
||||||
downloadUrl: '/api/urban-lifeline/file/download/',
|
downloadUrl: '/api/urban-lifeline/file/download/',
|
||||||
uploadUrl: '/api/urban-lifeline/file/upload',
|
uploadUrl: '/api/urban-lifeline/file/upload',
|
||||||
maxSize: {
|
maxSize: { image: 5, video: 100, document: 10 },
|
||||||
image: 5,
|
|
||||||
video: 100,
|
|
||||||
document: 10
|
|
||||||
},
|
|
||||||
acceptTypes: {
|
acceptTypes: {
|
||||||
image: 'image/*',
|
image: 'image/*',
|
||||||
video: 'video/*',
|
video: 'video/*',
|
||||||
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
token: {
|
token: {
|
||||||
key: 'token',
|
key: 'token',
|
||||||
refreshThreshold: 300000
|
refreshThreshold: 300000
|
||||||
},
|
},
|
||||||
|
|
||||||
publicImgPath: '/img',
|
publicImgPath: '/img',
|
||||||
publicWebPath: '/',
|
publicWebPath: '/',
|
||||||
|
|
||||||
// 单点登录配置(生产环境通过nginx代理)
|
|
||||||
sso: {
|
sso: {
|
||||||
platformUrl: '/',
|
platformUrl: '/',
|
||||||
workcaseUrl: '/workcase',
|
workcaseUrl: '/workcase',
|
||||||
biddingUrl: '/bidding'
|
biddingUrl: '/bidding'
|
||||||
},
|
},
|
||||||
|
aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=',
|
||||||
features: {
|
features: {
|
||||||
enableDebug: false,
|
enableDebug: false,
|
||||||
enableMockData: false
|
enableMockData: false
|
||||||
@@ -172,95 +135,86 @@ const prodDefaultConfig: AppRuntimeConfig = {
|
|||||||
// 配置加载
|
// 配置加载
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查值是否为未替换的占位符
|
||||||
|
*/
|
||||||
|
const isPlaceholder = (value: any): boolean => {
|
||||||
|
return typeof value === 'string' && value.startsWith('__') && value.endsWith('__');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 深度合并配置,跳过占位符值
|
||||||
|
*/
|
||||||
|
const mergeConfig = (target: any, source: any): any => {
|
||||||
|
const result = { ...target };
|
||||||
|
for (const key in source) {
|
||||||
|
const value = source[key];
|
||||||
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
||||||
|
result[key] = mergeConfig(target[key] || {}, value);
|
||||||
|
} else if (!isPlaceholder(value)) {
|
||||||
|
result[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取运行时配置
|
* 获取运行时配置
|
||||||
* 生产环境优先从 window.APP_RUNTIME_CONFIG 读取(app-config.js 注入)
|
|
||||||
*/
|
*/
|
||||||
const getRuntimeConfig = (): AppRuntimeConfig => {
|
const getRuntimeConfig = (): AppRuntimeConfig => {
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
console.log('[配置] 开发环境,使用内置配置');
|
console.log('[Config] 开发环境,使用内置配置');
|
||||||
return devConfig;
|
return devConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生产环境:尝试读取外部配置
|
|
||||||
try {
|
try {
|
||||||
const runtimeConfig = (window as any).APP_RUNTIME_CONFIG;
|
const runtimeConfig = (window as any).APP_RUNTIME_CONFIG;
|
||||||
if (runtimeConfig && typeof runtimeConfig === 'object') {
|
if (runtimeConfig && typeof runtimeConfig === 'object') {
|
||||||
console.log('[配置] 加载外部配置 app-config.js');
|
// 合并配置,未替换的占位符使用默认值
|
||||||
console.log('[配置] API地址:', runtimeConfig.api?.baseUrl);
|
const merged = mergeConfig(prodDefaultConfig, runtimeConfig);
|
||||||
console.log('[配置] 环境:', runtimeConfig.env || 'production');
|
console.log('[Config] 加载运行时配置', merged);
|
||||||
return runtimeConfig as AppRuntimeConfig;
|
return merged;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[配置] 无法读取外部配置,使用默认配置', e);
|
console.warn('[Config] 无法读取外部配置', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[配置] 使用默认生产配置');
|
console.log('[Config] 使用默认生产配置');
|
||||||
return prodDefaultConfig;
|
return prodDefaultConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 当前应用配置
|
// 当前配置
|
||||||
const config = getRuntimeConfig();
|
const config = getRuntimeConfig();
|
||||||
console.log('[配置] 当前配置', config);
|
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 导出配置(向后兼容)
|
// 导出
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
// 单独导出常用配置项
|
// AES 密钥
|
||||||
|
export const AES_SECRET_KEY = config.aesSecretKey || 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=';
|
||||||
|
|
||||||
|
// 常用配置项
|
||||||
export const API_BASE_URL = config.api.baseUrl;
|
export const API_BASE_URL = config.api.baseUrl;
|
||||||
export const FILE_DOWNLOAD_URL = config.file.downloadUrl;
|
export const FILE_DOWNLOAD_URL = config.file.downloadUrl;
|
||||||
|
export const FILE_UPLOAD_URL = config.file.uploadUrl;
|
||||||
export const PUBLIC_IMG_PATH = config.publicImgPath;
|
export const PUBLIC_IMG_PATH = config.publicImgPath;
|
||||||
export const PUBLIC_WEB_PATH = config.publicWebPath;
|
export const PUBLIC_WEB_PATH = config.publicWebPath;
|
||||||
|
|
||||||
// 导出完整配置对象
|
// 完整配置对象
|
||||||
export const APP_CONFIG = {
|
export const APP_CONFIG = {
|
||||||
// 应用标题
|
|
||||||
title: '泰豪电源 AI 数智化平台',
|
title: '泰豪电源 AI 数智化平台',
|
||||||
name: '泰豪电源 AI 数智化平台',
|
name: '泰豪电源 AI 数智化平台',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
copyright: '泰豪电源',
|
copyright: '泰豪电源',
|
||||||
|
|
||||||
// 环境标识
|
|
||||||
env: config.env || 'production',
|
env: config.env || 'production',
|
||||||
|
|
||||||
// 应用基础路径
|
|
||||||
baseUrl: config.baseUrl,
|
baseUrl: config.baseUrl,
|
||||||
|
api: config.api,
|
||||||
// API 配置
|
file: config.file,
|
||||||
api: {
|
token: config.token,
|
||||||
baseUrl: config.api.baseUrl,
|
|
||||||
timeout: config.api.timeout
|
|
||||||
},
|
|
||||||
|
|
||||||
// 文件配置
|
|
||||||
file: {
|
|
||||||
downloadUrl: config.file.downloadUrl,
|
|
||||||
uploadUrl: config.file.uploadUrl,
|
|
||||||
maxSize: config.file.maxSize,
|
|
||||||
acceptTypes: config.file.acceptTypes
|
|
||||||
},
|
|
||||||
|
|
||||||
// Token 配置
|
|
||||||
token: {
|
|
||||||
key: config.token.key,
|
|
||||||
refreshThreshold: config.token.refreshThreshold
|
|
||||||
},
|
|
||||||
|
|
||||||
// 公共路径
|
|
||||||
publicImgPath: config.publicImgPath,
|
publicImgPath: config.publicImgPath,
|
||||||
publicWebPath: config.publicWebPath,
|
publicWebPath: config.publicWebPath,
|
||||||
|
sso: config.sso || { platformUrl: '/', workcaseUrl: '/workcase', biddingUrl: '/bidding' },
|
||||||
// 单点登录配置
|
|
||||||
sso: config.sso || {
|
|
||||||
platformUrl: '/',
|
|
||||||
workcaseUrl: '/workcase',
|
|
||||||
biddingUrl: '/bidding'
|
|
||||||
},
|
|
||||||
|
|
||||||
// 功能开关
|
|
||||||
features: config.features || {}
|
features: config.features || {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 默认导出
|
|
||||||
export default APP_CONFIG;
|
export default APP_CONFIG;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ declare module 'shared/api' {
|
|||||||
import type { AxiosResponse, AxiosRequestConfig } from 'axios'
|
import type { AxiosResponse, AxiosRequestConfig } from 'axios'
|
||||||
|
|
||||||
interface ApiInstance {
|
interface ApiInstance {
|
||||||
get<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
|
get<T = any>(url: string,data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
|
||||||
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
|
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
|
||||||
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
|
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
|
||||||
delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
|
delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
|
||||||
@@ -61,8 +61,6 @@ declare module 'shared/api' {
|
|||||||
|
|
||||||
export const api: ApiInstance
|
export const api: ApiInstance
|
||||||
export const TokenManager: any
|
export const TokenManager: any
|
||||||
export const authAPI: any
|
|
||||||
export const fileAPI: any
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'shared/api/auth' {
|
declare module 'shared/api/auth' {
|
||||||
@@ -81,26 +79,52 @@ declare module 'shared/api/ai' {
|
|||||||
|
|
||||||
// ============ types模块 ==================
|
// ============ types模块 ==================
|
||||||
declare module 'shared/types' {
|
declare module 'shared/types' {
|
||||||
export type { BaseDTO, BaseVO } from '../../../shared/src/types/base'
|
// 基础类型
|
||||||
|
export interface OrderField {
|
||||||
|
field: string
|
||||||
|
order: 'ASC' | 'DESC'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaseDTO {
|
||||||
|
optsn?: string
|
||||||
|
creator?: string
|
||||||
|
updater?: string
|
||||||
|
deptPath?: string
|
||||||
|
remark?: string
|
||||||
|
createTime?: string
|
||||||
|
updateTime?: string
|
||||||
|
deleteTime?: string
|
||||||
|
deleted?: boolean
|
||||||
|
limit?: number
|
||||||
|
startTime?: string
|
||||||
|
endTime?: string
|
||||||
|
orderFields?: OrderField[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaseVO extends BaseDTO {
|
||||||
|
id?: string
|
||||||
|
creatorName?: string
|
||||||
|
updaterName?: string
|
||||||
|
}
|
||||||
|
|
||||||
// 重新导出 response
|
// 重新导出 response
|
||||||
export type { ResultDomain } from '../../../shared/src/types/response'
|
export type { ResultDomain } from '../../../shared/src/types/response'
|
||||||
|
|
||||||
// 重新导出 page
|
// 重新导出 page
|
||||||
export type { PageDomain, PageParam, PageRequest } from '../../../shared/src/types/page'
|
export type { PageDomain, PageParam, PageRequest } from '../../../shared/src/types/page'
|
||||||
|
|
||||||
// 重新导出 auth
|
// 重新导出 auth
|
||||||
export type { LoginParam, LoginDomain } from '../../../shared/src/types/auth'
|
export type { LoginParam, LoginDomain } from '../../../shared/src/types/auth'
|
||||||
|
|
||||||
// 重新导出 sys
|
// 重新导出 sys
|
||||||
export type { SysUserVO, SysConfigVO, TbSysViewDTO } from '../../../shared/src/types/sys'
|
export type { SysUserVO, SysConfigVO, TbSysViewDTO } from '../../../shared/src/types/sys'
|
||||||
|
|
||||||
// 重新导出 file
|
// 重新导出 file
|
||||||
export type { TbSysFileDTO } from '../../../shared/src/types/file'
|
export type { TbSysFileDTO } from '../../../shared/src/types/file'
|
||||||
|
|
||||||
// 重新导出 ai
|
// 重新导出 ai
|
||||||
export type {
|
export type {
|
||||||
TbKnowledge,
|
TbKnowledge,
|
||||||
TbKnowledgeFile,
|
TbKnowledgeFile,
|
||||||
TbAgent,
|
TbAgent,
|
||||||
PromptCard,
|
PromptCard,
|
||||||
@@ -108,10 +132,17 @@ declare module 'shared/types' {
|
|||||||
TbChatMessage,
|
TbChatMessage,
|
||||||
DifyFileInfo,
|
DifyFileInfo,
|
||||||
ChatPrepareData,
|
ChatPrepareData,
|
||||||
StopChatParams,
|
CreateChatParam,
|
||||||
CommentMessageParams
|
StopChatParam,
|
||||||
|
CommentMessageParam,
|
||||||
|
ChatListParam,
|
||||||
|
ChatMessageListParam,
|
||||||
|
SSEMessageData,
|
||||||
|
SSECallbacks,
|
||||||
|
SSETask,
|
||||||
|
TbKnowledgeFileLog
|
||||||
} from '../../../shared/src/types/ai'
|
} from '../../../shared/src/types/ai'
|
||||||
|
|
||||||
// 重新导出 menu
|
// 重新导出 menu
|
||||||
export type { MenuItem, toMenuItem, toMenuItems } from '../../../shared/src/types/menu'
|
export type { MenuItem, toMenuItem, toMenuItems } from '../../../shared/src/types/menu'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,80 +9,93 @@ import fs from 'fs'
|
|||||||
const __filename = fileURLToPath(import.meta.url)
|
const __filename = fileURLToPath(import.meta.url)
|
||||||
const __dirname = dirname(__filename)
|
const __dirname = dirname(__filename)
|
||||||
|
|
||||||
export default defineConfig({
|
// 开发环境 shared 模块地址
|
||||||
// Platform 应用的基础路径
|
const DEV_SHARED_URL = 'https://localhost:7000/shared/mf-manifest.json'
|
||||||
base: '/platform/',
|
// 生产环境使用相对路径,通过 Nginx 代理访问
|
||||||
|
const PROD_SHARED_URL = '/shared/mf-manifest.json'
|
||||||
plugins: [
|
|
||||||
vue({
|
export default defineConfig(({ mode }) => {
|
||||||
script: {
|
const isDev = mode === 'development'
|
||||||
defineModel: true,
|
const sharedEntry = isDev ? DEV_SHARED_URL : PROD_SHARED_URL
|
||||||
propsDestructure: true
|
|
||||||
}
|
return {
|
||||||
}),
|
base: '/platform/',
|
||||||
vueJsx(),
|
|
||||||
federation({
|
plugins: [
|
||||||
name: 'platform',
|
vue({
|
||||||
remotes: {
|
script: {
|
||||||
shared: {
|
defineModel: true,
|
||||||
type: 'module',
|
propsDestructure: true
|
||||||
name: 'shared',
|
|
||||||
entry: 'https://org.xyzh.yslg/shared/remoteEntry.js'
|
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
vueJsx(),
|
||||||
|
federation({
|
||||||
|
name: 'platform',
|
||||||
|
remotes: {
|
||||||
|
shared: {
|
||||||
|
type: 'module',
|
||||||
|
name: 'shared',
|
||||||
|
entry: sharedEntry
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shared: {
|
||||||
|
vue: {},
|
||||||
|
'vue-router': {},
|
||||||
|
'element-plus': {},
|
||||||
|
axios: {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
|
define: {
|
||||||
|
__VUE_OPTIONS_API__: true,
|
||||||
|
__VUE_PROD_DEVTOOLS__: true,
|
||||||
|
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true
|
||||||
|
},
|
||||||
|
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': resolve(__dirname, 'src')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
server: {
|
||||||
|
port: 7001,
|
||||||
|
host: true,
|
||||||
|
cors: true,
|
||||||
|
open: '/',
|
||||||
|
https: (() => {
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
key: fs.readFileSync('C:/Users/FK05/443/localhost+3-key.pem'),
|
||||||
|
cert: fs.readFileSync('C:/Users/FK05/443/localhost+3.pem')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
})(),
|
||||||
|
hmr: {
|
||||||
|
path: '/@vite/client',
|
||||||
|
port: 7001
|
||||||
},
|
},
|
||||||
shared: {
|
proxy: {
|
||||||
vue: {},
|
'/api': {
|
||||||
'vue-router': {},
|
target: 'http://localhost:8180',
|
||||||
'element-plus': {},
|
changeOrigin: true,
|
||||||
axios: {}
|
rewrite: (path: string) => path.replace(/^\/api/, '')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
],
|
|
||||||
|
|
||||||
define: {
|
|
||||||
__VUE_OPTIONS_API__: true,
|
|
||||||
__VUE_PROD_DEVTOOLS__: true,
|
|
||||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true
|
|
||||||
},
|
|
||||||
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': resolve(__dirname, 'src')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
server: {
|
|
||||||
port: 7001,
|
|
||||||
host: true,
|
|
||||||
cors: true,
|
|
||||||
open: '/', // 开发时自动打开到根路径
|
|
||||||
// HTTPS 配置(使用 mkcert 生成的本地开发证书)
|
|
||||||
https: {
|
|
||||||
key: fs.readFileSync('C:/Users/FK05/443/localhost+3-key.pem'),
|
|
||||||
cert: fs.readFileSync('C:/Users/FK05/443/localhost+3.pem')
|
|
||||||
},
|
},
|
||||||
hmr: {
|
|
||||||
// 修复 base 路径导致的 WebSocket 连接问题
|
build: {
|
||||||
path: '/@vite/client',
|
outDir: 'dist',
|
||||||
port: 7001
|
sourcemap: true,
|
||||||
},
|
rollupOptions: {
|
||||||
proxy: {
|
output: {
|
||||||
'/api': {
|
manualChunks: {
|
||||||
target: 'http://localhost:8180',
|
'vue-vendor': ['vue', 'vue-router', 'pinia'],
|
||||||
changeOrigin: true,
|
'element-plus': ['element-plus']
|
||||||
rewrite: (path: string) => path.replace(/^\/api/, '')
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
build: {
|
|
||||||
outDir: 'dist',
|
|
||||||
sourcemap: true,
|
|
||||||
rollupOptions: {
|
|
||||||
output: {
|
|
||||||
manualChunks: {
|
|
||||||
'vue-vendor': ['vue', 'vue-router', 'pinia'],
|
|
||||||
'element-plus': ['element-plus']
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* @description 应用运行时配置文件
|
* @description 应用运行时配置文件 (支持 Docker 环境变量替换)
|
||||||
* @author yslg
|
|
||||||
* @since 2025-12-06
|
|
||||||
*
|
*
|
||||||
* 说明:
|
* 占位符说明:
|
||||||
* 1. 此文件在生产环境中被加载,用于覆盖内置配置
|
* - __PLACEHOLDER__ 格式的值会在 Docker 启动时被环境变量替换
|
||||||
* 2. Docker 部署时,可通过挂载此文件来修改配置,无需重新构建
|
* - 如果环境变量未设置,将使用默认值
|
||||||
* 3. 配置结构必须与 packages/shared/src/config/index.ts 中的 AppRuntimeConfig 保持一致
|
|
||||||
*
|
*
|
||||||
* 使用示例(Docker):
|
* Docker 部署:
|
||||||
* docker run -v /path/to/app-config.js:/app/public/app-config.js my-app:latest
|
* 1. 通过 volume 挂载覆盖此文件
|
||||||
|
* 2. 或通过启动脚本替换占位符
|
||||||
*/
|
*/
|
||||||
|
|
||||||
window.APP_RUNTIME_CONFIG = {
|
window.APP_RUNTIME_CONFIG = {
|
||||||
// 环境标识
|
// 环境标识
|
||||||
env: 'production',
|
env: '__APP_ENV__',
|
||||||
|
|
||||||
// API 配置
|
// API 配置
|
||||||
api: {
|
api: {
|
||||||
baseUrl: '/api',
|
baseUrl: '__API_BASE_URL__',
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -27,12 +25,12 @@ window.APP_RUNTIME_CONFIG = {
|
|||||||
|
|
||||||
// 文件配置
|
// 文件配置
|
||||||
file: {
|
file: {
|
||||||
downloadUrl: '/api/urban-lifeline/file/download/',
|
downloadUrl: '__API_BASE_URL__/urban-lifeline/file/download/',
|
||||||
uploadUrl: '/api/urban-lifeline/file/upload',
|
uploadUrl: '__API_BASE_URL__/urban-lifeline/file/upload',
|
||||||
maxSize: {
|
maxSize: {
|
||||||
image: 5, // MB
|
image: 5,
|
||||||
video: 100, // MB
|
video: 100,
|
||||||
document: 10 // MB
|
document: 10
|
||||||
},
|
},
|
||||||
acceptTypes: {
|
acceptTypes: {
|
||||||
image: 'image/*',
|
image: 'image/*',
|
||||||
@@ -44,18 +42,26 @@ window.APP_RUNTIME_CONFIG = {
|
|||||||
// Token 配置
|
// Token 配置
|
||||||
token: {
|
token: {
|
||||||
key: 'token',
|
key: 'token',
|
||||||
refreshThreshold: 300000 // 5分钟
|
refreshThreshold: 300000
|
||||||
},
|
},
|
||||||
|
|
||||||
// 公共资源路径
|
// 公共资源路径
|
||||||
publicImgPath: '/img',
|
publicImgPath: '__PUBLIC_PATH__/img',
|
||||||
publicWebPath: '/',
|
publicWebPath: '__PUBLIC_PATH__',
|
||||||
|
|
||||||
// 单点登录配置
|
// 单点登录配置
|
||||||
sso: {
|
sso: {
|
||||||
platformUrl: '/', // platform 平台地址
|
platformUrl: '__SSO_PLATFORM_URL__',
|
||||||
workcaseUrl: '/workcase', // workcase 服务地址
|
workcaseUrl: '__SSO_WORKCASE_URL__',
|
||||||
biddingUrl: '/bidding' // bidding 服务地址
|
biddingUrl: '__SSO_BIDDING_URL__'
|
||||||
|
},
|
||||||
|
|
||||||
|
// AES 加密密钥
|
||||||
|
aesSecretKey: '__AES_SECRET_KEY__',
|
||||||
|
|
||||||
|
// Jitsi 视频会议配置
|
||||||
|
jitsi: {
|
||||||
|
serverUrl: '__JITSI_SERVER_URL__'
|
||||||
},
|
},
|
||||||
|
|
||||||
// 功能开关
|
// 功能开关
|
||||||
|
|||||||
@@ -1,28 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* @description 应用运行时配置
|
* @description 应用运行时配置
|
||||||
* @author yslg
|
|
||||||
* @since 2025-12-06
|
|
||||||
*
|
*
|
||||||
* 配置加载策略:
|
* 配置加载策略:
|
||||||
* 1. 开发环境:使用下面定义的开发配置
|
* 1. 开发环境:使用内置开发配置
|
||||||
* 2. 生产环境:从 window.APP_RUNTIME_CONFIG 读取(来自 app-config.js)
|
* 2. 生产环境:从 window.APP_RUNTIME_CONFIG 读取(来自 app-config.js)
|
||||||
* 3. Docker部署:替换 app-config.js 文件实现配置外挂
|
* 3. Docker部署:启动时替换 app-config.js 中的占位符
|
||||||
*
|
|
||||||
* 配置结构说明:
|
|
||||||
* 此文件的配置结构与 app-config.js 完全对应
|
|
||||||
* 修改 app-config.js 后,这里的配置会自动应用
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ============================================
|
|
||||||
// AES 加密密钥
|
|
||||||
// ============================================
|
|
||||||
/**
|
|
||||||
* AES 加密密钥(与后端保持一致)
|
|
||||||
* 对应后端配置:security.aes.secret-key
|
|
||||||
* Base64 编码的 32 字节密钥(256 位)
|
|
||||||
*/
|
|
||||||
export const AES_SECRET_KEY = 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=' // Base64 编码,解码后是 "12345678901234567890123456789012" (32字节)
|
|
||||||
export const AGENT_ID = '17664699513920001'
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 类型定义
|
// 类型定义
|
||||||
// ============================================
|
// ============================================
|
||||||
@@ -53,11 +37,14 @@ export interface AppRuntimeConfig {
|
|||||||
};
|
};
|
||||||
publicImgPath: string;
|
publicImgPath: string;
|
||||||
publicWebPath: string;
|
publicWebPath: string;
|
||||||
// 单点登录配置
|
|
||||||
sso?: {
|
sso?: {
|
||||||
platformUrl: string; // platform 平台地址
|
platformUrl: string;
|
||||||
workcaseUrl: string; // workcase 服务地址
|
workcaseUrl: string;
|
||||||
biddingUrl: string; // bidding 服务地址
|
biddingUrl: string;
|
||||||
|
};
|
||||||
|
aesSecretKey?: string;
|
||||||
|
jitsi?: {
|
||||||
|
serverUrl: string;
|
||||||
};
|
};
|
||||||
features?: {
|
features?: {
|
||||||
enableDebug?: boolean;
|
enableDebug?: boolean;
|
||||||
@@ -67,103 +54,86 @@ export interface AppRuntimeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 配置定义(与 app-config.js 结构一致)
|
// 环境检测
|
||||||
// ============================================
|
// ============================================
|
||||||
const isDev = (import.meta as any).env?.DEV ?? false;
|
const isDev = (import.meta as any).env?.DEV ?? false;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
// 开发环境配置
|
// 开发环境配置
|
||||||
|
// ============================================
|
||||||
const devConfig: AppRuntimeConfig = {
|
const devConfig: AppRuntimeConfig = {
|
||||||
env: 'development',
|
env: 'development',
|
||||||
|
|
||||||
api: {
|
api: {
|
||||||
// 开发环境通过 Vite 代理转发到后端,避免浏览器直接跨域
|
|
||||||
// 实际请求路径示例:/api/... → 由代理转发到实际后端
|
|
||||||
baseUrl: '/api',
|
baseUrl: '/api',
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
},
|
},
|
||||||
|
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
|
||||||
file: {
|
file: {
|
||||||
// 通过 Nginx → Gateway 访问文件服务,使用 /urban-lifeline 前缀
|
|
||||||
downloadUrl: '/api/urban-lifeline/file/download/',
|
downloadUrl: '/api/urban-lifeline/file/download/',
|
||||||
uploadUrl: '/api/urban-lifeline/file/upload',
|
uploadUrl: '/api/urban-lifeline/file/upload',
|
||||||
maxSize: {
|
maxSize: { image: 5, video: 100, document: 10 },
|
||||||
image: 5,
|
|
||||||
video: 100,
|
|
||||||
document: 10
|
|
||||||
},
|
|
||||||
acceptTypes: {
|
acceptTypes: {
|
||||||
image: 'image/*',
|
image: 'image/*',
|
||||||
video: 'video/*',
|
video: 'video/*',
|
||||||
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
token: {
|
token: {
|
||||||
key: 'token',
|
key: 'token',
|
||||||
refreshThreshold: 300000
|
refreshThreshold: 300000
|
||||||
},
|
},
|
||||||
|
publicImgPath: '/img',
|
||||||
publicImgPath: 'http://localhost:5173/img',
|
publicWebPath: '/',
|
||||||
publicWebPath: 'http://localhost:5173',
|
|
||||||
|
|
||||||
// 单点登录配置
|
|
||||||
// 推荐:开发环境也通过nginx访问(http://localhost)
|
|
||||||
// 备选:直接访问各服务端口(platformUrl: 'http://localhost:7001')
|
|
||||||
sso: {
|
sso: {
|
||||||
platformUrl: '/', // 通过nginx访问platform
|
platformUrl: '/',
|
||||||
workcaseUrl: '/workcase', // 通过nginx访问workcase
|
workcaseUrl: '/workcase',
|
||||||
biddingUrl: '/bidding' // 通过nginx访问bidding
|
biddingUrl: '/bidding'
|
||||||
|
},
|
||||||
|
aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=',
|
||||||
|
jitsi: {
|
||||||
|
serverUrl: 'https://meet.example.com'
|
||||||
},
|
},
|
||||||
|
|
||||||
features: {
|
features: {
|
||||||
enableDebug: true,
|
enableDebug: true,
|
||||||
enableMockData: false
|
enableMockData: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================
|
||||||
// 生产环境默认配置(兜底)
|
// 生产环境默认配置(兜底)
|
||||||
|
// ============================================
|
||||||
const prodDefaultConfig: AppRuntimeConfig = {
|
const prodDefaultConfig: AppRuntimeConfig = {
|
||||||
env: 'production',
|
env: 'production',
|
||||||
|
|
||||||
api: {
|
api: {
|
||||||
baseUrl: '/api',
|
baseUrl: '/api',
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
},
|
},
|
||||||
|
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
|
||||||
file: {
|
file: {
|
||||||
downloadUrl: '/api/file/download/',
|
downloadUrl: '/api/urban-lifeline/file/download/',
|
||||||
uploadUrl: '/api/file/upload',
|
uploadUrl: '/api/urban-lifeline/file/upload',
|
||||||
maxSize: {
|
maxSize: { image: 5, video: 100, document: 10 },
|
||||||
image: 5,
|
|
||||||
video: 100,
|
|
||||||
document: 10
|
|
||||||
},
|
|
||||||
acceptTypes: {
|
acceptTypes: {
|
||||||
image: 'image/*',
|
image: 'image/*',
|
||||||
video: 'video/*',
|
video: 'video/*',
|
||||||
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
token: {
|
token: {
|
||||||
key: 'token',
|
key: 'token',
|
||||||
refreshThreshold: 300000
|
refreshThreshold: 300000
|
||||||
},
|
},
|
||||||
|
|
||||||
publicImgPath: '/img',
|
publicImgPath: '/img',
|
||||||
publicWebPath: '/',
|
publicWebPath: '/',
|
||||||
|
|
||||||
// 单点登录配置(生产环境通过nginx代理)
|
|
||||||
sso: {
|
sso: {
|
||||||
platformUrl: '/',
|
platformUrl: '/',
|
||||||
workcaseUrl: '/workcase',
|
workcaseUrl: '/workcase',
|
||||||
biddingUrl: '/bidding'
|
biddingUrl: '/bidding'
|
||||||
},
|
},
|
||||||
|
aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=',
|
||||||
|
jitsi: {
|
||||||
|
serverUrl: 'https://meet.example.com'
|
||||||
|
},
|
||||||
features: {
|
features: {
|
||||||
enableDebug: false,
|
enableDebug: false,
|
||||||
enableMockData: false
|
enableMockData: false
|
||||||
@@ -174,96 +144,90 @@ const prodDefaultConfig: AppRuntimeConfig = {
|
|||||||
// 配置加载
|
// 配置加载
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查值是否为未替换的占位符
|
||||||
|
*/
|
||||||
|
const isPlaceholder = (value: any): boolean => {
|
||||||
|
return typeof value === 'string' && value.startsWith('__') && value.endsWith('__');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 深度合并配置,跳过占位符值
|
||||||
|
*/
|
||||||
|
const mergeConfig = (target: any, source: any): any => {
|
||||||
|
const result = { ...target };
|
||||||
|
for (const key in source) {
|
||||||
|
const value = source[key];
|
||||||
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
||||||
|
result[key] = mergeConfig(target[key] || {}, value);
|
||||||
|
} else if (!isPlaceholder(value)) {
|
||||||
|
result[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取运行时配置
|
* 获取运行时配置
|
||||||
* 生产环境优先从 window.APP_RUNTIME_CONFIG 读取(app-config.js 注入)
|
|
||||||
*/
|
*/
|
||||||
const getRuntimeConfig = (): AppRuntimeConfig => {
|
const getRuntimeConfig = (): AppRuntimeConfig => {
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
console.log('[配置] 开发环境,使用内置配置');
|
console.log('[Config] 开发环境,使用内置配置');
|
||||||
return devConfig;
|
return devConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生产环境:尝试读取外部配置
|
|
||||||
try {
|
try {
|
||||||
const runtimeConfig = (window as any).APP_RUNTIME_CONFIG;
|
const runtimeConfig = (window as any).APP_RUNTIME_CONFIG;
|
||||||
if (runtimeConfig && typeof runtimeConfig === 'object') {
|
if (runtimeConfig && typeof runtimeConfig === 'object') {
|
||||||
console.log('[配置] 加载外部配置 app-config.js');
|
const merged = mergeConfig(prodDefaultConfig, runtimeConfig);
|
||||||
console.log('[配置] API地址:', runtimeConfig.api?.baseUrl);
|
console.log('[Config] 加载运行时配置', merged);
|
||||||
console.log('[配置] 环境:', runtimeConfig.env || 'production');
|
return merged;
|
||||||
return runtimeConfig as AppRuntimeConfig;
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[配置] 无法读取外部配置,使用默认配置', e);
|
console.warn('[Config] 无法读取外部配置', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[配置] 使用默认生产配置');
|
console.log('[Config] 使用默认生产配置');
|
||||||
return prodDefaultConfig;
|
return prodDefaultConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 当前应用配置
|
// 当前配置
|
||||||
const config = getRuntimeConfig();
|
const config = getRuntimeConfig();
|
||||||
console.log('[配置] 当前配置', config);
|
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 导出配置(向后兼容)
|
// 导出
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
// 单独导出常用配置项
|
// AES 密钥
|
||||||
|
export const AES_SECRET_KEY = config.aesSecretKey || 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=';
|
||||||
|
|
||||||
|
// AI Agent ID
|
||||||
|
export const AGENT_ID = '17664699513920001';
|
||||||
|
|
||||||
|
// 常用配置项
|
||||||
export const API_BASE_URL = config.api.baseUrl;
|
export const API_BASE_URL = config.api.baseUrl;
|
||||||
export const FILE_DOWNLOAD_URL = config.file.downloadUrl;
|
export const FILE_DOWNLOAD_URL = config.file.downloadUrl;
|
||||||
export const FILE_UPLOAD_URL = config.file.uploadUrl;
|
export const FILE_UPLOAD_URL = config.file.uploadUrl;
|
||||||
export const PUBLIC_IMG_PATH = config.publicImgPath;
|
export const PUBLIC_IMG_PATH = config.publicImgPath;
|
||||||
export const PUBLIC_WEB_PATH = config.publicWebPath;
|
export const PUBLIC_WEB_PATH = config.publicWebPath;
|
||||||
|
|
||||||
// 文件上传大小限制(100MB)
|
|
||||||
export const FILE_MAX_SIZE = 100 * 1024 * 1024;
|
export const FILE_MAX_SIZE = 100 * 1024 * 1024;
|
||||||
|
|
||||||
// 导出完整配置对象
|
// Jitsi 配置
|
||||||
|
export const JITSI_SERVER_URL = config.jitsi?.serverUrl || 'https://meet.example.com';
|
||||||
|
|
||||||
|
// 完整配置对象
|
||||||
export const APP_CONFIG = {
|
export const APP_CONFIG = {
|
||||||
// 应用标题
|
title: '泰豪电源工单系统',
|
||||||
title: '泰豪电源 AI 数智化平台',
|
|
||||||
|
|
||||||
// 环境标识
|
|
||||||
env: config.env || 'production',
|
env: config.env || 'production',
|
||||||
|
|
||||||
// 应用基础路径
|
|
||||||
baseUrl: config.baseUrl,
|
baseUrl: config.baseUrl,
|
||||||
|
api: config.api,
|
||||||
// API 配置
|
file: config.file,
|
||||||
api: {
|
token: config.token,
|
||||||
baseUrl: config.api.baseUrl,
|
|
||||||
timeout: config.api.timeout
|
|
||||||
},
|
|
||||||
|
|
||||||
// 文件配置
|
|
||||||
file: {
|
|
||||||
downloadUrl: config.file.downloadUrl,
|
|
||||||
uploadUrl: config.file.uploadUrl,
|
|
||||||
maxSize: config.file.maxSize,
|
|
||||||
acceptTypes: config.file.acceptTypes
|
|
||||||
},
|
|
||||||
|
|
||||||
// Token 配置
|
|
||||||
token: {
|
|
||||||
key: config.token.key,
|
|
||||||
refreshThreshold: config.token.refreshThreshold
|
|
||||||
},
|
|
||||||
|
|
||||||
// 公共路径
|
|
||||||
publicImgPath: config.publicImgPath,
|
publicImgPath: config.publicImgPath,
|
||||||
publicWebPath: config.publicWebPath,
|
publicWebPath: config.publicWebPath,
|
||||||
|
sso: config.sso || { platformUrl: '/', workcaseUrl: '/workcase', biddingUrl: '/bidding' },
|
||||||
// 单点登录配置
|
jitsi: config.jitsi || { serverUrl: 'https://meet.example.com' },
|
||||||
sso: config.sso || {
|
|
||||||
platformUrl: '/',
|
|
||||||
workcaseUrl: '/workcase',
|
|
||||||
biddingUrl: '/bidding'
|
|
||||||
},
|
|
||||||
|
|
||||||
// 功能开关
|
|
||||||
features: config.features || {}
|
features: config.features || {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 默认导出
|
|
||||||
export default APP_CONFIG;
|
export default APP_CONFIG;
|
||||||
|
|||||||
@@ -9,84 +9,97 @@ import fs from 'fs'
|
|||||||
const __filename = fileURLToPath(import.meta.url)
|
const __filename = fileURLToPath(import.meta.url)
|
||||||
const __dirname = dirname(__filename)
|
const __dirname = dirname(__filename)
|
||||||
|
|
||||||
export default defineConfig(({ mode }) => ({
|
// 开发环境 shared 模块地址
|
||||||
// 开发和生产环境都通过nginx代理访问/workcase
|
const DEV_SHARED_URL = 'https://localhost:7000/shared/mf-manifest.json'
|
||||||
base: '/workcase/',
|
// 生产环境使用相对路径,通过 Nginx 代理访问
|
||||||
|
const PROD_SHARED_URL = '/shared/mf-manifest.json'
|
||||||
plugins: [
|
|
||||||
vue({
|
export default defineConfig(({ mode }) => {
|
||||||
script: {
|
const isDev = mode === 'development'
|
||||||
defineModel: true,
|
const sharedEntry = isDev ? DEV_SHARED_URL : PROD_SHARED_URL
|
||||||
propsDestructure: true
|
|
||||||
}
|
return {
|
||||||
}),
|
base: '/workcase/',
|
||||||
vueJsx(),
|
|
||||||
federation({
|
plugins: [
|
||||||
name: 'workcase',
|
vue({
|
||||||
remotes: {
|
script: {
|
||||||
shared: {
|
defineModel: true,
|
||||||
type: 'module',
|
propsDestructure: true
|
||||||
name: 'shared',
|
|
||||||
entry: 'https://org.xyzh.yslg/shared/remoteEntry.js'
|
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
vueJsx(),
|
||||||
|
federation({
|
||||||
|
name: 'workcase',
|
||||||
|
remotes: {
|
||||||
|
shared: {
|
||||||
|
type: 'module',
|
||||||
|
name: 'shared',
|
||||||
|
entry: sharedEntry
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shared: {
|
||||||
|
vue: {},
|
||||||
|
'vue-router': {},
|
||||||
|
'element-plus': {},
|
||||||
|
axios: {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
|
define: {
|
||||||
|
__VUE_OPTIONS_API__: true,
|
||||||
|
__VUE_PROD_DEVTOOLS__: true,
|
||||||
|
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true,
|
||||||
|
global: 'globalThis'
|
||||||
|
},
|
||||||
|
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': resolve(__dirname, 'src')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
server: {
|
||||||
|
port: 7003,
|
||||||
|
host: true,
|
||||||
|
cors: true,
|
||||||
|
open: '/workcase/',
|
||||||
|
https: (() => {
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
key: fs.readFileSync('C:/Users/FK05/443/localhost+3-key.pem'),
|
||||||
|
cert: fs.readFileSync('C:/Users/FK05/443/localhost+3.pem')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
})(),
|
||||||
|
hmr: {
|
||||||
|
path: '/@vite/client',
|
||||||
|
port: 7003
|
||||||
},
|
},
|
||||||
shared: {
|
proxy: {
|
||||||
vue: {},
|
'/api': {
|
||||||
'vue-router': {},
|
target: 'http://localhost:8180',
|
||||||
'element-plus': {},
|
changeOrigin: true,
|
||||||
axios: {}
|
ws: true,
|
||||||
|
rewrite: (path: string) => path.replace(/^\/api/, '')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
],
|
|
||||||
|
|
||||||
define: {
|
|
||||||
__VUE_OPTIONS_API__: true,
|
|
||||||
__VUE_PROD_DEVTOOLS__: true,
|
|
||||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true,
|
|
||||||
global: 'globalThis'
|
|
||||||
},
|
|
||||||
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': resolve(__dirname, 'src')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
server: {
|
|
||||||
port: 7003,
|
|
||||||
host: true,
|
|
||||||
cors: true,
|
|
||||||
open: '/workcase/', // 开发时自动打开到 /workcase/ 路径
|
|
||||||
// HTTPS 配置(使用 mkcert 生成的本地开发证书)
|
|
||||||
https: {
|
|
||||||
key: fs.readFileSync('C:/Users/FK05/443/localhost+3-key.pem'),
|
|
||||||
cert: fs.readFileSync('C:/Users/FK05/443/localhost+3.pem')
|
|
||||||
},
|
},
|
||||||
hmr: {
|
|
||||||
// 修复 base 路径导致的 WebSocket 连接问题
|
build: {
|
||||||
path: '/@vite/client',
|
outDir: 'dist',
|
||||||
port: 7003
|
sourcemap: true,
|
||||||
},
|
rollupOptions: {
|
||||||
proxy: {
|
output: {
|
||||||
'/api': {
|
manualChunks: {
|
||||||
target: 'http://localhost:8180',
|
'vue-vendor': ['vue', 'vue-router', 'pinia'],
|
||||||
changeOrigin: true,
|
'element-plus': ['element-plus']
|
||||||
ws: true, // 启用 WebSocket 代理
|
}
|
||||||
rewrite: (path: string) => path.replace(/^\/api/, '')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
build: {
|
|
||||||
outDir: 'dist',
|
|
||||||
sourcemap: true,
|
|
||||||
rollupOptions: {
|
|
||||||
output: {
|
|
||||||
manualChunks: {
|
|
||||||
'vue-vendor': ['vue', 'vue-router', 'pinia'],
|
|
||||||
'element-plus': ['element-plus']
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user