master
huwei 2026-06-17 17:24:40 +08:00
commit 2950b06f89
27 changed files with 1975 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,398 @@
# GBS 底座服务手册
> 最后更新2026-06-16
> 文档范围K8s 集群、中间件、微服务全部服务清单
---
## 一、服务器信息
| 角色 | 主机名 | IP | OS | SSH 账号 | SSH 密码 |
|------|--------|-----|-----|----------|----------|
| Master | k8s-master | 192.168.20.100 | CentOS 7 | root | `Zcloud@zcloud100` |
| Worker01 | k8s-work01 | 192.168.20.110 | CentOS 7 | root | `Zcloud@zcloud110` |
| Worker02 | k8s-work02 | 192.168.20.120 | CentOS 7 | root | `Zcloud@zcloud120` |
**K8s 集群版本**v1.27.6
**容器运行时**Docker 26.1.3 + cri-dockerd 0.3.4
**网络插件**Calico v3.26.1
**Pod 网段**10.244.0.0/16
**Service 网段**10.96.0.0/12
**DNS 域名**cluster.local
---
## 二、基础设施服务Docker 直接部署在 Master 节点)
### 2.1 MySQL
| 属性 | 值 |
|------|-----|
| **部署方式** | DockerMaster 节点) |
| **镜像版本** | mysql:8.0.35 |
| **访问地址** | `192.168.20.100:33080` |
| **集群内部地址** | 通过宿主机 IP 访问 |
| **账号** | `root` |
| **密码** | `Mysql@zcloud33080` |
| **字符集** | utf8mb4 / utf8mb4_0900_ai_ci |
> **注意**Docker 环境变量中 `MYSQL_ROOT_PASSWORD=Zcloud@zcloud2026` 是容器创建时的初始密码,但实际 root 密码已被后续操作改为 `Mysql@zcloud33080`。**请使用 `Mysql@zcloud33080` 连接。**
**数据库列表**24 个业务库 + 系统库):
| 数据库名 | 用途 |
|----------|------|
| `nacos` | Nacos 配置存储(注意:不是 nacos_config |
**连接方式**
```bash
# 外部连接(任意客户端)
mysql -h 192.168.20.100 -P 33080 -uroot -p'Mysql@zcloud33080'
# 集群内部 Pod 连接(通过宿主机 IP
mysql -h 192.168.20.100 -P 33080 -uroot -p'Mysql@zcloud33080'
```
---
### 2.2 Redis
| 属性 | 值 |
|------|-----|
| **部署方式** | DockerMaster 节点) |
| **镜像版本** | redis:7.2-alpine实际版本 7.2.14 |
| **访问地址** | `192.168.20.100:6379` |
| **密码** | `Zcloud@zcloud2026` |
| **模式** | 单机standalone |
**连接方式**
```bash
# 外部连接
redis-cli -h 192.168.20.100 -p 6379 -a 'Zcloud@zcloud2026'
# Spring Boot 配置application.yml
spring:
redis:
host: 192.168.20.100
port: 6379
password: Zcloud@zcloud2026
```
---
### 2.3 MinIO对象存储
| 属性 | 值 |
|------|-----|
| **部署方式** | DockerMaster 节点) |
| **镜像版本** | minio/minio:latest |
| **API 地址** | `http://192.168.20.100:9000` |
| **Web 控制台** | `http://192.168.20.100:9001` |
| **账号** | `admin` |
| **密码** | `Zcloud@zcloud2026` |
| **Browser** | 已开启MINIO_BROWSER=on |
**使用方式**
1. 浏览器打开 `http://192.168.20.100:9001`
2. 使用 `admin / Zcloud@zcloud2026` 登录
3. 可创建 Bucket、上传文件、管理访问策略
---
## 三、K8s 集群基础服务
### 3.1 Nacos注册中心 & 配置中心)
| 属性 | 值 |
|------|-----|
| **部署方式** | K8s Deploymentnamespace: jjb-dragon |
| **镜像版本** | nacos-server:2.0.3 |
| **副本数** | 1 |
| **运行节点** | k8s-master |
| **Web 控制台** | `http://192.168.20.100:30290/nacos` |
| **集群内部地址** | `prod-nacos.jjb-dragon.svc.cluster.local:8848` 或简写 `prod-nacos:8848` |
| **账号** | `nacos` |
| **密码** | `nacos`(默认密码) |
| **模式** | standalone |
| **数据存储** | MySQLnacos 库) |
**端口映射**
| 服务端口 | NodePort | 用途 |
|----------|----------|------|
| 8848 | 30290 | HTTP 控制台 & API |
| 9848 | 31290 | gRPC 客户端通信 |
| 9849 | 31291 | gRPC Raft 通信 |
| 7848 | 30740 | Jraft 通信 |
**命名空间**
| 命名空间 ID | 显示名称 | 配置数 |
|-------------|----------|--------|
| (空) | public | 1 |
| `jjb-dragon` | jjb-dragon | 51 |
| `jjb-dragon-facade` | jjb-dragon-facade | 537 |
**接入方式**
```yaml
# Spring Boot 微服务配置
spring:
cloud:
nacos:
discovery:
server-addr: prod-nacos:8848
namespace: jjb-dragon
config:
server-addr: prod-nacos:8848
namespace: jjb-dragon
```
---
### 3.2 RocketMQ消息队列
| 属性 | 值 |
|------|-----|
| **部署方式** | K8s Deploymentnamespace: jjb-dragon |
| **镜像版本** | rocketmq:4.4.0 / rocketmq-console-ng:new |
| **副本数** | 1含 NameServer + Broker + Console 三容器) |
| **运行节点** | k8s-work01 |
| **集群名称** | JjbMqCluster |
| **Web 控制台** | `http://192.168.20.100:30300` |
| **集群内部 NameServer** | `rocketmq.jjb-dragon.svc.cluster.local:9876` |
| **认证** | 无(默认未开启 ACL |
**端口映射**
| 服务 | 容器端口 | NodePort | 用途 |
|------|----------|----------|------|
| Console | 8080 | 30300 | Web 管理控制台 |
| NameServer | 9876 | 30658 | 服务发现 |
| Broker | 10909 | 30161 | Broker VIP 通道 |
| Broker | 10911 | 31356 | Broker 主端口 |
| Broker | 10912 | 31493 | Broker HA |
**接入方式**
```yaml
# Spring Boot 配置
rocketmq:
name-server: rocketmq:9876
producer:
group: jjb-producer-group
```
**Broker 配置要点**
- 自动创建 Topic已开启
- 默认队列数4
- 消息最大大小655360 字节
- Broker 角色ASYNC_MASTER
- 刷盘方式ASYNC_FLUSH
---
### 3.3 Kubernetes Dashboard
| 属性 | 值 |
|------|-----|
| **部署方式** | Helm Chartnamespace: kubernetes-dashboard |
| **版本** | v2.7.0 |
| **访问地址** | `https://192.168.20.100:30180` |
| **认证方式** | Token |
**获取 Token**
```bash
# 如果 SA 和绑定已存在(文档中显示已创建过 kube-dashboard-admin-sa
# 但当前集群中该 SA 不存在,需要重新创建:
# 1. 创建 ServiceAccount 和 ClusterRoleBinding
kubectl create serviceaccount kube-dashboard-admin-sa -n kube-system
kubectl create clusterrolebinding kube-dashboard-admin-binding \
--clusterrole=cluster-admin \
--serviceaccount=kube-system:kube-dashboard-admin-sa
# 2. 生成 Token有效期 10 年)
kubectl create token kube-dashboard-admin-sa -n kube-system --duration=87600h
```
> **注意**:之前部署文档中生成的 Token 对应的 SA 已不存在,需要重新创建。
---
### 3.4 Metrics Server
| 属性 | 值 |
|------|-----|
| **部署方式** | K8s YAMLnamespace: kube-system |
| **版本** | v0.6.0 |
| **用途** | 提供 `kubectl top` 命令的 CPU/内存指标数据 |
| **状态** | 正常运行 |
---
### 3.5 Calico网络插件
| 属性 | 值 |
|------|-----|
| **版本** | v3.26.1 |
| **部署方式** | K8s YAMLnamespace: kube-system |
| **Pod 网段** | 10.244.0.0/16 |
---
## 四、镜像仓库凭证
### 4.1 image-pull-secret底座镜像
| 属性 | 值 |
|------|-----|
| **Secret 名** | `image-pull-secret` |
| **命名空间** | jjb-dragon |
| **仓库地址** | `jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com` |
| **用户名** | `10952138@qq.com` |
| **密码** | `idurCT!rIq9EzISD` |
### 4.2 image-pull-secret1应用镜像
| 属性 | 值 |
|------|-----|
| **Secret 名** | `image-pull-secret1` |
| **命名空间** | jjb-dragon |
| **仓库地址** | `registry.cn-zhangjiakou.aliyuncs.com` |
| **用户名** | `kilaa` |
| **密码** | `Kilaa@6666` |
---
## 五、业务微服务清单
所有微服务部署在 `jjb-dragon` 命名空间,使用 Helm Chart `jjb-prod/jjb-java-app` 部署。
| 序号 | 服务名 | Deployment | 状态 | 镜像版本 | 运行节点 |
|------|--------|------------|------|----------|----------|
| 1 | 网关 | jjb-saas-gateway | **Running** | oat-20250902-1 | k8s-work01 |
| 2 | 认证 | jjb-saas-auth | **Running** | ota-20260528-1 | k8s-work01 |
| 3 | 数据中心 | jjb-saas-data-center | **Running** | ota-20251111-1 | k8s-work01 |
| 4 | 事件 | jjb-saas-events | **Running** | ota-20251119-1 | k8s-work01 |
| 5 | 消息 | jjb-saas-message | **Running** | ota-20260317-1 | k8s-work01 |
| 6 | 官网 | jjb-saas-official | **Running** | ipass-20250816-2 | k8s-work01 |
| 7 | 流程布局 | jjb-saas-process-layout | **Running** | ota-20250926-1 | k8s-work01 |
| 8 | 安全 | jjb-saas-security | **Running** | ipass-20250906-2 | k8s-work01 |
| 9 | 用户 | jjb-saas-user | CrashLoopBackOff | 20251107-1808 | k8s-work01 |
| 10 | 系统 | jjb-saas-system | CrashLoopBackOff | ota-20260427-1 | k8s-work01 |
| 11 | 配置 | jjb-saas-config | CrashLoopBackOff | ota-20260115-1 | k8s-work01 |
| 12 | 附件 | jjb-saas-attachment | CrashLoopBackOff | ipass-20250906-2 | k8s-work01 |
| 13 | 应用 | jjb-saas-application | CrashLoopBackOff | ota-20260304-2 | k8s-work01 |
| 14 | 工作台 | jjb-saas-desk | CrashLoopBackOff | ota-20260116-1 | k8s-work01 |
| 15 | 门面 | jjb-saas-facade | CrashLoopBackOff | ota-20260603-1 | k8s-work01 |
| 16 | 基础 | jjb-saas-base | CrashLoopBackOff | ota-20260528-2 | k8s-work01 |
| 17 | 表单设计 | jjb-saas-formily-design | CrashLoopBackOff | wb-20250904-1 | k8s-work01 |
| 18 | 登录 | jjb-saas-login | CrashLoopBackOff | ota-20251216-1 | k8s-work01 |
| 19 | 开放平台 | jjb-saas-open-platform | CrashLoopBackOff | ota-20260401-1 | k8s-work01 |
| 20 | Netty 服务 | jjb-saas-netty-server | CrashLoopBackOff | ota-20250820-3 | k8s-work01 |
| 21 | BPM 流程 | jjb-saas-bpm | CrashLoopBackOff | ota-20251111-2 | k8s-work01 |
| 22 | 组件设计 | jjb-saas-component-design | CrashLoopBackOff | ota-20251111-1 | k8s-work01 |
| 23 | 文档 | jjb-saas-document | CrashLoopBackOff | ota-20250617-1 | k8s-work01 |
| 24 | 视图 | jjb-saas-view | CrashLoopBackOff | ota-20241129-1 | k8s-work01 |
**服务端口**
- 网关jjb-saas-gatewayNodePort **30140**(外部访问入口)
- 其余微服务:均为 ClusterIP 类型(集群内部 80 端口)
## 七、快速接入指南
### 7.1 访问各管理控制台
| 服务 | 地址 | 账号 | 密码 |
|------|------|------|------|
| Nacos | http://192.168.20.100:30290/nacos | `nacos` | `nacos` |
| RocketMQ Console | http://192.168.20.100:30300 | 无需登录 | - |
| MinIO Console | http://192.168.20.100:9001 | `admin` | `Zcloud@zcloud2026` |
| K8s Dashboard | https://192.168.20.100:30180 | Token 登录 | 见 3.3 节 |
| 业务网关 | http://192.168.20.100:30140 | 待业务修复后可用 | - |
### 7.2 微服务 Nacos 配置模板
```yaml
spring:
cloud:
nacos:
discovery:
server-addr: prod-nacos:8848
namespace: jjb-dragon
config:
server-addr: prod-nacos:8848
namespace: jjb-dragon
file-extension: yml
datasource:
url: jdbc:mysql://192.168.20.100:33080/jjb-saas-xxx?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: Mysql@zcloud33080
redis:
host: 192.168.20.100
port: 6379
password: Zcloud@zcloud2026
```
### 7.3 SSH 连接服务器
```bash
# Master
ssh root@192.168.20.100 # 密码: Zcloud@zcloud100
# Worker01
ssh root@192.168.20.110 # 密码: Zcloud@zcloud110
# Worker02
ssh root@192.168.20.120 # 密码: Zcloud@zcloud120
```
### 7.4 常用运维命令
```bash
# 查看所有 Pod 状态
kubectl get pods -A -o wide
# 查看 jjb-dragon 命名空间下所有资源
kubectl get all -n jjb-dragon
# 查看 Pod 日志
kubectl logs -n jjb-dragon deploy/<deployment> --tail=100
# 重启某个服务
kubectl rollout restart deployment/<deployment> -n jjb-dragon
# 查看节点资源使用
kubectl top nodes
kubectl top pods -n jjb-dragon
# 进入 Pod 内部
kubectl exec -it -n jjb-dragon deploy/<deployment> -- /bin/bash
```
---
## 八、服务端口速查表
| 端口 | 协议 | 服务 | 说明 |
|------|------|------|------|
| 22 | TCP | SSH | 服务器管理 |
| 80 | TCP | 业务网关ClusterIP | 集群内部 |
| 6379 | TCP | Redis | 外部可访问 |
| 6443 | TCP | K8s API Server | 集群管理 |
| 8848 | TCP | Nacos HTTP | 集群内部 |
| 9000 | TCP | MinIO API | 对象存储 API |
| 9001 | TCP | MinIO Console | Web 管理界面 |
| 9876 | TCP | RocketMQ NameServer | 集群内部 |
| 10911 | TCP | RocketMQ Broker | 集群内部 |
| 30140 | TCP | 业务网关 NodePort | 外部访问入口 |
| 30180 | TCP | K8s Dashboard | Web UIHTTPS |
| 30290 | TCP | Nacos Console | Web 管理界面 |
| 30300 | TCP | RocketMQ Console | Web 管理界面 |
| 30658 | TCP | RocketMQ NameServer NodePort | 外部访问 |
| 30740 | TCP | Nacos Jraft | 集群通信 |
| 31290 | TCP | Nacos gRPC Client | 集群通信 |
| 31291 | TCP | Nacos gRPC Raft | 集群通信 |
| 33080 | TCP | MySQL | 数据库连接 |
---

File diff suppressed because it is too large Load Diff

39
docs/sql/init.sql Normal file
View File

@ -0,0 +1,39 @@
-- =============================================
-- 安全评价业务库初始建表脚本
-- 数据库safety_eval_db
-- 字符集utf8mb4排序规则utf8mb4_0900_ai_ci
-- =============================================
CREATE DATABASE IF NOT EXISTS `safety_eval_db`
CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci;
USE `safety_eval_db`;
-- =============================================
-- 评价机构主档案
-- =============================================
CREATE TABLE IF NOT EXISTS `se_institution` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '机构名称',
`credit_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '统一社会信用代码',
`legal_person_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '法人姓名',
`contact_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '联系人姓名',
`contact_phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '联系电话',
`status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '入驻状态(PENDING/APPROVED/REJECTED)',
-- GBS默认字段
`delete_enum` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT 'false' COMMENT '删除标识true/false',
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
`create_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人姓名',
`update_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '更新人姓名',
`tenant_id` bigint DEFAULT NULL COMMENT '租户id',
`org_id` bigint DEFAULT NULL COMMENT '单位id',
`version` int DEFAULT NULL COMMENT '版本',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`create_id` bigint DEFAULT NULL COMMENT '创建人id',
`update_id` bigint DEFAULT NULL COMMENT '更新人id',
`env` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '环境',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_credit_code` (`credit_code`, `delete_enum`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='评价机构主档案';

View File

@ -0,0 +1,433 @@
# 基于 GBS 底座的安全评价系统开发内容梳理
## 1. 建设定位
重庆安全评价在线服务应用基于 GBS 底座和已有基础服务建设采用“GBS 基础能力复用 + 安全评价业务服务扩展”的方式落地。
当前建设主线聚焦评价机构准入和档案形成,优先完成以下闭环:
1. 评价机构账号注册与身份接入。
2. 机构入驻申请。
3. 机构基础信息、资质材料、人员证书、制度文件等资料提交。
4. 监管端资料受理、资料评审、补正、复审和审核确认。
5. 入驻结果通知、公示查询和机构档案形成。
6. 项目管理、现场监管、报告归档、服务评价等扩展能力基于机构档案逐步建设。
## 2. GBS 底座复用范围
| GBS 能力/服务 | 本系统使用方式 | 复用标识 | 落地内容 |
| --- | --- | --- | --- |
| `jjb-saas-gateway` | 统一访问入口、路由、鉴权前置 | 复用 | 机构端、监管端、公示端统一入口 |
| `jjb-saas-auth` / `jjb-saas-login` | 登录、Token、认证 | 复用 | 支撑机构用户和监管用户登录 |
| `jjb-saas-user` | 用户、账号、人员基础信息 | 复用 | 用户账号、联系人、审核人员基础信息 |
| `jjb-saas-system` | 菜单、角色、组织、数据权限 | 复用 | 机构端、监管端菜单和角色配置 |
| `jjb-saas-security` | 安全审计、权限控制 | 复用 | 操作审计、接口访问控制 |
| `jjb-saas-base` | 字典、区域、通用主数据 | 复用 | 行政区划、机构类型、证书类型、材料类型 |
| `jjb-saas-attachment` | 文件上传、预览、下载、存储 | 复用 | 营业执照、资质证书、人员证书、制度文件等材料 |
| `jjb-saas-message` | 通知、待办、催办 | 复用 | 审核待办、补正提醒、审核结果通知 |
| `jjb-saas-bpm` | 流程流转、待办、审批轨迹 | 复用 | 入驻审核、资料补正、资质变更审核 |
| `jjb-saas-process-layout` | 流程页面和流程布局 | 复用 | 入驻评审节点页面布局 |
| `jjb-saas-formily-design` | 动态表单设计 | 复用 | 入驻申请表、资料清单表、审核表单 |
| `jjb-saas-component-design` | 通用组件设计 | 复用 | 查询列表、详情页、附件列表、审核表单组件 |
| `jjb-saas-open-platform` | 外部接口接入 | 复用 | 统一社会信用代码、证书查询等接口接入 |
| `jjb-saas-data-center` | 数据汇总、统计分析 | 复用 | 机构数量、审核效率、入驻态势统计 |
| `jjb-saas-events` / `RocketMQ` | 状态变更事件 | 复用 | 入驻状态、档案变更、通知事件 |
| `Nacos` | 配置中心、服务注册 | 复用 | 安评业务服务注册与配置 |
| `MinIO` | 附件对象存储 | 复用 | 通过附件服务保存材料文件 |
| `MySQL` | 业务数据存储 | 复用基础设施 | 新增安评业务库 |
| `Redis` | 缓存、验证码、临时状态 | 复用 | 登录辅助、验证码、短期缓存 |
## 3. 新增业务服务
### 3.1 服务设置
| 服务 | 建议名称 | 主要职责 |
| --- | --- | --- |
| 安全评价业务服务 | `safety-eval-service` | 承载评价机构入驻、资料评审、机构档案、资质人员维护、项目登记、报告归档、服务评价等安全评价业务 |
### 3.2 服务职责
`safety-eval-service` 负责安全评价行业数据和业务规则的统一承载,重点包含:
1. 机构入驻申请单。
2. 机构业务档案。
3. 机构资质和人员证书。
4. 材料清单、材料附件引用和材料审核结果。
5. 审核意见、补正记录、档案版本。
6. 与 GBS 用户、权限、流程、附件、消息、字典、数据中心等服务的接口适配。
### 3.3 业务校验
业务校验由 `safety-eval-service` 通过固定校验、字典配置和参数配置实现:
| 校验场景 | 实现方式 |
| --- | --- |
| 统一社会信用代码格式校验 | 服务内固定校验 |
| 入驻材料完整性校验 | 材料清单配置 + 必填项校验 |
| 资质证书有效期校验 | 日期字段校验 |
| 人员证书有效期校验 | 日期字段校验 |
| 重复入驻校验 | 机构统一社会信用代码唯一性校验 |
| 节点提交前校验 | 业务服务提供校验接口,流程节点提交时调用 |
| 到期提醒 | 定时任务扫描有效期并调用消息服务 |
### 3.4 流程复用
流程能力复用 GBS 的 `jjb-saas-bpm``jjb-saas-process-layout`
本项目落地内容:
1. 入驻审核流程模板。
2. 资料补正流程节点。
3. 资质和人员变更审核流程模板。
4. 审核意见、审核结论、材料状态与业务状态映射。
5. 业务服务与 BPM 的流程启动、提交、退回、办结接口适配。
## 4. 当前需要开发的内容
### 4.1 P0评价机构注册入驻与资料评审
| 功能 | 主要内容 | 依赖底座 |
| --- | --- | --- |
| 机构账号注册 | 机构管理员注册、账号登录、绑定机构 | login、auth、user |
| 机构基础核验 | 统一社会信用代码、机构名称、法人信息、联系人 | base、open-platform |
| 入驻申请 | 填写机构基本信息、业务范围、办公地址、联系方式 | formily、base |
| 资料清单配置 | 配置营业执照、资质证书、人员证书、制度文件、承诺书等材料项 | base、formily |
| 材料上传 | 多类型附件上传、预览、替换、版本记录 | attachment、MinIO |
| 材料完整性校验 | 提交前校验必填项、格式、有效期、重复机构 | safety-eval-service |
| 入驻审核流程 | 受理、资料审查、补正、复审、通过、驳回 | bpm、message |
| 补正管理 | 审核人员发起补正,机构重新提交,保留历史意见 | bpm、message、attachment |
| 审核意见记录 | 逐项材料审核意见、总体意见、附件留痕 | safety-eval-service |
| 机构档案 | 入驻通过后生成机构档案、资质档案、人员档案 | safety-eval-service |
| 入驻结果通知 | 站内信、短信、待办通知 | message |
| 机构公示 | 已入驻机构列表、详情、资质范围展示 | official 或业务前端 |
### 4.2 P1资质人员维护与变更
| 功能 | 主要内容 | 依赖底座 |
| --- | --- | --- |
| 机构信息维护 | 地址、联系人、法人、简介等信息维护 | user、base、attachment |
| 资质证书维护 | 资质范围、等级、有效期、证书附件 | attachment |
| 人员信息维护 | 专职人员、评价师、技术负责人、过程控制负责人 | user、base |
| 人员证书维护 | 证书类型、专业、有效期、附件 | attachment |
| 变更审核 | 重要信息变更走审核流程 | bpm、message |
| 到期提醒 | 资质和证书到期前提醒 | message、xxl-job |
### 4.3 P2项目与报告基础能力
| 功能 | 建设内容 |
| --- | --- |
| 项目登记 | 项目基本信息、服务企业、评价类型、合同附件 |
| 项目组 | 人员选择、项目角色、项目负责人 |
| 从业告知 | 告知信息提交、附件、状态记录 |
| 项目进度 | 业务状态和流程状态联动 |
| 报告上传 | 报告文件上传、版本记录、审核意见 |
| 报告归档 | 归档材料、归档状态、归档查询 |
### 4.4 P3监管统计与服务评价
| 功能 | 建设内容 |
| --- | --- |
| 现场作业 | 现场任务、签到记录、照片材料、作业记录 |
| 服务评价 | 企业评价、监管评价、评价汇总 |
| 监管统计 | 入驻数量、项目数量、审核效率、机构活跃度 |
| 风险提醒 | 证书到期、资料缺失、项目异常等固定提醒 |
## 5. 系统架构
### 5.1 总体架构
```mermaid
flowchart TB
subgraph U["访问端"]
A1["评价机构端"]
A2["监管审核端"]
A3["公众公示端"]
A4["企业端/移动端扩展"]
end
subgraph GBS["GBS 底座复用层"]
GW["gateway 网关<br/>复用"]
AUTH["auth/login 认证<br/>复用"]
USER["user/system 用户组织权限<br/>复用"]
BASE["base 字典区域<br/>复用"]
BPM["bpm/process-layout 流程<br/>复用"]
FORM["formily/component 表单组件<br/>复用"]
ATT["attachment/MinIO 附件<br/>复用"]
MSG["message 消息待办<br/>复用"]
OPEN["open-platform 外部接口<br/>复用"]
DATA["data-center 数据中心<br/>复用"]
end
subgraph BIZ["新增业务层"]
SE["safety-eval-service<br/>安全评价业务服务"]
DB["safety_eval_db<br/>安评业务库"]
end
A1 --> GW
A2 --> GW
A3 --> GW
A4 --> GW
GW --> AUTH
GW --> SE
SE --> USER
SE --> BASE
SE --> BPM
SE --> FORM
SE --> ATT
SE --> MSG
SE --> OPEN
SE --> DATA
SE --> DB
```
### 5.2 业务分层架构
```mermaid
flowchart LR
UI["前端页面<br/>机构端/监管端/公示端"] --> API["业务接口<br/>safety-eval-service"]
API --> APP["应用层<br/>注册入驻/资料评审/档案维护"]
APP --> DOMAIN["领域层<br/>机构/资质/人员/材料/审核"]
DOMAIN --> INFRA["基础设施适配层<br/>GBS用户/流程/附件/消息/字典"]
DOMAIN --> DB["业务库"]
INFRA --> GBS["GBS基础服务"]
```
## 6. 核心业务流程
### 6.1 评价机构注册入驻主流程
```mermaid
flowchart TD
A["机构管理员注册账号"] --> B["登录机构端"]
B --> C["创建/绑定评价机构"]
C --> D["填写机构基础信息"]
D --> E["上传入驻资料"]
E --> F["提交前完整性校验"]
F -->|校验未通过| E
F -->|校验通过| G["启动入驻审核流程<br/>复用 GBS BPM"]
G --> H["监管端受理"]
H --> I["资料逐项评审"]
I -->|需补正| J["发起补正<br/>复用 BPM/消息"]
J --> K["机构补正材料"]
K --> I
I -->|驳回| L["结束并通知机构"]
I -->|通过| M["生成机构档案"]
M --> N["入驻结果通知"]
N --> O["机构公示/业务准入"]
```
### 6.2 资料评审流程
```mermaid
flowchart TD
A["审核人员打开待办"] --> B["查看机构申请信息"]
B --> C["查看材料清单"]
C --> D["逐项预览附件"]
D --> E{"材料是否符合要求"}
E -->|符合| F["标记材料通过"]
E -->|需补正| G["填写问题和补正要求"]
F --> H{"全部材料是否完成"}
G --> H
H -->|继续评审| C
H -->|提交补正| I["提交补正意见"]
H -->|审核通过| J["提交通过意见"]
I --> K["流程退回机构补正<br/>复用 GBS BPM"]
J --> L["流程办结,生成机构档案"]
```
### 6.3 资质/人员变更流程
```mermaid
flowchart TD
A["机构发起信息变更"] --> B["选择变更类型"]
B --> C["修改信息并上传证明材料"]
C --> D["提交变更申请"]
D --> E["业务服务校验材料完整性"]
E -->|校验未通过| C
E -->|校验通过| F["启动变更审核流程<br/>复用 GBS BPM"]
F --> G["监管审核"]
G -->|补正| H["机构补正"]
H --> G
G -->|驳回| I["保持原档案"]
G -->|通过| J["更新机构档案并记录版本"]
```
## 7. 时序图
### 7.1 机构提交入驻申请
```mermaid
sequenceDiagram
participant O as 机构用户
participant FE as 机构端前端
participant SE as safety-eval-service
participant U as GBS用户/权限
participant A as GBS附件服务
participant B as GBS流程BPM
participant M as GBS消息服务
participant DB as 安评业务库
O->>FE: 填写入驻信息并上传材料
FE->>A: 上传附件
A-->>FE: 返回附件ID
FE->>SE: 提交入驻申请
SE->>U: 校验用户与机构权限
U-->>SE: 返回校验结果
SE->>DB: 保存申请、材料清单、附件引用
SE->>SE: 执行完整性和有效期校验
SE->>B: 启动入驻审核流程(复用)
B-->>SE: 返回流程实例ID
SE->>DB: 更新申请状态为审核中
SE->>M: 发送监管待办和通知(复用)
SE-->>FE: 返回提交成功
```
### 7.2 监管人员资料评审
```mermaid
sequenceDiagram
participant R as 监管审核人员
participant FE as 监管端前端
participant B as GBS流程BPM
participant SE as safety-eval-service
participant A as GBS附件服务
participant M as GBS消息服务
participant DB as 安评业务库
R->>FE: 打开入驻审核待办
FE->>B: 查询流程待办(复用)
B-->>FE: 返回待办信息
FE->>SE: 查询申请详情和材料清单
SE->>DB: 读取机构申请、材料、历史意见
SE-->>FE: 返回详情
FE->>A: 预览材料附件(复用)
R->>FE: 填写逐项审核意见
FE->>SE: 保存审核意见
SE->>DB: 保存材料审核结果
R->>FE: 提交通过/补正/驳回
FE->>SE: 提交流程动作
SE->>B: 提交/退回流程(复用)
B-->>SE: 返回流程状态
SE->>DB: 更新申请状态与机构档案
SE->>M: 通知机构处理结果(复用)
SE-->>FE: 返回处理完成
```
## 8. 数据流
### 8.1 入驻数据流
```mermaid
flowchart LR
A["机构端录入"] --> B["safety-eval-service"]
B --> C["安评业务库<br/>机构/申请/材料/审核意见"]
A --> D["GBS附件服务"]
D --> E["MinIO对象存储"]
D --> B
B --> F["GBS BPM<br/>流程实例/待办/轨迹"]
B --> G["GBS消息服务<br/>通知/催办"]
B --> H["GBS用户权限<br/>账号/角色/组织"]
B --> I["公示端/数据中心<br/>入驻结果与统计数据"]
```
### 8.2 业务数据归属
| 数据 | 保存位置 | 说明 |
| --- | --- | --- |
| 登录账号、基础用户 | GBS user/auth | 底座复用 |
| 角色、菜单、数据权限 | GBS system/security | 底座复用 |
| 字典、行政区划 | GBS base | 底座复用 |
| 附件文件 | GBS attachment + MinIO | 底座复用 |
| 流程实例、待办、流转记录 | GBS bpm | 底座复用 |
| 消息通知 | GBS message | 底座复用 |
| 机构业务档案 | `safety_eval_db` | 新增 |
| 入驻申请 | `safety_eval_db` | 新增 |
| 材料清单和审核结果 | `safety_eval_db` | 新增 |
| 资质、人员、证书扩展信息 | `safety_eval_db` | 新增 |
| 公示信息 | `safety_eval_db` 或数据中心 | 业务查询与统计展示 |
## 9. 建议业务数据模型
一期数据模型围绕机构入驻和资料评审设计。
| 表/对象 | 作用 |
| --- | --- |
| `se_institution` | 评价机构主档案 |
| `se_institution_apply` | 入驻/变更申请单 |
| `se_institution_qualification` | 机构资质证书 |
| `se_institution_personnel` | 机构人员 |
| `se_personnel_certificate` | 人员证书 |
| `se_material_item` | 材料清单配置 |
| `se_apply_material` | 申请材料与附件引用 |
| `se_material_review` | 材料逐项评审意见 |
| `se_apply_review_record` | 申请总体审核意见 |
| `se_institution_archive_version` | 机构档案版本 |
| `se_public_disclosure` | 入驻公示信息 |
## 10. 接口边界
### 10.1 `safety-eval-service` 对前端提供
| 接口组 | 示例能力 |
| --- | --- |
| 机构注册入驻 | 创建机构、查询机构、提交入驻申请、撤回申请 |
| 材料管理 | 查询材料清单、上传后绑定材料、替换材料、查看材料状态 |
| 审核管理 | 查询待审核申请、保存材料意见、提交通过/补正/驳回 |
| 档案管理 | 查询机构档案、资质、人员、证书、档案版本 |
| 公示查询 | 查询已入驻机构列表与详情 |
### 10.2 `safety-eval-service` 调用 GBS
| GBS 服务 | 调用目的 |
| --- | --- |
| user/system/auth | 当前用户、角色、机构绑定、数据权限 |
| base | 字典、区域、材料类型 |
| attachment | 附件上传结果、预览、下载、删除权限 |
| bpm | 启动流程、提交节点、退回、查询流程状态 |
| message | 待办提醒、审核结果通知、补正提醒 |
| open-platform | 工商、证书等外部数据核验 |
| data-center | 统计分析 |
## 11. 开发优先级
### 第一阶段:机构入驻闭环
目标:让评价机构能够进入平台,监管人员能够完成资料评审。
1. GBS 账号、角色、菜单、机构端/监管端权限配置。
2. `safety-eval-service` 工程、数据库、基础字典。
3. 机构注册、机构绑定、入驻申请。
4. 材料清单配置、附件绑定、提交校验。
5. 入驻审核 BPM 流程模板复用与适配。
6. 监管端资料评审、补正、通过、驳回。
7. 入驻通过后生成机构档案。
8. 入驻结果通知与公示查询。
### 第二阶段:资质人员维护
目标:保证机构档案持续有效。
1. 资质证书维护。
2. 人员及证书维护。
3. 重要信息变更审核。
4. 到期提醒。
5. 档案版本记录。
### 第三阶段:项目与报告基础
目标:在机构档案基础上扩展业务办理。
1. 项目登记。
2. 项目组维护。
3. 从业告知。
4. 报告上传与归档基础。
### 第四阶段:监管增强
目标:补充监管效率和服务质量能力。
1. 现场作业证据。
2. 服务评价。
3. 风险提醒。
4. 统计分析。

163
pom.xml Normal file
View File

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jjb.saas</groupId>
<artifactId>jjb-saas-parent</artifactId>
<version>2.2.0-SNAPSHOT</version>
</parent>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-service</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>safety-eval-service</name>
<description>安全评价业务服务 - 基于GBS底座DDD分层架构</description>
<modules>
<module>safety-eval-start</module>
<module>safety-eval-adapter</module>
<module>safety-eval-app</module>
<module>safety-eval-client</module>
<module>safety-eval-domain</module>
<module>safety-eval-infrastructure</module>
</modules>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring Boot -->
<spring-boot.version>2.7.18</spring-boot.version>
<!-- Dubbo -->
<dubbo.version>3.2.9</dubbo.version>
<!-- MyBatis Plus -->
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<!-- Swagger -->
<swagger.version>1.6.14</swagger.version>
<!-- Lombok -->
<lombok.version>1.18.30</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 本项目内部模块 -->
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-start</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-adapter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-app</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-domain</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-infrastructure</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- MyBatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>gbs-snapshots</id>
<name>GBS Snapshots Repository</name>
<url>http://192.168.20.100:8578/repository/maven-snapshots/</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
<repository>
<id>gbs-releases</id>
<name>GBS Releases Repository</name>
<url>http://192.168.20.100:8578/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-service</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>safety-eval-adapter</artifactId>
<packaging>jar</packaging>
<name>safety-eval-adapter</name>
<description>适配层 - 负责对前端展示的路由和适配相当于MVC的Controller</description>
<dependencies>
<!-- Client层 -->
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-client</artifactId>
</dependency>
<!-- App层 -->
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-app</artifactId>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- DubboAdapter层可能引用其他服务 facade -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,43 @@
package org.qinan.safetyeval.adapter.web;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.qinan.safetyeval.client.api.InstitutionApi;
import org.qinan.safetyeval.client.co.InstitutionCO;
import org.qinan.safetyeval.client.dto.InstitutionAddCmd;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* Controller
* <p>
* Adapter
* 使: @PreAuthorize("@pms.hasPermission('*-*-*')")
* </p>
*
* @author safety-eval
*/
@Api(tags = "评价机构管理")
@RestController
@RequestMapping("/institution")
public class InstitutionController {
@Resource
private InstitutionApi institutionApi;
@ApiOperation("新增评价机构")
@PostMapping("/save")
// @PreAuthorize("@pms.hasPermission('1-6-1')") // TODO: 配置实际权限编码
public InstitutionCO add(@Validated @RequestBody InstitutionAddCmd cmd) {
return institutionApi.add(cmd);
}
@ApiOperation("查询评价机构详情")
@GetMapping("/get")
// @PreAuthorize("@pms.hasPermission('1-6-2')")
public InstitutionCO get(@RequestParam Long id) {
return institutionApi.get(id);
}
}

44
safety-eval-app/pom.xml Normal file
View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-service</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>safety-eval-app</artifactId>
<packaging>jar</packaging>
<name>safety-eval-app</name>
<description>应用层 - 获取输入、组装上下文、参数校验、调用领域层做业务处理</description>
<dependencies>
<!-- Client层 -->
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-client</artifactId>
</dependency>
<!-- Domain层 -->
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-domain</artifactId>
</dependency>
<!-- Infrastructure层应用层可直接调用基础设施层 -->
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-infrastructure</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,59 @@
package org.qinan.safetyeval.app.executor;
import org.qinan.safetyeval.client.api.InstitutionApi;
import org.qinan.safetyeval.client.co.InstitutionCO;
import org.qinan.safetyeval.client.dto.InstitutionAddCmd;
import org.qinan.safetyeval.domain.entity.InstitutionEntity;
import org.qinan.safetyeval.domain.gateway.InstitutionGateway;
import org.qinan.safetyeval.domain.service.InstitutionDomainService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* App
* <p>
* domain
*
* </p>
*
* @author safety-eval
*/
@Service
public class InstitutionExecutor implements InstitutionApi {
@Resource
private InstitutionDomainService institutionDomainService;
@Override
public InstitutionCO add(InstitutionAddCmd cmd) {
// Cmd -> Entity 转换
InstitutionEntity entity = new InstitutionEntity();
entity.setName(cmd.getName());
entity.setCreditCode(cmd.getCreditCode());
entity.setLegalPersonName(cmd.getLegalPersonName());
entity.setContactName(cmd.getContactName());
entity.setContactPhone(cmd.getContactPhone());
// 调用领域服务处理业务逻辑
InstitutionEntity result = institutionDomainService.add(entity);
// Entity -> CO 转换
return toCO(result);
}
@Override
public InstitutionCO get(Long id) {
InstitutionEntity entity = institutionDomainService.get(id);
return toCO(entity);
}
private InstitutionCO toCO(InstitutionEntity entity) {
InstitutionCO co = new InstitutionCO();
co.setId(entity.getId());
co.setName(entity.getName());
co.setCreditCode(entity.getCreditCode());
co.setStatus(entity.getStatus());
return co;
}
}

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-service</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>safety-eval-client</artifactId>
<packaging>jar</packaging>
<name>safety-eval-client</name>
<description>Client层 - 对外暴露的接口定义、DTO、CO对象供其他服务Dubbo调用</description>
<dependencies>
<!-- Domain层 -->
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-domain</artifactId>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,25 @@
package org.qinan.safetyeval.client.api;
import org.qinan.safetyeval.client.co.InstitutionCO;
import org.qinan.safetyeval.client.dto.InstitutionAddCmd;
/**
* Client
* <p>
* AdapterDubbo
* </p>
*
* @author safety-eval
*/
public interface InstitutionApi {
/**
*
*/
InstitutionCO add(InstitutionAddCmd cmd);
/**
*
*/
InstitutionCO get(Long id);
}

View File

@ -0,0 +1,27 @@
package org.qinan.safetyeval.client.co;
import lombok.Data;
/**
* COClient Object-
* <p>
* AdapterCo
* </p>
*
* @author safety-eval
*/
@Data
public class InstitutionCO {
/** 机构ID */
private Long id;
/** 机构名称 */
private String name;
/** 统一社会信用代码 */
private String creditCode;
/** 入驻状态 */
private String status;
}

View File

@ -0,0 +1,31 @@
package org.qinan.safetyeval.client.dto;
import lombok.Data;
/**
*
* <p>
* xxCmd@Validated
* </p>
*
* @author safety-eval
*/
@Data
public class InstitutionAddCmd {
/** 机构名称 */
private String name;
/** 统一社会信用代码 */
private String creditCode;
/** 法人姓名 */
private String legalPersonName;
/** 联系人姓名 */
private String contactName;
/** 联系电话 */
private String contactPhone;
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-service</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>safety-eval-domain</artifactId>
<packaging>jar</packaging>
<name>safety-eval-domain</name>
<description>领域层 - 核心业务逻辑,不依赖任何其他层次</description>
<dependencies>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,42 @@
package org.qinan.safetyeval.domain.entity;
import lombok.Data;
/**
*
* <p>
*
* </p>
*
* @author safety-eval
*/
@Data
public class InstitutionEntity {
/** 机构ID */
private Long id;
/** 机构名称 */
private String name;
/** 统一社会信用代码 */
private String creditCode;
/** 法人姓名 */
private String legalPersonName;
/** 联系人姓名 */
private String contactName;
/** 联系电话 */
private String contactPhone;
/** 入驻状态 */
private String status;
/** 租户ID */
private Long tenantId;
/** 单位ID */
private Long orgId;
}

View File

@ -0,0 +1,30 @@
package org.qinan.safetyeval.domain.gateway;
import org.qinan.safetyeval.domain.entity.InstitutionEntity;
/**
* GatewayDomain
* <p>
* Gatewaydomaininfrastructure
* gatewayAppDomain使
* </p>
*
* @author safety-eval
*/
public interface InstitutionGateway {
/**
*
*/
InstitutionEntity save(InstitutionEntity entity);
/**
* ID
*/
InstitutionEntity get(Long id);
/**
*
*/
InstitutionEntity getByCreditCode(String creditCode);
}

View File

@ -0,0 +1,44 @@
package org.qinan.safetyeval.domain.service;
import org.qinan.safetyeval.domain.entity.InstitutionEntity;
import org.qinan.safetyeval.domain.gateway.InstitutionGateway;
import javax.annotation.Resource;
/**
*
* <p>
*
*
* </p>
*
* @author safety-eval
*/
public class InstitutionDomainService {
@Resource
private InstitutionGateway institutionGateway;
/**
* -
* <p>
*
* </p>
*/
public InstitutionEntity add(InstitutionEntity entity) {
// 重复入驻校验
InstitutionEntity existing = institutionGateway.getByCreditCode(entity.getCreditCode());
if (existing != null) {
throw new RuntimeException("该统一社会信用代码已注册机构,不可重复入驻");
}
entity.setStatus("PENDING");
return institutionGateway.save(entity);
}
/**
*
*/
public InstitutionEntity get(Long id) {
return institutionGateway.get(id);
}
}

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-service</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>safety-eval-infrastructure</artifactId>
<packaging>jar</packaging>
<name>safety-eval-infrastructure</name>
<description>基础设施层 - 数据库CRUD、搜索引擎、分布式服务RPC等领域防腐重任</description>
<dependencies>
<!-- Domain层实现domain层定义的gateway接口 -->
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-domain</artifactId>
</dependency>
<!-- MyBatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- Dubbo调用其他GBS服务 facade -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.jjb.saas</groupId>
<artifactId>jjb-saas-application-client</artifactId>
</dependency>
<dependency>
<groupId>com.jjb.saas</groupId>
<artifactId>jjb-saas-system-client</artifactId>
</dependency>
<dependency>
<groupId>com.jjb.saas</groupId>
<artifactId>jjb-saas-auth-client</artifactId>
</dependency>
<dependency>
<groupId>com.jjb.saas</groupId>
<artifactId>jjb-saas-framework-facade</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,25 @@
package org.qinan.safetyeval.infrastructure.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MyBatis Plus
*
* @author safety-eval
*/
@Configuration
@MapperScan("org.qinan.safetyeval.infrastructure.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

View File

@ -0,0 +1,79 @@
package org.qinan.safetyeval.infrastructure.dataobject;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* Infrastructure -
* <p>
* GBS
* delete_enum, remarks, create_name, update_name, tenant_id, org_id,
* version, create_time, update_time, create_id, update_id, env
* </p>
*
* @author safety-eval
*/
@Data
@TableName("se_institution")
public class InstitutionDO {
/** 主键ID */
private Long id;
/** 机构名称 */
private String name;
/** 统一社会信用代码 */
private String creditCode;
/** 法人姓名 */
private String legalPersonName;
/** 联系人姓名 */
private String contactName;
/** 联系电话 */
private String contactPhone;
/** 入驻状态 */
private String status;
// ---- GBS默认字段 ----
/** 删除标识 */
private String deleteEnum;
/** 备注 */
private String remarks;
/** 创建人姓名 */
private String createName;
/** 更新人姓名 */
private String updateName;
/** 租户ID */
private Long tenantId;
/** 单位ID */
private Long orgId;
/** 版本 */
private Integer version;
/** 创建时间 */
private LocalDateTime createTime;
/** 修改时间 */
private LocalDateTime updateTime;
/** 创建人ID */
private Long createId;
/** 更新人ID */
private Long updateId;
/** 环境 */
private String env;
}

View File

@ -0,0 +1,80 @@
package org.qinan.safetyeval.infrastructure.gatewayimpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.qinan.safetyeval.domain.entity.InstitutionEntity;
import org.qinan.safetyeval.domain.gateway.InstitutionGateway;
import org.qinan.safetyeval.infrastructure.dataobject.InstitutionDO;
import org.qinan.safetyeval.infrastructure.mapper.InstitutionMapper;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* GatewayInfrastructure
* <p>
* Gatewaydomaininfrastructure
* gateway
* </p>
*
* @author safety-eval
*/
@Component
public class InstitutionGatewayImpl implements InstitutionGateway {
@Resource
private InstitutionMapper institutionMapper;
@Override
public InstitutionEntity save(InstitutionEntity entity) {
InstitutionDO dataObject = toDO(entity);
institutionMapper.insert(dataObject);
entity.setId(dataObject.getId());
return entity;
}
@Override
public InstitutionEntity get(Long id) {
InstitutionDO dataObject = institutionMapper.selectById(id);
return toEntity(dataObject);
}
@Override
public InstitutionEntity getByCreditCode(String creditCode) {
LambdaQueryWrapper<InstitutionDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(InstitutionDO::getCreditCode, creditCode);
wrapper.eq(InstitutionDO::getDeleteEnum, "false");
InstitutionDO dataObject = institutionMapper.selectOne(wrapper);
return toEntity(dataObject);
}
private InstitutionDO toDO(InstitutionEntity entity) {
InstitutionDO dataObject = new InstitutionDO();
dataObject.setName(entity.getName());
dataObject.setCreditCode(entity.getCreditCode());
dataObject.setLegalPersonName(entity.getLegalPersonName());
dataObject.setContactName(entity.getContactName());
dataObject.setContactPhone(entity.getContactPhone());
dataObject.setStatus(entity.getStatus());
dataObject.setTenantId(entity.getTenantId());
dataObject.setOrgId(entity.getOrgId());
dataObject.setDeleteEnum("false");
return dataObject;
}
private InstitutionEntity toEntity(InstitutionDO dataObject) {
if (dataObject == null) {
return null;
}
InstitutionEntity entity = new InstitutionEntity();
entity.setId(dataObject.getId());
entity.setName(dataObject.getName());
entity.setCreditCode(dataObject.getCreditCode());
entity.setLegalPersonName(dataObject.getLegalPersonName());
entity.setContactName(dataObject.getContactName());
entity.setContactPhone(dataObject.getContactPhone());
entity.setStatus(dataObject.getStatus());
entity.setTenantId(dataObject.getTenantId());
entity.setOrgId(dataObject.getOrgId());
return entity;
}
}

View File

@ -0,0 +1,14 @@
package org.qinan.safetyeval.infrastructure.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.qinan.safetyeval.infrastructure.dataobject.InstitutionDO;
/**
* MapperInfrastructure
*
* @author safety-eval
*/
@Mapper
public interface InstitutionMapper extends BaseMapper<InstitutionDO> {
}

81
safety-eval-start/pom.xml Normal file
View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-service</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>safety-eval-start</artifactId>
<packaging>jar</packaging>
<name>safety-eval-start</name>
<description>启动模块 - Spring Boot启动类</description>
<dependencies>
<!-- Adapter层 -->
<dependency>
<groupId>org.qinan</groupId>
<artifactId>safety-eval-adapter</artifactId>
</dependency>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- Nacos Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.0.5.0</version>
</dependency>
<!-- Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2021.0.5.0</version>
</dependency>
<!-- Spring Boot Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,22 @@
package org.qinan.safetyeval.start;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
*
* <p>
* GBSGBS
* </p>
*
* @author safety-eval
*/
@SpringBootApplication
@EnableDubbo
public class SafetyEvalApplication {
public static void main(String[] args) {
SpringApplication.run(SafetyEvalApplication.class, args);
}
}

View File

@ -0,0 +1,48 @@
server:
port: 8095
servlet:
context-path: /safety-eval
spring:
application:
name: safety-eval-service
cloud:
nacos:
discovery:
server-addr: 192.168.20.100:8848
namespace: public
config:
server-addr: 192.168.20.100:8848
namespace: public
file-extension: yml
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.20.100:3306/safety_eval_db?useUnicode=true&characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: root
mybatis-plus:
mapper-locations: classpath*:mapper/**/*.xml
global-config:
db-config:
logic-delete-field: deleteEnum
logic-delete-value: "true"
logic-not-delete-value: "false"
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
dubbo:
application:
name: safety-eval-service
protocol:
name: dubbo
port: 20895
registry:
address: nacos://192.168.20.100:8848
scan:
base-packages: org.qinan.safetyeval
logging:
level:
org.qinan.safetyeval: debug

View File

@ -0,0 +1,16 @@
# =============================================
# Bootstrap配置 - Nacos配置中心加载前的基础配置
# =============================================
spring:
application:
name: safety-eval-service
cloud:
nacos:
config:
server-addr: 192.168.20.100:8848
namespace: public
file-extension: yml
shared-configs:
- data-id: common.yml
group: DEFAULT_GROUP
refresh: true