fujian_water_biz_doc/output/merged_docs.md

6875 lines
209 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "福建水务营收系统概要设计文档"
author: "系统设计团队"
date: "2025年06月09日"
---
---
# 福建水务营收系统架构设计文档
## 文档信息
| 项目信息 | 详情 |
|---------|------|
| **项目名称** | 福建水务营收系统 |
| **文档类型** | 概要设计文档 |
| **技术框架** | RuoYi-Vue-Pro + yudao-ui-admin-vue3 |
| **文档版本** | v1.0 |
| **编写日期** | 2024-12-19 |
| **文档状态** | ✅ 基本完成 |
## 目录
- [一、系统架构概述](#一系统架构概述)
- [二、技术架构](#二技术架构)
- [三、应用架构](#三应用架构)
- [四、数据架构](#四数据架构)
- [五、安全架构](#五安全架构)
- [六、部署架构](#六部署架构)
- [七、接口架构](#七接口架构)
## 一、系统架构概述
福建水务营收系统采用多层架构设计,旨在支持集团化的集中管理、统一资源管理的业务需求。系统架构的设计目标是实现"一个业务平台、一网通平台"的建设目标,为集团及下属各分公司提供统一的营业收费系统。
系统架构主要包括以下核心特点:
- 多租户架构:支持集团、分公司、营业站点的多层级租户管理模式
- 统一资源服务:统一的数字水务系统运行资源环境
- 统一平台应用:统一业务流程,集中汇集数据
- 统一对外接口:提供标准的接口和能力
### 1. 系统总体架构图
```mermaid
graph TB
subgraph "用户层"
A1[Web管理端<br/>yudao-ui-admin-vue3]
A2[移动抄表端<br/>uni-app]
A3[客户微信端<br/>微信小程序]
A4[客户支付宝端<br/>支付宝小程序]
end
subgraph "网关层"
B1[Nginx负载均衡]
B2[API网关<br/>统一认证/权限控制]
end
subgraph "应用层"
C1[营收管理<br/>RuoYi-Vue-Pro]
C2[客户服务<br/>RuoYi-Vue-Pro]
C3[表务管理<br/>RuoYi-Vue-Pro]
C4[统计分析<br/>RuoYi-Vue-Pro]
end
subgraph "服务层"
D1[权限服务<br/>Spring Security]
D2[工作流服务<br/>Flowable]
D3[消息服务<br/>Redis MQ]
D4[文件服务<br/>MinIO/OSS]
end
subgraph "数据层"
E1[(OpenGauss 5.0+<br/>主从架构)]
E2[(Redis 6.0<br/>集群缓存)]
E3[文件存储<br/>分布式存储]
end
subgraph "外部接口"
F1[银行接口<br/>代扣/托收]
F2[支付接口<br/>微信/支付宝]
F3[短信接口<br/>阿里云/腾讯云]
F4[物联网接口<br/>智能水表]
end
A1 --> B1
A2 --> B1
A3 --> B1
A4 --> B1
B1 --> B2
B2 --> C1
B2 --> C2
B2 --> C3
B2 --> C4
C1 --> D1
C1 --> D2
C1 --> D3
C1 --> D4
C2 --> D1
C2 --> D3
C3 --> D1
C3 --> D2
C4 --> D1
D1 --> E1
D2 --> E1
D3 --> E2
D4 --> E3
C1 --> F1
C1 --> F2
C2 --> F3
C3 --> F4
```
### 2. 物理部署架构图
```mermaid
graph TB
subgraph "DMZ区域"
LB1[负载均衡器<br/>Nginx Cluster]
WAF[Web应用防火墙]
end
subgraph "应用服务区"
subgraph "Web服务集群"
WEB1[Web服务器1<br/>8核32G]
WEB2[Web服务器2<br/>8核32G]
end
subgraph "应用服务集群"
APP1[应用服务器1<br/>16核64G]
APP2[应用服务器2<br/>16核64G]
end
end
subgraph "数据服务区"
subgraph "数据库集群"
DB1[OpenGauss主库<br/>32核128G]
DB2[OpenGauss从库<br/>32核128G]
end
subgraph "缓存集群"
REDIS1[Redis主节点<br/>16核32G]
REDIS2[Redis从节点<br/>16核32G]
REDIS3[Redis哨兵<br/>8核16G]
end
subgraph "文件存储"
FILE1[文件服务器1<br/>8核32G 10TB]
FILE2[文件服务器2<br/>8核32G 10TB]
end
end
subgraph "管理服务区"
MONITOR[监控服务器<br/>8核16G]
BACKUP[备份服务器<br/>8核32G 20TB]
JUMP[跳板服务器<br/>4核8G]
end
Internet --> WAF
WAF --> LB1
LB1 --> WEB1
LB1 --> WEB2
WEB1 --> APP1
WEB1 --> APP2
WEB2 --> APP1
WEB2 --> APP2
APP1 --> DB1
APP2 --> DB1
DB1 --> DB2
APP1 --> REDIS1
APP2 --> REDIS1
REDIS1 --> REDIS2
REDIS3 --> REDIS1
REDIS3 --> REDIS2
APP1 --> FILE1
APP2 --> FILE2
FILE1 --> FILE2
MONITOR --> APP1
MONITOR --> APP2
MONITOR --> DB1
MONITOR --> REDIS1
BACKUP --> DB1
BACKUP --> FILE1
```
## 二、技术架构
系统采用B/S和M/S相结合的架构模式具体技术栈如下
### 1. 技术栈总览图
```mermaid
graph TB
subgraph "前端技术栈"
FE1[Vue 3.2+ TypeScript]
FE2[Element Plus UI]
FE3[Vite 构建工具]
FE4[Pinia 状态管理]
FE5[Vue Router 路由]
FE6[Axios HTTP请求]
FE7[ECharts 图表]
FE8[富文本编辑器]
end
subgraph "后端技术栈"
BE1[Spring Boot 3.x]
BE2[Spring Security 6.x]
BE3[MyBatis Plus 3.x]
BE4[Redis 6.0+]
BE5[OpenGauss 5.0+]
BE6[Knife4j API文档]
BE7[Jackson JSON处理]
BE8[Maven 依赖管理]
end
subgraph "中间件技术栈"
MW1[Nginx 负载均衡]
MW2[Redis 缓存集群]
MW3[Flowable 工作流]
MW4[Quartz 定时任务]
MW5[MinIO 文件存储]
MW6[RocketMQ 消息队列]
MW7[ElasticSearch 搜索]
MW8[Sentinel 熔断限流]
end
subgraph "移动端技术栈"
MB1[uni-app 跨平台]
MB2[uView UI组件]
MB3[微信小程序]
MB4[支付宝小程序]
MB5[H5响应式]
MB6[高德地图SDK]
MB7[NFC设备接口]
end
subgraph "监控运维技术栈"
OP1[SkyWalking APM]
OP2[Spring Boot Admin]
OP3[Docker 容器化]
OP4[Kubernetes 编排]
OP5[Jenkins CI/CD]
OP6[Prometheus 监控]
OP7[Grafana 仪表盘]
OP8[ELK 日志分析]
end
FE1 --> BE1
FE6 --> BE1
BE1 --> BE2
BE1 --> BE3
BE3 --> BE5
BE1 --> BE4
BE1 --> MW3
BE1 --> MW4
MW1 --> BE1
BE1 --> MW5
BE1 --> MW6
BE1 --> MW7
MW8 --> BE1
MB1 --> BE1
MB3 --> BE1
MB4 --> BE1
OP1 --> BE1
OP2 --> BE1
OP3 --> BE1
OP4 --> OP3
OP5 --> OP4
OP6 --> BE1
OP7 --> OP6
OP8 --> BE1
```
### 2. 系统数据流向图
```mermaid
flowchart TD
subgraph "数据采集层"
A1[移动抄表APP<br/>数据采集]
A2[智能水表<br/>远程数据]
A3[Web管理端<br/>业务录入]
A4[客户端小程序<br/>用户数据]
A5[外部系统<br/>接口数据]
end
subgraph "数据接入层"
B1[API网关<br/>数据验证]
B2[数据清洗<br/>格式转换]
B3[消息队列<br/>异步处理]
B4[数据缓存<br/>临时存储]
end
subgraph "业务处理层"
C1[抄表服务<br/>水量计算]
C2[收费服务<br/>账单生成]
C3[账务服务<br/>财务处理]
C4[工单服务<br/>流程处理]
C5[统计服务<br/>数据分析]
end
subgraph "数据存储层"
D1[(MySQL主库<br/>核心业务数据)]
D2[(MySQL从库<br/>查询数据)]
D3[(Redis缓存<br/>热点数据)]
D4[文件存储<br/>附件图片]
D5[(备份库<br/>历史数据)]
end
subgraph "数据服务层"
E1[查询服务<br/>数据检索]
E2[报表服务<br/>统计分析]
E3[接口服务<br/>对外开放]
E4[推送服务<br/>消息通知]
end
subgraph "数据展现层"
F1[管理后台<br/>业务操作]
F2[统计大屏<br/>可视化展示]
F3[移动端<br/>现场作业]
F4[客户端<br/>自助服务]
F5[第三方系统<br/>数据集成]
end
%% 数据流向关系
A1 --> B1
A2 --> B2
A3 --> B1
A4 --> B1
A5 --> B3
B1 --> B4
B2 --> B3
B3 --> C1
B4 --> C2
C1 --> D1
C2 --> D1
C3 --> D1
C4 --> D1
C5 --> D2
D1 --> D2
D1 --> D3
D1 --> D5
D2 --> E1
D3 --> E1
D1 --> E2
D2 --> E3
E1 --> F1
E2 --> F2
E3 --> F3
E4 --> F4
E3 --> F5
%% 反向数据流
F1 -.-> C2
F3 -.-> C1
F4 -.-> C3
F5 -.-> C4
```
### 3. 服务端技术架构
- 操作系统:国产 Linux 操作系统
- 数据库华为OpenGauss 5.0+数据库,企业级国产数据库
- 应用框架基于RuoYi-Vue-Pro框架定制开发
- 核心框架Spring Boot 3.x支持JDK 17/21
- ORM框架MyBatis Plus增强的MyBatis
- 权限框架Spring Security基于RBAC的权限管理
- 数据缓存Redis + Redisson高性能缓存和分布式锁
- 工作流引擎Flowable灵活的工作流处理
- 任务调度基于Quartz的CRON任务调度
- 服务监控Spring Boot Admin、SkyWalking APM
- 消息队列基于Redis的轻量级消息队列
- 文档生成Knife4j基于Swagger的API文档生成
- 代码生成自动化CRUD和表单代码生成器
- 多租户基于字段隔离的SaaS多租户设计
#### 2.1 RuoYi-Vue-Pro框架配置示例
**application.yml主配置文件**
```yaml
# 服务端口配置
server:
port: 48080
servlet:
context-path: /admin-api
# Spring Boot 配置
spring:
application:
name: water-biz-server
profiles:
active: local
# 数据源配置
datasource:
druid:
url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: ${MYSQL_PASSWORD:123456}
driver-class-name: com.mysql.cj.jdbc.Driver
# 连接池配置
initial-size: 10
min-idle: 10
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# Redis 配置
redis:
host: 127.0.0.1
port: 6379
password: ${REDIS_PASSWORD:}
database: 1
timeout: 6000ms
lettuce:
pool:
max-active: 32
max-wait: 6000ms
max-idle: 32
min-idle: 8
# MyBatis Plus 配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: NONE
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
type-aliases-package: cn.iocoder.yudao.module.*.dal.dataobject
# 水务系统多租户配置
yudao:
tenant:
enable: true
ignore-urls:
- /admin-api/water/tenant/get-id-by-name
- /admin-api/infra/file/*/get/**
ignore-tables:
- water_tenant
- water_system_config
- water_dict_data
- water_dict_type
# 水务系统安全配置
security:
permit-all-urls:
- /admin-api/water/auth/login
- /admin-api/water/auth/logout
- /admin-api/water/auth/refresh-token
- /admin-api/water/captcha/get
- /admin-api/water/sms/send
# 文件存储配置
file:
config:
type: local
local:
domain: http://127.0.0.1:48080
path: /Users/yunai/file_test
# 短信配置
sms:
alibaba:
access-key-id: ${SMS_ACCESS_KEY_ID:}
access-key-secret: ${SMS_ACCESS_KEY_SECRET:}
signature: 福建水务
template-code: SMS_123456
```
**多租户配置实现:**
```java
@Component
@Slf4j
public class WaterTenantConfiguration {
@Resource
private TenantProperties tenantProperties;
/**
* 多租户字段处理器
*/
@Bean
public TenantLineHandler tenantLineHandler() {
return new TenantLineHandler() {
@Override
public Expression getTenantId() {
// 从当前登录用户上下文获取租户ID
Long tenantId = TenantContextHolder.getTenantId();
if (tenantId == null) {
return null;
}
return new LongValue(tenantId);
}
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public boolean ignoreTable(String tableName) {
// 忽略的表不进行多租户处理
return tenantProperties.getIgnoreTables().contains(tableName);
}
};
}
/**
* 多租户拦截器
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 多租户插件
TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
tenantInterceptor.setTenantLineHandler(tenantLineHandler());
interceptor.addInnerInterceptor(tenantInterceptor);
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
```
**权限控制配置:**
```java
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Configuration
public class WaterSecurityConfiguration {
@Resource
private SecurityProperties securityProperties;
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity,
@Lazy TokenAuthenticationFilter tokenAuthenticationFilter) throws Exception {
return httpSecurity
// 设置 URL 安全权限
.authorizeHttpRequests(c -> c
// 1. 静态资源,可匿名访问
.requestMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
// 2. 设置 @PermitAll 无需认证
.requestMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll()
// 3. 兜底规则,必须认证
.anyRequest().authenticated()
)
// 设置处理器
.exceptionHandling(c -> c.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler))
// 添加 Token Filter
.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
// 不创建 SecurityContext
.sessionManagement(c -> c.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// 禁用 CSRF因为使用 token 机制
.csrf(AbstractHttpConfigurer::disable)
// 禁用 cors
.cors(AbstractHttpConfigurer::disable)
.build();
}
}
```
### 3. 客户端技术架构
- 前端框架基于yudao-ui-admin-vue3框架定制开发
- 核心框架Vue 3.x + TypeScript
- 组件库Element Plus现代化UI组件
- 状态管理Pinia新一代的Vue状态管理库
- 路由管理Vue Router
- HTTP工具Axios请求拦截与统一处理
- CSS框架Tailwind CSS / UnoCSS原子化CSS
- 图表组件ECharts强大的可视化图表库
- 富文本编辑器WangEditor
- 文件上传基于Element Plus的上传组件
- 权限控制:细粒度的按钮级权限控制
- 动态表格:支持拖拽、排序、筛选
- 代码规范ESLint + Prettier标准化代码风格
#### 3.1 前端项目结构配置
**package.json 依赖配置:**
```json
{
"name": "water-biz-ui-admin",
"version": "1.0.0",
"description": "福建水务营收系统管理后台",
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"@vueuse/core": "^10.5.0",
"axios": "^1.6.0",
"echarts": "^5.4.3",
"element-plus": "^2.4.2",
"pinia": "^2.1.7",
"vue": "^3.3.8",
"vue-router": "^4.2.5",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12"
},
"devDependencies": {
"@types/node": "^20.8.7",
"@typescript-eslint/eslint-plugin": "^6.9.1",
"@typescript-eslint/parser": "^6.9.1",
"@vitejs/plugin-vue": "^4.4.1",
"eslint": "^8.52.0",
"eslint-plugin-vue": "^9.17.0",
"prettier": "^3.0.3",
"typescript": "^5.2.2",
"vite": "^4.5.0",
"vue-tsc": "^1.8.22"
}
}
```
**vite.config.ts 构建配置:**
```typescript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'~': resolve(__dirname, 'src'),
'#': resolve(__dirname, 'types')
}
},
server: {
host: '0.0.0.0',
port: 3000,
open: true,
proxy: {
'/admin-api': {
target: 'http://127.0.0.1:48080',
changeOrigin: true,
ws: true
}
}
},
build: {
target: 'es2015',
outDir: 'dist',
assetsDir: 'static',
sourcemap: false,
chunkSizeWarningLimit: 1500,
rollupOptions: {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]'
}
}
}
})
```
**src/stores/user.ts 用户状态管理:**
```typescript
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { UserApi, UserVO } from '@/api/system/user'
import { getAccessToken, removeToken } from '@/utils/auth'
export const useUserStore = defineStore('user', () => {
const userInfo = ref<UserVO>()
const permissions = ref<string[]>([])
const roles = ref<string[]>([])
const nickname = computed(() => userInfo.value?.nickname ?? '')
const avatar = computed(() => userInfo.value?.avatar ?? '')
const email = computed(() => userInfo.value?.email ?? '')
// 获取用户信息
const getUserInfo = async () => {
const res = await UserApi.getUserProfile()
userInfo.value = res
permissions.value = res.permissions
roles.value = res.roles
}
// 用户登出
const logout = async () => {
try {
await UserApi.logout()
} finally {
await resetToken()
}
}
// 重置令牌
const resetToken = async () => {
userInfo.value = undefined
permissions.value = []
roles.value = []
removeToken()
}
// 检查权限
const hasPermission = (permission: string) => {
return permissions.value.includes(permission)
}
// 检查角色
const hasRole = (role: string) => {
return roles.value.includes(role)
}
return {
userInfo,
permissions,
roles,
nickname,
avatar,
email,
getUserInfo,
logout,
resetToken,
hasPermission,
hasRole
}
})
```
**src/utils/request.ts HTTP请求封装**
```typescript
import axios, { AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getAccessToken, getRefreshToken, removeToken } from '@/utils/auth'
import { useUserStore } from '@/stores/user'
// 创建 axios 实例
const service = axios.create({
baseURL: import.meta.env.VITE_BASE_URL,
timeout: 50000,
withCredentials: false
})
// 请求拦截器
service.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 添加 token
const accessToken = getAccessToken()
if (accessToken && config.headers) {
config.headers.Authorization = `Bearer ${accessToken}`
}
// 添加租户ID
const tenantId = localStorage.getItem('tenantId')
if (tenantId && config.headers) {
config.headers['tenant-id'] = tenantId
}
return config
},
error => {
console.log(error)
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
(response: AxiosResponse) => {
const { data } = response
const { code, msg } = data
// 业务请求成功
if (code === 0) {
return data
}
// token 过期,尝试刷新
if (code === 401) {
return handleTokenExpired()
}
// 业务请求失败
ElMessage.error(msg || '系统未知错误,请反馈给管理员')
return Promise.reject(new Error(msg || 'Error'))
},
error => {
console.log('err' + error)
let { message } = error
if (message === 'Network Error') {
message = '后端接口连接异常'
} else if (message.includes('timeout')) {
message = '系统接口请求超时'
} else if (message.includes('Request failed with status code')) {
message = '系统接口' + message.substr(message.length - 3) + '异常'
}
ElMessage.error(message)
return Promise.reject(error)
}
)
// 处理 token 过期
const handleTokenExpired = async () => {
const userStore = useUserStore()
ElMessageBox.alert('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
type: 'warning'
}).then(() => {
userStore.resetToken().then(() => {
location.reload()
})
})
}
export default service
```
### 4. 前端技术架构详细设计
#### 4.1 Web管理端架构 (yudao-ui-admin-vue3)
**技术栈组成:**
```mermaid
graph TB
subgraph "开发框架"
A1[Vue 3.2.47 Composition API]
A2[TypeScript 4.9.4]
A3[Vite 4.0.0 构建工具]
end
subgraph "UI组件库"
B1[Element Plus 2.3.14]
B2[Element Plus Icons]
B3[自定义组件库]
end
subgraph "状态管理"
C1[Pinia 2.0.28]
C2[持久化插件]
C3[全局状态管理]
end
subgraph "路由系统"
D1[Vue Router 4.1.6]
D2[路由守卫]
D3[动态路由]
D4[权限控制]
end
subgraph "HTTP通信"
E1[Axios 1.2.2]
E2[请求拦截器]
E3[响应拦截器]
E4[错误处理]
end
subgraph "工具库"
F1[Lodash 工具函数]
F2[dayjs 时间处理]
F3[nprogress 进度条]
F4[js-cookie Cookie管理]
F5[crypto-js 加密解密]
end
A1 --> B1
A1 --> C1
A1 --> D1
A1 --> E1
B1 --> B3
C1 --> C2
D1 --> D2
E1 --> E2
```
**项目结构设计:**
```text
yudao-ui-admin-vue3/
├── public/ # 静态资源
├── src/
│ ├── api/ # API接口定义
│ │ └── water/ # 水务业务API
│ │ ├── customer/ # 客户管理API
│ │ ├── meter/ # 抄表管理API
│ │ ├── billing/ # 收费管理API
│ │ └── workflow/ # 工单管理API
│ ├── assets/ # 静态资源
│ ├── components/ # 全局组件
│ │ ├── Dialog/ # 弹窗组件
│ │ ├── Form/ # 表单组件
│ │ ├── Table/ # 表格组件
│ │ └── Upload/ # 上传组件
│ ├── layout/ # 布局组件
│ ├── router/ # 路由配置
│ ├── stores/ # Pinia状态管理
│ ├── styles/ # 全局样式
│ ├── utils/ # 工具函数
│ ├── views/ # 页面组件
│ │ └── water/ # 水务业务页面
│ │ ├── customer/ # 客户管理
│ │ ├── meter/ # 抄表管理
│ │ ├── billing/ # 收费管理
│ │ └── workflow/ # 工单管理
│ └── App.vue
├── types/ # TypeScript类型定义
├── vite.config.ts # Vite配置
├── tsconfig.json # TypeScript配置
└── package.json # 项目依赖
```
**核心配置示例:**
```typescript
// vite.config.ts - Vite构建配置
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@/api': resolve(__dirname, 'src/api'),
'@/components': resolve(__dirname, 'src/components'),
'@/utils': resolve(__dirname, 'src/utils')
}
},
server: {
port: 80,
proxy: {
'/admin-api': {
target: 'http://127.0.0.1:48080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/admin-api/, '/admin-api')
}
}
},
build: {
outDir: 'dist',
sourcemap: false,
rollupOptions: {
output: {
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: '[ext]/[name]-[hash].[ext]'
}
}
}
})
```
#### 4.2 移动端架构 (uni-app)
**技术栈组成:**
```mermaid
graph TB
subgraph "跨平台框架"
M1[uni-app 3.x]
M2[Vue 3 Composition API]
M3[TypeScript支持]
end
subgraph "UI组件库"
N1[uView UI 2.0]
N2[uni-ui组件]
N3[自定义水务组件]
end
subgraph "状态管理"
O1[Vuex 4.x]
O2[uni-app存储]
O3[缓存管理]
end
subgraph "设备能力"
P1[相机API<br/>水表拍照]
P2[NFC读取<br/>水表标签]
P3[GPS定位<br/>抄表轨迹]
P4[扫码API<br/>二维码扫描]
end
subgraph "网络通信"
Q1[uni.request<br/>HTTP请求]
Q2[WebSocket<br/>实时通信]
Q3[文件上传<br/>图片处理]
end
M1 --> N1
M1 --> O1
M1 --> P1
M1 --> Q1
N1 --> N3
P1 --> P2
Q1 --> Q2
```
**移动端项目结构:**
```text
water-mobile-app/
├── pages/ # 页面目录
│ ├── index/ # 首页
│ ├── meter/ # 抄表功能
│ │ ├── task/ # 抄表任务
│ │ ├── read/ # 抄表录入
│ │ └── history/ # 抄表历史
│ ├── workflow/ # 工单管理
│ └── personal/ # 个人中心
├── components/ # 组件目录
│ ├── meter-reader/ # 水表读数组件
│ ├── map-trace/ # 地图轨迹组件
│ └── camera-scan/ # 相机扫描组件
├── static/ # 静态资源
├── store/ # 状态管理
├── utils/ # 工具函数
├── api/ # 接口定义
├── manifest.json # 应用配置
└── pages.json # 页面配置
```
#### 4.3 客户端小程序架构
**微信小程序技术栈:**
- 开发框架:微信小程序原生框架
- UI组件WeUI + 自定义组件
- 状态管理:小程序全局数据管理
- 支付集成微信支付API
- 地图服务腾讯地图API
**支付宝小程序技术栈:**
- 开发框架:支付宝小程序原生框架
- UI组件mini-antui + 自定义组件
- 状态管理:小程序全局数据管理
- 支付集成支付宝支付API
- 地图服务高德地图API
#### 4.4 前端工程化配置
**代码规范:**
```json
// .eslintrc.js - ESLint配置
{
"extends": [
"@vue/typescript/recommended",
"@vue/prettier",
"@vue/prettier/@typescript-eslint"
],
"rules": {
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": "error",
"vue/multi-word-component-names": "off"
}
}
```
**构建优化:**
- Vite热更新开发环境快速构建
- 代码分割:按路由和组件懒加载
- 资源压缩Gzip压缩和图片优化
- CDN加速静态资源CDN分发
- 缓存策略浏览器缓存和Service Worker
- 移动端:
- 核心框架uni-app跨平台
- 组件库uview-ui
- 小程序支持:微信小程序、支付宝小程序等
- 移动端地图高德地图SDK用于抄表轨迹和导航
- 设备接入NFC、扫码、相机等硬件设备接口
### 2.3 技术特性
- 单点登录OAuth2 + JWT实现统一认证
- 数据交换基于RESTful API的系统内部数据交换与共享
- 统一报表平台集成JimuReport支持自定义报表设计与生成
- 大屏设计集成GoView支持可视化大屏设计
- 安全保障:满足安全等保三级要求
- 密码加密BCrypt加密算法
- 防XSS攻击表单数据过滤
- 防SQL注入参数化查询
- 防CSRF攻击Token验证
- 性能规格支持200并发用户50并发移动设备系统响应时间不超过3秒
- 扩展容量支持100万客户的业务量满足企业3-5年的业务发展需求
- 支持功能:
- 支付管理:微信支付、支付宝支付等
- 短信服务:阿里云、腾讯云等多家短信服务商
- AI能力
- 智能抄表:基于图像识别的水表读数
- 异常分析基于AI的用水异常分析
- API网关支持API权限管理、限流熔断、白名单控制
## 3. 应用架构
### 1. 微服务应用架构图
```mermaid
graph TB
subgraph "网关层"
GW[API网关<br/>Spring Cloud Gateway]
AUTH[认证服务<br/>OAuth2 + JWT]
end
subgraph "基础服务层"
subgraph "系统服务"
SYS[系统管理服务<br/>用户/角色/权限]
TENANT[租户管理服务<br/>多租户隔离]
FILE[文件管理服务<br/>附件存储]
MSG[消息服务<br/>短信/邮件/推送]
end
subgraph "工作流服务"
WF[工作流引擎<br/>Flowable]
TASK[任务调度服务<br/>Quartz]
end
end
subgraph "业务服务层"
subgraph "客户域服务"
CUST[客户管理服务<br/>Customer Service]
METER[水表管理服务<br/>Meter Service]
ADDR[地址管理服务<br/>Address Service]
end
subgraph "营收域服务"
READ[抄表服务<br/>Reading Service]
BILL[账单服务<br/>Billing Service]
PAY[收费服务<br/>Payment Service]
ACC[账务服务<br/>Accounting Service]
end
subgraph "运营域服务"
ORDER[工单服务<br/>Workflow Service]
RPT[报表服务<br/>Report Service]
STATS[统计分析服务<br/>Statistics Service]
end
subgraph "接口域服务"
BANK[银行接口服务<br/>Bank Service]
PAY_GW[支付网关服务<br/>Payment Gateway]
IOT[物联网服务<br/>IoT Service]
SMS[短信服务<br/>SMS Service]
end
end
subgraph "数据层"
subgraph "业务数据库"
DB_CUST[(客户库<br/>Customer DB)]
DB_BILL[(营收库<br/>Billing DB)]
DB_RPT[(报表库<br/>Report DB)]
end
subgraph "缓存与存储"
REDIS[(Redis集群<br/>缓存/会话)]
ES[(ElasticSearch<br/>搜索引擎)]
FILE_STORE[文件存储<br/>MinIO/OSS]
end
end
%% 网关层连接
GW --> AUTH
GW --> SYS
GW --> CUST
GW --> READ
GW --> ORDER
%% 服务间调用
CUST --> METER
CUST --> ADDR
READ --> METER
READ --> CUST
BILL --> READ
BILL --> CUST
PAY --> BILL
ACC --> PAY
ORDER --> WF
ORDER --> TASK
RPT --> STATS
%% 外部接口调用
PAY --> BANK
PAY --> PAY_GW
READ --> IOT
ORDER --> SMS
%% 数据层连接
CUST --> DB_CUST
METER --> DB_CUST
BILL --> DB_BILL
PAY --> DB_BILL
RPT --> DB_RPT
SYS --> REDIS
AUTH --> REDIS
CUST --> REDIS
BILL --> ES
FILE --> FILE_STORE
```
### 2. 服务治理架构
```mermaid
graph TB
subgraph "服务发现与注册"
NACOS[Nacos注册中心<br/>服务注册/发现/配置]
end
subgraph "服务网格层"
subgraph "负载均衡"
LB[Ribbon负载均衡<br/>客户端负载均衡]
FEIGN[OpenFeign<br/>服务间调用]
end
subgraph "容错保护"
CB[Sentinel熔断器<br/>流量控制/熔断降级]
RETRY[重试机制<br/>失败重试]
end
subgraph "链路追踪"
TRACE[SkyWalking<br/>分布式链路追踪]
METRIC[Micrometer<br/>指标收集]
end
end
subgraph "配置管理"
CONFIG[Nacos Config<br/>配置中心]
SECRET[配置加密<br/>敏感信息保护]
end
subgraph "监控告警"
MONITOR[Spring Boot Admin<br/>应用监控]
ALERT[告警系统<br/>异常通知]
LOG[ELK日志系统<br/>日志聚合分析]
end
NACOS --> LB
NACOS --> FEIGN
LB --> CB
FEIGN --> TRACE
CB --> RETRY
CONFIG --> SECRET
MONITOR --> ALERT
TRACE --> LOG
```
系统应用架构基于业务域划分,主要包括以下核心应用模块:
### 3.1 统一平台
- 单点登录:统一认证入口,支持多种登录方式
- 系统管理:组织机构、员工管理、角色权限管理、菜单配置等
- 流程节点提醒:工作流节点到期和状态变更提醒
### 3.2 营收系统
- 系统管理:水价管理、用户档案管理、更名过户管理等
- 抄表开账:册本管理、抄表录入、复核开账等
- 收费管理:柜台收费、特殊开账、柜台结账、批量缴费等
- 账务处理:预存调整、未销调整、已销调整、分账调整等
- 发票管理:发票查询、发票开具、电子发票等
- 代收业务:实时收费、银行代扣、银行托收等
- 环卫系统:计费核定、计费退补、计费减免等
- 业务工单:业务清单、上报清单、稽查工单、移表工单等
### 3.3 客户服务
- 微信、支付宝服务窗:账户绑定、用水查询、在线缴费等
- 历史账单:账单查询、用水分析、账单推送等
- 电子发票:发票申请、发票查询、发票下载等
- 营业网点:网点查询、网点导航、业务指南等
- 账户流水:流水查询、明细下载、交易统计等
- 微网厅:用户注册、信息查询、业务办理等
### 3.4 表务系统
- 表务工单:换表工单、移表工单、拆表工单、复装工单等
- 表务仓库:新表入库、水表检定、水表领用、水表出库等
- 水表参数与基础信息:水表厂家管理、水表型号管理等
- 物联网对接与数据同步:厂家设备信息管理、远程抄表数据同步等
### 3.5 报装管理
- 报装流程:报装申请、方案设计、合同签订、施工管理等
- 一户一表管理:改造计划、改造实施、用户转换等
### 3.6 统计分析
- 报表查询:标准报表、自定义报表、报表导出打印等
- 欠费查询:欠费情况统计、欠费用户明细、欠费分析等
- 缴费记录:缴费情况统计、缴费明细查询、缴费趋势分析等
- 用水分析:用水量统计、用水趋势分析、异常用水分析等
### 3.7 工程管理
- 工程申请:工程立项、材料提交、前期勘察等
- 工程施工:施工计划、施工派工、施工记录等
- 工程验收:验收申请、验收检查、验收记录等
- 工程查询:工程进度查询、工程资料查询、工程统计等
### 3.8 抄表APP
- 首页功能:首页展示、个人信息、快捷查询等
- 抄表功能抄表任务、NFC抄表、扫码抄表、AI录入等
- 工单管理:问题上报、问题回填、代办工单、稽查工单等
### 3.9 接口服务
- API市场API展示、API使用说明、API测试等
- API管理API申请、API调度看板、接口服务配置管理等
- 接口权限管理:授权管理、白名单管理、安全策略等
- 系统对外接口:查询接口、业务处理接口、状态同步接口等
### 3.10 系统配置
- 水表参数:水表厂家、水表型号、水表量程等
- 地址参数:行政区划、地址编码、地址库等
- 价格体系:用水性质、水价标准、阶梯水价等
- 基本配置:系统参数、业务规则、打印模板等
- 催缴管理:催缴计划、催缴任务、催缴执行等
- 用户权限:菜单权限、功能权限、数据权限等
- 定时任务:任务配置、任务监控、任务日志等
## 4. 数据架构
系统数据架构基于客户关系数据库为核心和基础,实现客户全生命周期管理。
### 4.1 数据分层
- 数据采集层:负责从各业务系统和物联网设备采集原始数据
- 数据存储层:统一数据存储,实现分布式数据管理
- 数据服务层:提供数据服务接口
- 数据展现层:提供数据分析和可视化功能
### 4.2 OpenGauss数据库架构
#### 4.2.1 主从高可用架构
```mermaid
graph TB
subgraph "OpenGauss高可用集群"
MASTER[("OpenGauss主库<br/>Primary Node<br/>读写操作")]
STANDBY[("OpenGauss备库<br/>Standby Node<br/>只读操作")]
CASCADE[("OpenGauss级联备库<br/>Cascade Standby<br/>负载分担")]
end
subgraph "应用层"
APP1[应用服务器1]
APP2[应用服务器2]
APP3[应用服务器3]
end
subgraph "连接池"
POOL[连接池<br/>HikariCP<br/>Druid]
end
subgraph "监控管理"
MON[OpenGauss Monitor<br/>性能监控]
BACKUP[定时备份<br/>gs_backup]
end
APP1 --> POOL
APP2 --> POOL
APP3 --> POOL
POOL --> MASTER
POOL --> STANDBY
POOL --> CASCADE
MASTER -.->|流复制| STANDBY
STANDBY -.->|级联复制| CASCADE
MON --> MASTER
MON --> STANDBY
BACKUP --> MASTER
```
#### 4.2.2 分片存储架构
```mermaid
graph TB
subgraph "OpenGauss分布式架构"
subgraph "协调节点"
CN1[协调节点1<br/>Coordinator Node]
CN2[协调节点2<br/>Coordinator Node]
end
subgraph "数据节点组1"
DN1_1[数据节点1-主<br/>Datanode Primary]
DN1_2[数据节点1-备<br/>Datanode Standby]
end
subgraph "数据节点组2"
DN2_1[数据节点2-主<br/>Datanode Primary]
DN2_2[数据节点2-备<br/>Datanode Standby]
end
subgraph "GTM节点"
GTM[全局事务管理器<br/>GTM Master]
GTM_S[GTM备节点<br/>GTM Standby]
end
end
CN1 --> DN1_1
CN1 --> DN2_1
CN2 --> DN1_1
CN2 --> DN2_1
DN1_1 -.->|主备同步| DN1_2
DN2_1 -.->|主备同步| DN2_2
GTM -.->|备份| GTM_S
CN1 --> GTM
CN2 --> GTM
```
#### 4.2.3 数据安全架构
```mermaid
graph TB
subgraph "安全防护层"
TDE[透明数据加密<br/>TDE]
RLS[行级安全<br/>Row Level Security]
MASK[动态数据脱敏<br/>Dynamic Data Masking]
AUDIT[三权分立审计<br/>Separated Audit]
end
subgraph "访问控制层"
RBAC[基于角色的访问控制<br/>RBAC]
LDAP[LDAP集成认证<br/>External Auth]
SSL[SSL/TLS加密传输<br/>Encrypted Transport]
end
subgraph "数据存储层"
ENCRYPT[存储层加密<br/>Storage Encryption]
COMPRESS[数据压缩<br/>Data Compression]
BACKUP_ENC[备份加密<br/>Backup Encryption]
end
TDE --> ENCRYPT
RLS --> RBAC
MASK --> ENCRYPT
AUDIT --> BACKUP_ENC
RBAC --> SSL
LDAP --> SSL
```
### 4.3 数据模型设计
- **客户信息模型**:包含客户基础信息、表卡信息、账户信息、联系人信息等
- **业务数据模型**:抄表数据、收费数据、账务数据、发票数据等
- **工单数据模型**:表务工单、报装工单、业务工单等
- **配置数据模型**:系统参数、水表参数、价格体系等
- **报表数据模型**:统计数据、分析数据、预测数据等
- **物联网数据模型**:设备信息、状态信息、实时数据等
### 4.4 数据集成与共享
- **统一数据标准**定义统一的数据标准和数据字典符合OpenGauss规范
- **数据集成机制**采用OpenGauss XA事务实现系统间的数据一致性
- **数据共享机制**基于OpenGauss外部数据包装器(FDW)实现跨库数据访问
- **数据同步策略**支持实时流复制、定时数据同步、批量ETL处理等
### 4.5 OpenGauss特性应用
#### 4.5.1 性能优化特性
- **向量化执行引擎**批量数据处理提升OLAP查询性能30-50%
- **列存储引擎**统计报表类查询压缩比高达10:1
- **分区表技术**:按月份分区存储抄表数据,支持分区裁剪
- **并行查询**:复杂统计查询自动并行执行
- **智能优化器**:自适应查询计划,持续性能优化
#### 4.5.2 企业级特性
- **在线扩容**:支持不停机新增数据节点
- **故障自愈**主备节点故障自动切换RTO < 10秒
- **读写分离**自动路由读请求到备节点减轻主库压力
- **负载均衡**连接池级别的智能负载均衡
- **全量/增量备份**支持热备份最小备份粒度到事务级
## 5. 安全架构
系统安全架构基于OpenGauss数据库的企业级安全特性满足等保三级要求和国产化安全标准
### 5.1 网络安全
- **边界防护**防火墙入侵检测/防御系统
- **访问控制**基于角色的访问控制(RBAC)
- **通信安全**SSL/TLS加密传输支持国密算法
- **安全监控**实时监控网络安全状态和异常访问
### 5.2 OpenGauss数据安全架构
#### 5.2.1 数据加密安全
```mermaid
graph TB
subgraph "加密层级"
L1[传输层加密<br/>SSL/TLS/国密SM]
L2[存储层加密<br/>TDE透明数据加密]
L3[字段级加密<br/>敏感字段加密]
L4[备份加密<br/>备份文件加密]
end
subgraph "密钥管理"
KMS[密钥管理系统<br/>Key Management]
HSM[硬件安全模块<br/>Hardware Security]
ROT[密钥轮换<br/>Key Rotation]
end
subgraph "国密算法"
SM2[SM2椭圆曲线<br/>非对称加密]
SM3[SM3哈希算法<br/>消息摘要]
SM4[SM4分组密码<br/>对称加密]
end
L1 --> KMS
L2 --> HSM
L3 --> ROT
L4 --> KMS
KMS --> SM2
HSM --> SM3
ROT --> SM4
```
#### 5.2.2 访问控制安全
```mermaid
graph TB
subgraph "身份认证"
AUTH1[用户名密码认证]
AUTH2[LDAP集成认证]
AUTH3[Kerberos认证]
AUTH4[证书认证]
end
subgraph "权限控制"
RBAC[基于角色的权限控制<br/>Role-Based Access Control]
RLS[行级安全策略<br/>Row Level Security]
CLS[列级安全控制<br/>Column Level Security]
TENANT[多租户数据隔离<br/>Multi-Tenant Isolation]
end
subgraph "审计监控"
AUDIT[操作审计日志<br/>Audit Logging]
MONITOR[实时安全监控<br/>Security Monitoring]
ALERT[安全告警<br/>Security Alert]
REPORT[合规报告<br/>Compliance Report]
end
AUTH1 --> RBAC
AUTH2 --> RLS
AUTH3 --> CLS
AUTH4 --> TENANT
RBAC --> AUDIT
RLS --> MONITOR
CLS --> ALERT
TENANT --> REPORT
```
### 5.3 数据安全特性
- **透明数据加密(TDE)**自动加密存储数据支持SM4国密算法
- **行级安全(RLS)**基于用户角色的行级数据访问控制
- **列级权限**敏感字段的精细化访问控制
- **动态脱敏**查询时自动脱敏显示敏感信息
- **数据备份安全**备份文件自动加密支持增量备份
- **审计日志**完整记录所有数据库操作支持合规审计
### 5.4 多租户安全隔离
- **逻辑隔离**基于tenant_id的数据隔离
- **连接隔离**租户间连接池隔离
- **权限隔离**租户级别的权限管理
- **资源隔离**CPU内存IO资源限制
### 5.5 应用安全
- **身份认证**多因素认证支持短信验证码邮箱验证等
- **授权管理**细粒度的权限控制支持菜单按钮数据权限
- **安全审计**用户操作审计关键业务操作全程记录
- **密码策略**密码复杂度定期更换失败锁定等安全策略
- **会话管理**会话超时并发限制单点登录等
### 5.6 接口安全
- **接口认证**基于JWT Token的接口认证
- **接口授权**基于角色的接口授权和权限验证
- **接口加密**敏感数据的加密传输支持国密算法
- **接口防护**防重放防篡改防SQL注入等安全措施
- **接口限流**基于IP用户应用的多维度限流策略
## 6. 部署架构
系统采用集中部署的模式基于集团私有云环境进行部署
### 6.1 物理部署
- **生产环境**高可用集群部署
- 应用服务器2台或以上服务器负载均衡
- **OpenGauss数据库集群**主从+级联备架构支持自动故障切换
- 缓存服务器Redis集群
- 文件服务器冗余存储
- **灾备环境**异地灾备定期数据同步支持OpenGauss流复制
- **测试环境**用于系统测试和验证单节点OpenGauss部署
- **开发环境**用于系统开发和集成测试单节点OpenGauss部署
### 6.2 逻辑部署
- **应用服务器集群**负责业务逻辑处理支持水平扩展
- **OpenGauss数据库集群**负责数据存储和管理提供高可用保障
- **文件服务器**负责文档和附件存储支持分布式存储
- **缓存服务器**Redis集群提高系统性能
- **负载均衡服务器**实现请求分发和负载均衡
- **移动应用服务**提供移动端API服务
- **API网关**统一的接口管理和控制
### 6.3 容器部署
- 基于Docker容器技术实现微服务部署
- 使用Kubernetes进行容器编排和管理
- 支持容器的自动扩缩容和故障转移
- 实现服务的灰度发布和版本控制
## 7. 接口架构
系统提供标准化的接口实现与外部系统的集成和数据交换
### 7.1 外部接口
- 银行接口实现与银行系统的对接支持代扣托收等功能
- 支付宝/微信接口支持在线支付功能
- 短信接口支持短信通知和验证码功能
- 集抄系统接口实现与智能水表集中抄表系统的对接
- 政务系统接口实现与地方政务平台和政务APP的对接
- 消火栓系统接口实现与消火栓系统的对接
- 环卫系统接口实现与环卫系统的对接
- OA系统接口实现与OA系统的工作流对接
### 7.2 内部接口
- ESB服务接口系统内部模块间的数据交换
- 报表接口提供报表数据查询和生成功能
- 查询接口提供数据查询功能
- 业务处理接口提供业务处理功能
- 消息通知接口提供消息推送和通知功能
- 工作流接口提供工作流处理和状态查询功能
### 7.3 接口标准
- 接口协议RESTful APIWebService消息队列等
- 数据格式JSONXML等
- 接口安全身份认证授权加密传输等
- 接口文档统一的接口文档和示例代码
- 接口测试提供接口测试工具和环境
### 7.4 接口服务管理
- API网关统一的接口入口和管理
- 服务注册与发现服务的自动注册和发现
- 服务路由根据请求参数进行服务路由
- 服务降级在服务不可用时提供降级策略
- 服务监控实时监控服务的可用性和性能
---
# 福建水务营收系统模块功能设计文档
## 文档信息
| 项目信息 | 详情 |
|---------|------|
| **项目名称** | 福建水务营收系统 |
| **文档类型** | 概要设计文档 |
| **技术框架** | RuoYi-Vue-Pro + yudao-ui-admin-vue3 |
| **文档版本** | v1.0 |
| **编写日期** | 2024-12-19 |
| **文档状态** | 已完成 |
## 目录
- [福建水务营收系统模块功能设计文档](#福建水务营收系统模块功能设计文档)
- [文档信息](#文档信息)
- [目录](#目录)
- [一、系统整体架构](#一系统整体架构)
- [1.1 系统架构图](#11-系统架构图)
- [1.2 技术架构图](#12-技术架构图)
- [1.3 业务架构图](#13-业务架构图)
- [二、统一平台](#二统一平台)
- [2.1 单点登录](#21-单点登录)
- [2.2 系统管理](#22-系统管理)
- [三、营收系统](#三营收系统)
- [3.1 系统管理](#31-系统管理)
- [3.2 抄表开账](#32-抄表开账)
- [3.2.1 业务流程图](#321-业务流程图)
- [3.2.2 主要功能](#322-主要功能)
- [3.2.3 核心接口定义](#323-核心接口定义)
- [3.2.4 前端界面设计](#324-前端界面设计)
- [3.3 收费管理](#33-收费管理)
- [3.3.1 业务流程图](#331-业务流程图)
- [3.3.2 主要功能](#332-主要功能)
- [3.3.3 核心接口定义](#333-核心接口定义)
- [3.4 账务处理](#34-账务处理)
- [3.4.1 业务流程图](#341-业务流程图)
- [3.4.2 主要功能](#342-主要功能)
- [3.4.3 核心接口定义](#343-核心接口定义)
- [3.5 发票管理](#35-发票管理)
- [3.5.1 业务流程图](#351-业务流程图)
- [3.5.2 核心接口定义](#352-核心接口定义)
- [3.6 代收业务](#36-代收业务)
- [3.7 环卫系统](#37-环卫系统)
- [3.8 业务工单](#38-业务工单)
- [四、表务系统](#四表务系统)
- [4.1 表务工单](#41-表务工单)
- [4.2 表务仓库](#42-表务仓库)
- [4.3 水表参数与基础信息](#43-水表参数与基础信息)
- [4.4 物联网对接与数据同步](#44-物联网对接与数据同步)
- [五、报装系统](#五报装系统)
- [5.1 报装流程](#51-报装流程)
- [5.2 一户一表管理](#52-一户一表管理)
- [六、客户服务](#六客户服务)
- [6.1 微信、支付宝服务窗](#61-微信支付宝服务窗)
- [6.2 历史账单](#62-历史账单)
- [6.3 电子发票](#63-电子发票)
- [6.4 营业网点](#64-营业网点)
- [6.5 账户流水](#65-账户流水)
- [6.6 微网厅](#66-微网厅)
- [七、系统配置](#七系统配置)
- [7.1 水表参数](#71-水表参数)
- [7.2 地址参数](#72-地址参数)
- [7.3 价格体系](#73-价格体系)
- [7.4 基本配置](#74-基本配置)
- [7.5 催缴管理](#75-催缴管理)
- [7.6 用户权限](#76-用户权限)
- [7.7 定时任务](#77-定时任务)
- [八、系统接口](#八系统接口)
- [8.1 银行接口](#81-银行接口)
- [8.2 支付宝/微信接口](#82-支付宝微信接口)
- [8.3 短信接口](#83-短信接口)
- [8.4 集抄系统接口](#84-集抄系统接口)
- [8.5 政务系统接口](#85-政务系统接口)
- [8.6 消火栓系统接口](#86-消火栓系统接口)
- [8.7 其他系统对接](#87-其他系统对接)
- [九、统计分析](#九统计分析)
- [9.1 报表查询](#91-报表查询)
- [9.2 欠费查询](#92-欠费查询)
- [9.3 缴费记录](#93-缴费记录)
- [9.4 用水分析](#94-用水分析)
- [十、工程管理](#十工程管理)
- [10.1 工程申请](#101-工程申请)
- [10.2 工程施工](#102-工程施工)
- [10.3 工程验收](#103-工程验收)
- [10.4 工程查询](#104-工程查询)
- [十一、抄表APP](#十一抄表app)
- [11.1 首页功能](#111-首页功能)
- [11.2 抄表功能](#112-抄表功能)
- [11.3 工单管理](#113-工单管理)
- [十二、接口服务](#十二接口服务)
- [12.1 API市场](#121-api市场)
- [12.2 API管理](#122-api管理)
- [12.3 接口权限管理](#123-接口权限管理)
- [12.4 系统对外接口](#124-系统对外接口)
- [系统集成架构](#系统集成架构)
- [前后端集成架构](#前后端集成架构)
- [技术栈整合方案](#技术栈整合方案)
## 一、系统整体架构
福建水务营收系统采用现代化的分布式微服务架构基于RuoYi-Vue-Pro后端框架和yudao-ui-admin-vue3前端框架构建为水务企业提供完整的营收管理解决方案
### 1.1 系统架构图
```mermaid
graph TB
subgraph "用户层"
A1[管理员用户]
A2[抄表员]
A3[收费员]
A4[客户用户]
end
subgraph "接入层"
B1[PC端管理后台<br/>yudao-ui-admin-vue3]
B2[移动端抄表APP<br/>uni-app]
B3[微信小程序]
B4[支付宝小程序]
B5[Web客户端]
end
subgraph "网关层"
C1[API网关<br/>Spring Cloud Gateway]
C2[负载均衡<br/>Nginx]
end
subgraph "服务层"
D1[用户认证服务<br/>Spring Security + JWT]
D2[营收管理服务<br/>RuoYi-Vue-Pro]
D3[表务管理服务]
D4[报装管理服务]
D5[客户服务]
D6[系统管理服务]
end
subgraph "中间件层"
E1[(Redis缓存<br/>6.0+)]
E2[RabbitMQ消息队列]
E3[Elasticsearch搜索]
E4[MinIO文件存储]
end
subgraph "数据层"
F1[(主数据库<br/>OpenGauss 5.0+)]
F2[(从数据库<br/>OpenGauss 5.0+)]
F3[(历史数据库<br/>OpenGauss 5.0+)]
end
subgraph "外部系统"
G1[银行系统]
G2[支付宝/微信]
G3[短信平台]
G4[集抄系统]
G5[政务平台]
end
A1 --> B1
A2 --> B2
A3 --> B1
A4 --> B3
A4 --> B4
A4 --> B5
B1 --> C2
B2 --> C2
B3 --> C2
B4 --> C2
B5 --> C2
C2 --> C1
C1 --> D1
C1 --> D2
C1 --> D3
C1 --> D4
C1 --> D5
C1 --> D6
D1 --> E1
D2 --> E1
D2 --> E2
D3 --> E1
D4 --> E3
D5 --> E4
D6 --> E1
D2 --> F1
D3 --> F1
D4 --> F2
D5 --> F2
D6 --> F3
D2 --> G1
D2 --> G2
D5 --> G3
D3 --> G4
D4 --> G5
```
### 1.2 技术架构图
```mermaid
graph TB
subgraph "前端技术栈"
FE1[Vue 3.x]
FE2[TypeScript 4.x]
FE3[Element Plus]
FE4[Vite 4.x]
FE5[Pinia状态管理]
end
subgraph "后端技术栈"
BE1[Spring Boot 3.x]
BE2[Spring Security 6.x]
BE3[MyBatis Plus 3.x]
BE4[Spring Cloud Gateway]
BE5[Hibernate Validator]
end
subgraph "数据库技术"
DB1[OpenGauss 5.0+]
DB2[Redis 6.0+]
DB3[HikariCP连接池]
DB4[MyBatis-Plus代码生成]
end
subgraph "中间件技术"
MW1[RabbitMQ 3.x]
MW2[Elasticsearch 8.x]
MW3[MinIO对象存储]
MW4[XXL-JOB定时任务]
end
subgraph "运维技术"
OPS1[Docker容器化]
OPS2[Jenkins CI/CD]
OPS3[Prometheus监控]
OPS4[ELK日志分析]
end
subgraph "安全技术"
SEC1[JWT Token认证]
SEC2[OAuth2.0授权]
SEC3[AES数据加密]
SEC4[RSA签名验证]
end
FE1 --> FE2
FE2 --> FE3
FE3 --> FE4
FE4 --> FE5
BE1 --> BE2
BE2 --> BE3
BE3 --> BE4
BE4 --> BE5
DB1 --> DB2
DB2 --> DB3
DB3 --> DB4
MW1 --> MW2
MW2 --> MW3
MW3 --> MW4
OPS1 --> OPS2
OPS2 --> OPS3
OPS3 --> OPS4
SEC1 --> SEC2
SEC2 --> SEC3
SEC3 --> SEC4
```
### 1.3 业务架构图
```mermaid
graph TB
subgraph "统一平台层"
UP1[单点登录]
UP2[系统管理]
UP3[用户权限]
UP4[组织架构]
end
subgraph "核心业务层"
CB1[客户管理]
CB2[抄表管理]
CB3[收费管理]
CB4[账务管理]
CB5[表务管理]
CB6[报装管理]
end
subgraph "增值服务层"
VS1[客户服务]
VS2[移动应用]
VS3[微信服务]
VS4[电子发票]
VS5[在线支付]
end
subgraph "数据服务层"
DS1[统计分析]
DS2[报表查询]
DS3[数据导出]
DS4[决策支持]
end
subgraph "集成服务层"
IS1[银行接口]
IS2[支付接口]
IS3[短信接口]
IS4[集抄接口]
IS5[政务接口]
end
UP1 --> CB1
UP2 --> CB2
UP3 --> CB3
UP4 --> CB4
CB1 --> VS1
CB2 --> VS2
CB3 --> VS3
CB4 --> VS4
CB5 --> VS5
CB6 --> VS1
VS1 --> DS1
VS2 --> DS2
VS3 --> DS3
VS4 --> DS4
VS5 --> DS1
DS1 --> IS1
DS2 --> IS2
DS3 --> IS3
DS4 --> IS4
DS1 --> IS5
```
## 二、统一平台
统一平台是客户服务平台的综合展示平台基于RuoYi-Vue-Pro和yudao-ui-admin-vue3框架构建包含日常工作功能和客户全部的信息是系统的基础功能模块
### 2.1 单点登录
单点登录模块基于Spring Security和JWT实现用户一次登录即可访问系统中所有应用的功能主要特点包括
- 支持通过用户名密码进行身份认证
- 支持OAuth2.0授权码+PKCE模式的第三方登录
- 支持手机号+短信验证码登录方式
- 支持多因素认证MFA增强安全性
- 根据登录人员所在公司的不同显示不同的系统名称和界面风格
- 提供流程节点到期提醒功能
- Token自动刷新机制提升用户体验
### 2.2 系统管理
系统管理模块基于RuoYi-Vue-Pro框架的现成功能提供对系统基础参数的配置管理功能主要包括
- 组织机构管理
- 支持多级组织结构的管理
- 支持组织机构导入导出
- 组织关系树形展示
- 组织数据权限控制
- 员工管理
- 系统操作人员的基本信息管理
- 用户分配角色与权限
- 用户状态管理启用/禁用
- 用户密码安全策略
- 用户操作日志记录
- 角色权限管理
- 基于RBAC模型的权限控制
- 支持数据权限精细化控制
- 支持多租户的权限隔离
- 基于菜单按钮级别的权限管理
- 系统菜单配置
- 支持自定义系统菜单和功能模块
- 菜单多级分类管理
- 动态路由生成
- 菜单权限配置
- 数据字典管理
- 维护系统使用的各类基础代码数据
- 支持字典项多级管理
- 支持字典缓存提高访问性能
- 系统监控
- 在线用户监控与管理
- 服务器性能监控
- 定时任务执行状态监控
- 系统缓存监控与管理
- 系统日志管理
- 记录用户登录日志
- 记录操作日志支持操作回溯
- 记录系统异常日志便于问题排查
- 短信管理
- 支持阿里云腾讯云等多家短信渠道
- 短信模板配置管理
- 短信发送日志记录
- 租户管理
- 支持SaaS多租户
- 租户套餐配置
- 租户数据隔离
- 租户资源管理
- 配置管理
- 系统参数配置
- 通知公告管理
- 定时任务配置
## 三、营收系统
营收系统是水务业务系统的核心组成部分负责抄表收费账务处理等关键业务功能
### 3.1 系统管理
营收系统的基础管理功能包括
- 水价管理不同用户类型的水价标准管理支持阶梯水价
- 用户档案管理维护用户基本信息用水信息账户信息等
- 客户分组管理
- 集收管理
- 客户基础信息管理
- 定额管理
- 客户优惠方案设置
- 更名过户管理处理用户变更过户等业务
- 注销报停管理处理用户注销暂停用水等业务
### 3.2 抄表开账
抄表开账模块负责水表读数的采集和账单生成是营收系统的核心业务模块
#### 3.2.1 业务流程图
```mermaid
flowchart TD
Start([开始抄表周期]) --> BookPlan[制定抄表计划]
BookPlan --> CreateBook[生成抄表册本]
CreateBook --> AssignReader[分配抄表员]
AssignReader --> ReadingStart[开始抄表]
ReadingStart --> ReadingType{抄表方式}
ReadingType -->|人工抄表| ManualReading[现场抄表录入]
ReadingType -->|远程抄表| RemoteReading[远程采集数据]
ReadingType -->|客户自报| SelfReporting[客户自主上报]
ManualReading --> DataValidation[数据校验]
RemoteReading --> DataValidation
SelfReporting --> DataValidation
DataValidation --> ValidationResult{校验结果}
ValidationResult -->|异常| ExceptionHandle[异常处理]
ValidationResult -->|正常| DataReview[数据复核]
ExceptionHandle --> ReviewException[人工审核异常]
ReviewException --> DataReview
DataReview --> ReviewResult{复核结果}
ReviewResult -->|退回| ReadingStart
ReviewResult -->|通过| BillGeneration[生成账单]
BillGeneration --> CalcWaterFee[计算水费]
CalcWaterFee --> CalcSewageFee[计算污水费]
CalcSewageFee --> CalcOtherFee[计算其他费用]
CalcOtherFee --> BillReview[账单审核]
BillReview --> BillResult{审核结果}
BillResult -->|退回| BillGeneration
BillResult -->|通过| BillConfirm[账单确认]
BillConfirm --> SendNotification[发送缴费通知]
SendNotification --> End([完成开账])
```
#### 3.2.2 主要功能
**册本管理**册本基本信息的维护和管理
- 册本创建与配置
- 抄表路线规划
- 抄表员分配
- 抄表周期设置
**抄表录入**支持多种抄表方式
- 手工抄表现场抄表批量录入
- 智能抄表远程数据采集自动同步
- 自报抄表客户自主上报在线提交
**抄表数据审核**确保数据质量
- 数据校验读数合理性检查用量异常检测
- 异常处理异常数据标记人工处理
- 开账处理数据确认账单生成
**追加抄表**支持非周期性特殊抄表
- 补抄管理漏抄数据补录
- 特殊抄表临时抄表需求
- 调整抄表读数错误修正
#### 3.2.3 核心接口定义
**抄表管理主要接口**
```java
@RestController
@RequestMapping("/admin-api/water/reading")
@Tag(name = "管理后台 - 抄表管理")
public class MeterReadingController {
@PostMapping("/create")
@Operation(summary = "创建抄表记录")
public CommonResult<Long> createReading(@Valid @RequestBody MeterReadingSaveReqVO createReqVO);
@PostMapping("/batch-create")
@Operation(summary = "批量创建抄表记录")
public CommonResult<MeterReadingBatchRespVO> batchCreateReading(@Valid @RequestBody MeterReadingBatchReqVO batchReqVO);
@PostMapping("/review")
@Operation(summary = "抄表数据复核")
public CommonResult<Boolean> reviewReading(@Valid @RequestBody MeterReadingReviewReqVO reviewReqVO);
@PostMapping("/generate-bill")
@Operation(summary = "生成账单")
public CommonResult<BillGenerateRespVO> generateBill(@Valid @RequestBody ReadingBillReqVO reqVO);
}
```
**接口设计要点**
- 遵循RESTful设计规范统一的请求响应格式
- 支持批量操作提高处理效率
- 完整的数据校验和异常处理机制
- 集成RuoYi-Vue-Pro的权限控制和日志记录
#### 3.2.4 前端界面设计
**抄表管理页面结构**
```vue
<template>
<ContentWrap>
<!-- 查询条件 -->
<el-form class="search-form" inline>
<el-form-item label="抄表日期">
<el-date-picker v-model="queryParams.readingDate" type="daterange" />
</el-form-item>
<el-form-item label="抄表状态">
<el-select v-model="queryParams.status">
<el-option label="待复核" value="pending" />
<el-option label="已通过" value="approved" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作按钮 -->
<el-row class="mb-10px">
<el-button type="primary" @click="handleAdd">新增抄表</el-button>
<el-button type="success" @click="handleBatchAdd">批量抄表</el-button>
<el-button type="warning" @click="handleExport">导出数据</el-button>
</el-row>
<!-- 数据表格 -->
<el-table v-loading="loading" :data="readingList">
<el-table-column prop="readingCode" label="抄表编号" width="180" />
<el-table-column prop="customerName" label="客户名称" />
<el-table-column prop="meterCode" label="水表编号" />
<el-table-column prop="readingValue" label="本次读数" />
<el-table-column prop="waterUsage" label="用水量" />
<el-table-column prop="readingDate" label="抄表日期" />
<el-table-column prop="status" label="状态">
<template #default="{ row }">
<dict-tag :type="DICT_TYPE.READING_STATUS" :value="row.status" />
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<template #default="{ row }">
<el-button link @click="handleUpdate(row)">编辑</el-button>
<el-button link @click="handleReview(row)">复核</el-button>
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</ContentWrap>
</template>
```
**前端页面功能特性**
- 响应式设计基于Element Plus的现代化UI组件
- 数据表格支持分页排序筛选等功能
- 表单验证前端数据校验和错误提示
- 批量操作支持批量抄表录入和批量审核
- 实时更新页面数据实时刷新和状态同步
### 3.3 收费管理
收费管理模块负责水费的收取和管理是营收系统的重要业务模块
#### 3.3.1 业务流程图
```mermaid
flowchart TD
Start([客户缴费]) --> QueryCustomer[查询客户信息]
QueryCustomer --> CustomerExists{客户是否存在}
CustomerExists -->|否| ErrorReturn[返回错误信息]
CustomerExists -->|是| QueryBills[查询欠费账单]
QueryBills --> BillExists{是否有欠费}
BillExists -->|否| NoDebt[无欠费提示]
BillExists -->|是| ShowBills[显示账单列表]
ShowBills --> SelectBills[选择缴费账单]
SelectBills --> CalcAmount[计算缴费金额]
CalcAmount --> SelectPayMethod[选择支付方式]
SelectPayMethod --> PaymentType{支付方式}
PaymentType -->|现金| CashPayment[现金收费]
PaymentType -->|银行卡| BankCardPay[银行卡支付]
PaymentType -->|在线支付| OnlinePayment[在线支付]
PaymentType -->|预存款| PrepaidPayment[预存款支付]
CashPayment --> ValidatePayment[验证收费金额]
BankCardPay --> ValidatePayment
OnlinePayment --> ThirdPartyPay[第三方支付]
PrepaidPayment --> CheckBalance[检查预存余额]
ThirdPartyPay --> PaymentCallback[支付回调]
PaymentCallback --> ValidatePayment
CheckBalance --> BalanceOK{余额是否充足}
BalanceOK -->|否| InsufficientBalance[余额不足]
BalanceOK -->|是| ValidatePayment
ValidatePayment --> PaymentSuccess{支付成功}
PaymentSuccess -->|否| PaymentFailed[支付失败处理]
PaymentSuccess -->|是| UpdateAccount[更新账户状态]
UpdateAccount --> UpdateBills[更新账单状态]
UpdateBills --> GenerateReceipt[生成收费凭证]
GenerateReceipt --> PrintReceipt[打印收据]
PrintReceipt --> SendNotification[发送缴费通知]
SendNotification --> Complete([完成缴费])
PaymentFailed --> End([结束])
InsufficientBalance --> End
ErrorReturn --> End
NoDebt --> End
```
#### 3.3.2 主要功能
**柜台收费**现场收费服务
- 用户查询客户信息查询账单查询
- 收费处理多种支付方式找零计算
- 收费打印收据打印发票开具
- 预存预付余额充值预付费管理
**柜台结账**营业网点日常结账
- 日结处理当日收费汇总统计分析
- 交款管理现金上缴账务核对
- 结账查询历史结账记录查询
**预付款管理**预付费业务处理
- 预付款充值余额充值充值记录
- 使用管理自动扣款余额提醒
- 退款处理预付款退款退款审核
**缴费记录查询**缴费历史管理
- 多条件查询按时间金额渠道查询
- 统计分析缴费趋势渠道分析
- 导出功能缴费记录导出
#### 3.3.3 核心接口定义
**缴费管理主要接口**
```java
@RestController
@RequestMapping("/admin-api/water/payment")
@Tag(name = "管理后台 - 缴费管理")
public class PaymentController {
@PostMapping("/create")
@Operation(summary = "创建缴费记录")
public CommonResult<PaymentRespVO> createPayment(@Valid @RequestBody PaymentCreateReqVO createReqVO);
@PostMapping("/cash-payment")
@Operation(summary = "现金缴费")
public CommonResult<PaymentRespVO> cashPayment(@Valid @RequestBody CashPaymentReqVO cashReqVO);
@PostMapping("/online-payment")
@Operation(summary = "在线支付")
public CommonResult<OnlinePaymentRespVO> onlinePayment(@Valid @RequestBody OnlinePaymentReqVO onlineReqVO);
@PostMapping("/prepaid-payment")
@Operation(summary = "预存款缴费")
public CommonResult<PaymentRespVO> prepaidPayment(@Valid @RequestBody PrepaidPaymentReqVO prepaidReqVO);
}
```
**接口设计特点**
- 支持多种缴费方式现金银行卡在线支付预存款
- 事务控制确保缴费操作的原子性和一致性
- 异步处理第三方支付采用异步回调机制
- 安全验证完整的权限控制和数据校验
```
#### 3.3.4 前端界面设计
**缴费管理页面结构**
```vue
<template>
<ContentWrap>
<!-- 客户查询 -->
<el-form class="search-form" inline>
<el-form-item label="客户编号">
<el-input v-model="queryParams.customerCode" placeholder="请输入客户编号" />
</el-form-item>
<el-form-item label="客户姓名">
<el-input v-model="queryParams.customerName" placeholder="请输入客户姓名" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 账单信息 -->
<el-table v-loading="loading" :data="billList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="billCode" label="账单编号" />
<el-table-column prop="billDate" label="账期" />
<el-table-column prop="waterUsage" label="用水量" />
<el-table-column prop="totalAmount" label="应缴金额" />
<el-table-column prop="balanceAmount" label="欠费金额" />
</el-table>
<!-- 缴费操作 -->
<el-row class="payment-actions">
<el-col :span="12">
<el-statistic title="选中金额" :value="selectedAmount" prefix="¥" />
</el-col>
<el-col :span="12" class="text-right">
<el-button type="success" @click="handleCashPayment">现金缴费</el-button>
<el-button type="primary" @click="handleOnlinePayment">在线支付</el-button>
<el-button type="warning" @click="handlePrepaidPayment">预存扣费</el-button>
</el-col>
</el-row>
</ContentWrap>
</template>
```
### 3.4 账务处理
账务处理模块负责处理各类特殊账务情况确保账务数据的准确性和完整性
#### 3.4.1 业务流程图
```mermaid
flowchart TD
Start([账务处理请求]) --> CheckAuth[权限验证]
CheckAuth --> AuthOK{权限验证}
AuthOK -->|失败| AuthError[权限错误]
AuthOK -->|成功| ProcessType{处理类型}
ProcessType -->|调账| AdjustAccount[账务调整]
ProcessType -->|退款| RefundProcess[退款处理]
ProcessType -->|销账| WriteOff[销账处理]
ProcessType -->|预存调整| PrepaidAdjust[预存调整]
AdjustAccount --> ValidateAdjust[验证调整数据]
RefundProcess --> ValidateRefund[验证退款数据]
WriteOff --> ValidateWriteOff[验证销账数据]
PrepaidAdjust --> ValidatePrepaid[验证预存数据]
ValidateAdjust --> AdjustApproval[调账审批]
ValidateRefund --> RefundApproval[退款审批]
ValidateWriteOff --> WriteOffApproval[销账审批]
ValidatePrepaid --> PrepaidApproval[预存审批]
AdjustApproval --> ApprovalResult{审批结果}
RefundApproval --> ApprovalResult
WriteOffApproval --> ApprovalResult
PrepaidApproval --> ApprovalResult
ApprovalResult -->|拒绝| ApprovalReject[审批拒绝]
ApprovalResult -->|通过| ExecuteProcess[执行处理]
ExecuteProcess --> UpdateAccount[更新账户]
UpdateAccount --> RecordLog[记录日志]
RecordLog --> Complete([处理完成])
AuthError --> End([结束])
ApprovalReject --> End
```
#### 3.4.2 主要功能
**未销调整**处理各类账务调整需求
- 水量调整调整用水量和相关费用
- 金额调整直接调整账单金额
- 违约金减免减免或取消违约金
- 费用追加补收相关费用
**特殊开账**处理特殊情况的账单生成
- 补抄开账补录抄表数据并生成账单
- 估抄开账估算用水量生成账单
- 平均开账基于历史用量平均开账
**账务退款**处理各类退款业务
- 多缴退款退还多缴的水费
- 预付款退款退还预存余额
- 错误缴费退款退还错误缴费
#### 3.4.3 核心接口定义
```java
@RestController
@RequestMapping("/admin-api/water/account")
@Tag(name = "管理后台 - 账务处理")
@Validated
public class AccountProcessController {
@PostMapping("/adjust")
@Operation(summary = "账务调整")
@PreAuthorize("@ss.hasPermission('water:account:adjust')")
public CommonResult<Boolean> adjustAccount(@Valid @RequestBody AccountAdjustReqVO adjustReqVO);
@PostMapping("/refund")
@Operation(summary = "退款处理")
@PreAuthorize("@ss.hasPermission('water:account:refund')")
public CommonResult<Boolean> processRefund(@Valid @RequestBody RefundProcessReqVO refundReqVO);
@PostMapping("/write-off")
@Operation(summary = "销账处理")
@PreAuthorize("@ss.hasPermission('water:account:write-off')")
public CommonResult<Boolean> writeOffAccount(@Valid @RequestBody WriteOffReqVO writeOffReqVO);
}
```
### 3.5 发票管理
发票管理模块负责水费发票的全生命周期管理支持纸质发票和电子发票
#### 3.5.1 业务流程图
```mermaid
flowchart TD
Start([发票业务]) --> InvoiceType{发票类型}
InvoiceType -->|纸质发票| PaperInvoice[纸质发票管理]
InvoiceType -->|电子发票| EInvoice[电子发票管理]
PaperInvoice --> PaperStock[发票库存管理]
PaperStock --> PaperPrint[发票打印]
PaperPrint --> PaperRecord[打印记录]
EInvoice --> EInvoiceGenerate[电子发票生成]
EInvoiceGenerate --> EInvoiceSign[电子签章]
EInvoiceSign --> EInvoiceSend[发票推送]
PaperRecord --> InvoiceQuery[发票查询]
EInvoiceSend --> InvoiceQuery
InvoiceQuery --> InvoiceCancel{需要作废?}
InvoiceCancel -->|是| CancelInvoice[发票作废]
InvoiceCancel -->|否| Complete([完成])
CancelInvoice --> CancelRecord[作废记录]
CancelRecord --> Complete
```
#### 3.5.2 核心接口定义
```java
@RestController
@RequestMapping("/admin-api/water/invoice")
@Tag(name = "管理后台 - 发票管理")
@Validated
public class InvoiceController {
@PostMapping("/generate")
@Operation(summary = "生成发票")
public CommonResult<InvoiceRespVO> generateInvoice(@Valid @RequestBody InvoiceGenerateReqVO generateReqVO);
@PostMapping("/print")
@Operation(summary = "打印发票")
public CommonResult<Boolean> printInvoice(@Valid @RequestBody InvoicePrintReqVO printReqVO);
@PostMapping("/cancel")
@Operation(summary = "发票作废")
public CommonResult<Boolean> cancelInvoice(@Valid @RequestBody InvoiceCancelReqVO cancelReqVO);
}
```
### 3.6 代收业务
代收业务模块负责处理各种渠道的水费代收业务主要功能包括
- 实时收费银行代收支付宝/微信收费代收点收费
- 银行代扣代扣协议管理代扣数据生成和处理
- 银行托收托收单生成托收数据处理
- 代扣渠道管理渠道维护规则设置效率分析
### 3.7 环卫系统
环卫系统模块负责管理与环卫相关的收费和计费业务主要功能包括
- 计费核定环卫收费规则配置和业务字典维护
- 计费退补退费和补缴规则配置字典配置参与计算
- 计费减免环卫费用减免规则配置和审批流程
- 环卫收费统计环卫收费数据统计和分析
### 3.8 业务工单
业务工单模块负责管理日常业务工单的流转和处理主要功能包括
- 业务清单查询通过系统办理的日常业务工单及进度信息
- 上报清单新增查询问题清单包括通过手机端上报的问题
- 稽查工单对手机端的稽查信息进行多条件查询和导出
- 移表工单客户对需要进行移动的水表进行登记
- 换表工单新增客户自报的换表和故障的水表等进行换表登记
- 工作流可视化工作节点可视化展示和流程管理
## 四、表务系统
表务系统负责水表的全生命周期管理包括水表购置安装维修更换等业务
### 4.1 表务工单
表务工单模块负责处理各类表务作业主要功能包括
- 换表工单换表计划换表施工换表回填
- 移表工单移表申请移表施工移表验收
- 拆表工单拆表申请拆表施工拆表确认
- 复装工单复装申请复装施工复装验收
- 校表工单校表申请校表实施校表结果
- 稽查工单水量异常稽查违规用水稽查处罚决定
- 业务上报异常上报投诉上报处理结果反馈
### 4.2 表务仓库
表务仓库模块负责水表的仓储管理主要功能包括
- 新表入库水表检定入库登记入库确认
- 水表检定检定信息记录结果管理
- 水表领用领用单登记领用单管理
- 水表出库出库登记出库确认
- 水表退库退库申请退库确认
- 水表报废报废申请报废确认
- 水表生命周期查询状态查询历史记录查询
### 4.3 水表参数与基础信息
水表参数与基础信息模块负责维护水表相关的基础数据主要功能包括
- 水表厂家管理厂家信息维护厂家状态管理
- 水表型号管理型号信息维护型号分类管理
- 水表口径管理口径信息维护定换周期设置
- 水表量程管理量程信息维护量程范围设置
### 4.4 物联网对接与数据同步
物联网对接与数据同步模块负责水表数据的互联互通主要功能包括
- 厂家设备信息管理设备型号管理厂家信息维护
- 表务对接日志数据同步日志错误处理
- 水表数据推送接口新表数据推送校验机制
- 远程抄表数据同步数据接收验证与处理
- 物联网水表监控状态监控异常事件报警
## 五、报装系统
报装系统负责新用户的报装立户管理主要功能包括
### 5.1 报装流程
报装流程模块负责新用户报装业务的全流程管理主要功能包括
- 报装申请用户申请材料审核现场勘查
- 方案设计设计方案设计审核费用估算
- 合同签订费用通知合同签订收费管理
- 施工管理施工计划施工实施施工验收
- 开户通水水表安装用户立户通水确认
### 5.2 一户一表管理
一户一表管理模块负责实施"一户一表"改造主要功能包括
- 改造计划制定改造计划用户协商费用估算
- 改造实施施工管理水表安装验收管理
- 用户转换数据转换账务处理使用确认
## 六、客户服务
客户服务模块提供多渠道的客户服务功能主要包括
### 6.1 微信、支付宝服务窗
- 账户绑定支持用户绑定水务账户
- 用水查询查询用水情况和用水趋势
- 水费查询查询水费信息和欠费信息
- 在线缴费支持在线缴纳水费
- 业务办理支持在线办理简单业务
### 6.2 历史账单
- 账单查询查询历史账单信息
- 用水分析分析用水趋势提供图表展示
- 账单推送定期推送账单信息
- 账单明细提供详细的账单明细
### 6.3 电子发票
- 发票申请申请开具电子发票
- 发票查询查询已开具发票
- 发票下载下载电子发票
- 发票推送推送电子发票到用户邮箱或微信
### 6.4 营业网点
- 网点查询查询营业网点信息
- 网点导航提供到营业网点的导航
- 业务指南提供各网点业务办理指南
- 等候情况实时显示各网点的等候情况
### 6.5 账户流水
- 流水查询查询账户交易流水
- 明细下载下载流水明细
- 交易统计提供交易金额统计
- 缴费证明生成缴费证明
### 6.6 微网厅
- 用户注册用户注册微网厅账号
- 信息查询查询用水缴费信息
- 业务办理在线办理各类业务
- 用户反馈提交意见建议
## 七、系统配置
系统配置模块提供各类系统参数的配置管理功能主要包括
### 7.1 水表参数
- 水表厂家管理水表生产厂商信息
- 水表型号管理水表型号规格
- 水表量程管理水表量程规格
### 7.2 地址参数
- 行政区划管理行政区划信息
- 地址编码管理地址编码规则
- 地址库维护标准地址库
### 7.3 价格体系
- 用水性质管理不同用水性质的分类
- 水价标准管理不同用水性质的水价标准
- 阶梯水价管理阶梯水价设置
- 调价管理管理水价调整流程
### 7.4 基本配置
- 系统参数管理系统基本参数
- 业务规则管理业务处理规则
- 打印模板管理各类打印模板
- 短信模板管理短信发送模板
### 7.5 催缴管理
- 催缴计划制定欠费催缴计划
- 催缴任务分配催缴任务
- 催缴执行记录催缴执行情况
- 催缴结果统计催缴结果
### 7.6 用户权限
- 菜单权限不同角色可访问的菜单权限配置
- 功能权限不同角色可操作的功能权限配置
- 数据权限通过查询字典权限控制不同用户业务取数权限
- 角色管理自定义角色及权限组合
### 7.7 定时任务
- 任务配置定时任务可视化配置包含传参设置
- 任务监控定时任务执行状态监控
- 任务日志定时任务执行日志记录和查询
- 任务调度任务优先级和执行顺序管理
## 八、系统接口
系统接口模块提供与外部系统的集成和数据交换功能实现业务数据的互通互联
### 8.1 银行接口
银行接口实现与银行系统的对接支持代扣托收等功能主要包括
- 收费接口实现用户通过银行渠道缴纳水费
- 冲正接口处理银行退款和交易取消
- 对账接口与银行系统进行对账
- 托收接口支持银行托收功能
- 代扣接口支持银行代扣功能
### 8.2 支付宝/微信接口
支付宝和微信接口实现与第三方支付平台的对接支持在线支付功能主要包括
- 欠费查询查询用户欠费信息
- 在线支付支持用户在线缴纳水费
- 支付通知处理支付结果通知
- 对账接口与支付平台进行对账
### 8.3 短信接口
短信接口提供短信通知和验证功能主要包括
- 账单通知通过短信通知用户账单信息
- 缴费提醒提醒用户及时缴费
- 催缴通知向欠费用户发送催缴短信
- 业务通知通知用户业务办理状态
- 验证码功能提供短信验证码服务
### 8.4 集抄系统接口
集抄系统接口实现与智能水表集中抄表系统的对接主要包括
- 抄表数据获取获取智能水表的抄表数据
- 水表状态监控监控水表的使用状态
- 异常数据处理处理抄表异常情况
### 8.5 政务系统接口
政务系统接口实现与地方政务平台和政务APP的对接主要包括
- 数据推送推送营收数据到政务平台
- 数据查询支持政务平台查询水务数据
- 缴费对接支持通过政务平台缴费
- 报装工单对接对接报装业务工单
### 8.6 消火栓系统接口
消火栓系统接口实现与消火栓系统的对接主要功能包括
- 预存缴费管理管理用户预存水费
- 剩余水量计算计算用户剩余可用水量
- 取水控制根据预存和剩余水量控制取水
### 8.7 其他系统对接
其他系统对接模块负责与周边系统进行数据交换和业务协同主要功能包括
- 环卫系统对接实现与环卫系统的数据同步和业务流程对接
- 客服系统对接实现与客服系统的工单同步和问题处理
- 工单系统对接实现与工单系统的工单流转和状态同步
- OA系统对接实现与OA系统的审批流程对接和数据共享
- 智水擎平台对接实现与智水擎平台的数据交换和业务协同
## 九、统计分析
统计分析模块提供多维度的数据统计和分析功能为管理决策提供数据支持
### 9.1 报表查询
- 标准报表系统内置的标准统计报表
- 自定义报表用户可自定义的报表
- 报表导出支持将报表导出为ExcelPDF等格式
- 报表打印支持报表打印功能
### 9.2 欠费查询
- 欠费情况统计按区域用户类型等维度统计欠费情况
- 欠费用户明细查询欠费用户的详细信息
- 欠费分析分析欠费原因和趋势
- 欠费导出支持将欠费数据导出
### 9.3 缴费记录
- 缴费情况统计按多维度统计缴费情况
- 缴费明细查询查询缴费明细记录
- 缴费趋势分析分析缴费趋势
- 缴费渠道分析分析各缴费渠道的使用情况
### 9.4 用水分析
- 用水量统计按多维度统计用水量
- 用水趋势分析分析用水趋势预测用水需求
- 异常用水分析识别和分析异常用水情况
- 节水潜力分析分析用户节水潜力
## 十、工程管理
工程管理模块负责处理与供水工程相关的业务包括工程申请施工管理和工程验收等
### 10.1 工程申请
- 工程立项新建供水工程的立项申请
- 材料提交上传工程相关材料
- 前期勘察记录工程前期勘察结果
- 工程预算制定工程预算方案
- 申请审批对工程申请进行审批
### 10.2 工程施工
- 施工计划制定工程施工计划
- 施工派工将施工任务分配给施工人员
- 施工记录记录施工过程和施工情况
- 材料管理管理工程施工材料的使用情况
- 施工异常处理处理施工过程中的异常情况
### 10.3 工程验收
- 验收申请提交工程验收申请
- 验收检查对工程进行验收检查
- 验收记录记录验收结果
- 竣工结算进行工程竣工结算
- 工程归档对工程资料进行归档
### 10.4 工程查询
- 工程进度查询查询工程进度情况
- 工程资料查询查询工程相关资料
- 工程统计统计工程数量金额等信息
- 工程分析分析工程实施情况
## 十一、抄表APP
抄表APP是针对移动端开发的抄表工具支持外勤人员进行现场抄表问题处理和工单管理等业务操作
### 11.1 首页功能
- 首页显示当前登录用户信息快捷搜索和主要和抄表业务相关的功能模块
- 个人信息查看个人信息可以进行密码手机号信息修改可以进行抄表设置
- 快捷查询提供搜索栏用户输入户号户名地址以及册本后系统会自动检索到相关的信息
### 11.2 抄表功能
- 抄表任务显示当前登录的抄表员抄表任务信息
- NFC抄表抄表设备感应NFC后自动弹出抄表页
- 扫码抄表扫水表上二维码搜集该表信息弹出抄表页
- 数据采集抄表数据现场采集功能
- AI录入对接AI接口实现智能读数
- 抄表轨迹记录表的物理位置在地图上点击后采集水表定位
- 抄表导航指引抄表员前往下一个抄表点
- 抄表汇总系统会根据当前登录的人员自动汇总抄表信息
- 账单查询查询客户账单详情
- 欠费查询显示当前登录的抄表员抄表用水客户的欠费情况
### 11.3 工单管理
- 问题上报系统支持上报当前登录的抄表员抄表时遇到的用水问题
- 问题回填问题上报后可进行问题回填和处理
- 代办工单显示当前登录的抄表员需要代办工单
- 平台工单管理移动端提交工单后系统会自动提交到工单处置平台进行受理派发
- 停水复水工单当客户存在欠费的情况下可以对该客户进行停水操作
- 稽查工单实现抄表稽查和水价稽查
- 维修工单提交坏表维修报修等工单
## 十二、接口服务
接口服务模块提供系统对外的API接口管理和服务能力实现与第三方系统的便捷集成
### 12.1 API市场
- API展示展示系统提供的各类API接口
- API使用说明提供API接口的详细使用说明和示例
- API测试提供API接口的在线测试功能
### 12.2 API管理
- API申请第三方系统申请调用API的流程管理
- API调度看板监控API调用情况和性能指标
- 接口服务配置管理管理API接口的配置参数
- 接口限流熔断管理控制API接口的调用频率和熔断机制
### 12.3 接口权限管理
- 授权管理管理API接口的授权信息
- 白名单管理设置允许访问API的IP白名单
- 安全策略设置API调用的安全策略和防护措施
### 12.4 系统对外接口
- 查询接口提供各类数据查询接口
- 业务处理接口提供业务处理和操作接口
- 状态同步接口提供状态信息同步接口
- 数据推送接口提供数据推送和订阅接口
## 系统集成架构
### 前后端集成架构
```mermaid
graph TB
subgraph "前端应用"
F1[管理后台<br/>yudao-ui-admin-vue3]
F2[移动端<br/>uni-app]
F3[客户端<br/>微信小程序]
end
subgraph "后端服务"
B1[认证服务<br/>Spring Security]
B2[业务服务<br/>RuoYi-Vue-Pro]
B3[网关服务<br/>Spring Cloud Gateway]
end
subgraph "数据存储"
D1[(OpenGauss 5.0+)]
D2[(Redis 6.0)]
D3[MinIO文件存储]
end
F1 --> B3
F2 --> B3
F3 --> B3
B3 --> B1
B3 --> B2
B1 --> D2
B2 --> D1
B2 --> D2
B2 --> D3
```
### 技术栈整合方案
**后端技术整合**
- Spring Boot 3.x作为核心框架
- Spring Security 6.x提供安全认证
- MyBatis Plus 3.x简化数据访问
- RuoYi-Vue-Pro提供基础功能框架
**前端技术整合**
- Vue 3.x + TypeScript构建现代化前端
- Element Plus提供UI组件库
- Vite作为构建工具
- Pinia进行状态管理
**数据库集成**
- OpenGauss 5.0+作为主数据库国产自主可控
- Redis 6.0提供缓存和会话管理
- HikariCP连接池优化和读写分离支持
**中间件集成**
- RabbitMQ提供消息队列
- MinIO提供文件存储
- Elasticsearch提供全文搜索
这样的架构设计确保了系统的高可用性可扩展性和维护性为福建水务营收系统提供了坚实的技术基础
---
# 福建水务营收系统数据库设计文档
## 文档信息
| 项目信息 | 详情 |
|---------|------|
| **项目名称** | 福建水务营收系统 |
| **文档类型** | 概要设计文档 |
| **技术框架** | RuoYi-Vue-Pro + yudao-ui-admin-vue3 |
| **文档版本** | v1.0 |
| **编写日期** | 2024-12-19 |
| **文档状态** | 已完成 |
## 目录
- [一、数据库设计概述](#一数据库设计概述)
- [二、数据库架构](#二数据库架构)
- [三、核心数据模型ER图](#三核心数据模型er图)
- [四、核心数据表设计](#四核心数据表设计)
- [五、完整DDL语句](#五完整ddl语句)
- [六、OpenGauss数据库特性应用](#六opengauss数据库特性应用)
- [七、索引设计与优化](#七索引设计与优化)
- [八、OpenGauss数据安全设计](#八opengauss数据安全设计)
## 一、数据库设计概述
福建水务营收系统采用**华为OpenGauss 5.0+**数据库基于RuoYi-Vue-Pro框架规范设计OpenGauss作为国产自主可控的企业级数据库具有高性能高可用高安全的特点完全满足水务行业对数据安全和国产化的要求数据库架构支持多租户高并发高可用的业务需求为水务营收业务提供稳定可靠的数据存储服务
### 1.1 设计目标
- 支持100万客户的业务量满足3-5年业务发展需求
- 支持200并发用户50并发移动设备
- 系统响应时间不超过3秒
- 数据安全等保三级要求
- 支持多租户数据隔离
- **国产化要求**符合国产数据库替代要求
### 1.2 数据库选型优势
- **国产自主可控**华为OpenGauss是完全自主知识产权的数据库
- **高性能**优化的SQL引擎查询性能优于传统数据库20-30%
- **高可用**支持主备同步读写分离故障自动切换
- **安全可信**内置数据加密审计权限管控等安全特性
- **生态兼容**兼容PostgreSQL/MySQL协议迁移成本低
### 1.3 设计原则
- **标准化**遵循OpenGauss数据库设计规范
- **多租户**基于tenant_id字段实现数据隔离
- **可扩展**预留扩展字段支持业务增长
- **高性能**合理设计索引优化查询性能
- **安全性**利用OpenGauss内置安全特性
## 二、数据库架构
### 1. 数据库架构图
```mermaid
graph TB
subgraph "应用层"
APP[Water Biz Application<br/>RuoYi-Vue-Pro]
end
subgraph "数据访问层"
MP[MyBatis Plus<br/>ORM框架]
CACHE[Redis缓存<br/>热点数据]
end
subgraph "数据存储层"
subgraph "OpenGauss主从集群"
MASTER[(OpenGauss主库<br/>读写)]
SLAVE[(OpenGauss从库<br/>只读)]
end
subgraph "业务数据库"
DB_CUSTOMER[(客户数据库<br/>Customer DB)]
DB_BILLING[(营收数据库<br/>Billing DB)]
DB_METER[(表务数据库<br/>Meter DB)]
DB_SYSTEM[(系统数据库<br/>System DB)]
end
subgraph "数据归档"
DB_HISTORY[(历史数据库<br/>Archive DB)]
BACKUP[(备份存储<br/>Backup Storage)]
end
end
APP --> MP
APP --> CACHE
MP --> MASTER
MASTER --> SLAVE
MASTER --> DB_CUSTOMER
MASTER --> DB_BILLING
MASTER --> DB_METER
MASTER --> DB_SYSTEM
SLAVE --> DB_HISTORY
MASTER --> BACKUP
```
### 2. 多租户架构设计
```mermaid
graph TB
subgraph "多租户数据隔离"
TENANT1[租户1: 福建水务集团]
TENANT2[租户2: 厦门分公司]
TENANT3[租户3: 泉州分公司]
end
subgraph "共享数据库"
subgraph "业务表结构"
TABLE1[water_customer<br/>+ tenant_id]
TABLE2[water_meter<br/>+ tenant_id]
TABLE3[water_bill<br/>+ tenant_id]
TABLE4[water_payment<br/>+ tenant_id]
end
subgraph "租户隔离机制"
INTERCEPTOR[MyBatis Plus<br/>多租户拦截器]
FILTER[数据权限过滤器]
end
end
TENANT1 --> INTERCEPTOR
TENANT2 --> INTERCEPTOR
TENANT3 --> INTERCEPTOR
INTERCEPTOR --> FILTER
FILTER --> TABLE1
FILTER --> TABLE2
FILTER --> TABLE3
FILTER --> TABLE4
```
### 3. 通用字段设计
所有业务表统一包含以下基础字段
| 字段名 | 数据类型 | 长度 | 默认值 | 描述 |
|-------|---------|------|--------|-----|
| id | BIGINT | - | AUTO_INCREMENT | 主键ID |
| tenant_id | BIGINT | - | 0 | 租户ID(多租户隔离) |
| creator | VARCHAR | 64 | '' | 创建者 |
| create_time | DATETIME | - | CURRENT_TIMESTAMP | 创建时间 |
| updater | VARCHAR | 64 | '' | 更新者 |
| update_time | DATETIME | - | CURRENT_TIMESTAMP | 更新时间 |
| deleted | BIT | 1 | 0 | 逻辑删除标识 |
## 三、核心数据模型ER图
### 1. 客户管理模块ER图
```mermaid
erDiagram
WATER_CUSTOMER {
bigint id PK "主键ID"
varchar customer_code UK "客户编号"
varchar customer_name "客户名称"
varchar customer_type "客户类型"
varchar id_type "证件类型"
varchar id_number "证件号码"
varchar phone "联系电话"
varchar address "详细地址"
varchar area_code "行政区划代码"
tinyint status "状态"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
WATER_METER {
bigint id PK "主键ID"
varchar meter_code UK "水表编号"
varchar meter_no "水表表号"
varchar meter_type "水表类型"
varchar meter_model "水表型号"
varchar meter_caliber "水表口径"
date install_date "安装日期"
varchar install_position "安装位置"
decimal initial_reading "初始读数"
decimal current_reading "当前读数"
varchar reading_cycle "抄表周期"
varchar book_code "册本编号"
tinyint status "状态"
bigint customer_id FK "客户ID"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
WATER_CUSTOMER_ACCOUNT {
bigint id PK "主键ID"
decimal balance "账户余额"
decimal credit_amount "信用额度"
date last_payment_date "最近缴费日期"
tinyint status "账户状态"
bigint customer_id FK "客户ID"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
WATER_CUSTOMER ||--o{ WATER_METER : "拥有"
WATER_CUSTOMER ||--|| WATER_CUSTOMER_ACCOUNT : "对应"
```
### 2. 营收管理模块ER图
```mermaid
erDiagram
WATER_METER_READING {
bigint id PK "主键ID"
varchar reading_code UK "抄表记录编号"
date reading_date "抄表日期"
decimal reading_value "抄表读数"
decimal prev_reading_value "上次读数"
decimal water_usage "用水量"
varchar reading_type "抄表类型"
varchar reader_id "抄表员ID"
varchar remark "备注"
tinyint status "状态"
bigint meter_id FK "水表ID"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
WATER_BILL {
bigint id PK "主键ID"
varchar bill_code UK "账单编号"
varchar bill_month "账期"
decimal water_usage "用水量"
decimal water_fee "水费金额"
decimal sewage_fee "污水处理费"
decimal other_fee "其他费用"
decimal total_amount "总金额"
date due_date "缴费截止日期"
tinyint bill_status "账单状态"
bigint customer_id FK "客户ID"
bigint meter_id FK "水表ID"
bigint reading_id FK "抄表记录ID"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
WATER_PAYMENT {
bigint id PK "主键ID"
varchar payment_code UK "缴费记录编号"
varchar payment_type "缴费类型"
varchar payment_channel "缴费渠道"
decimal payment_amount "缴费金额"
datetime payment_time "缴费时间"
varchar transaction_no "交易流水号"
varchar operator_id "操作员ID"
varchar remark "备注"
tinyint payment_status "缴费状态"
bigint bill_id FK "账单ID"
bigint customer_id FK "客户ID"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
WATER_METER_READING ||--|| WATER_BILL : "生成"
WATER_BILL ||--o{ WATER_PAYMENT : "对应"
```
### 3. 表务管理模块ER图
```mermaid
erDiagram
WATER_METER_ARCHIVE {
bigint id PK "主键ID"
varchar archive_code UK "档案编号"
varchar manufacturer "生产厂家"
date production_date "生产日期"
int valid_period "有效期(月)"
date verification_date "检定日期"
date next_verification_date "下次检定日期"
varchar certificate_no "检定证书号"
tinyint archive_status "档案状态"
bigint meter_id FK "水表ID"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
WATER_METER_WORKORDER {
bigint id PK "主键ID"
varchar workorder_code UK "工单编号"
varchar workorder_type "工单类型"
varchar workorder_status "工单状态"
date apply_date "申请日期"
date plan_date "计划执行日期"
date execute_date "实际执行日期"
varchar applicant_id "申请人ID"
varchar executor_id "执行人ID"
varchar reason "申请原因"
varchar result "执行结果"
bigint meter_id FK "水表ID"
bigint customer_id FK "客户ID"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
WATER_METER_STOCK {
bigint id PK "主键ID"
varchar stock_code UK "库存编号"
varchar warehouse_code "仓库编码"
varchar warehouse_name "仓库名称"
int stock_quantity "库存数量"
int min_stock "最小库存"
int max_stock "最大库存"
varchar meter_model "水表型号"
varchar meter_caliber "水表口径"
tinyint stock_status "库存状态"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
WATER_METER ||--|| WATER_METER_ARCHIVE : "对应"
WATER_METER ||--o{ WATER_METER_WORKORDER : "产生"
```
### 4. 系统管理模块ER图
```mermaid
erDiagram
SYSTEM_TENANT {
bigint id PK "主键ID"
varchar tenant_name "租户名称"
varchar tenant_code UK "租户编码"
varchar contact_name "联系人"
varchar contact_phone "联系电话"
varchar contact_email "联系邮箱"
tinyint tenant_status "租户状态"
datetime expire_time "过期时间"
varchar domain "域名"
varchar package_name "套餐名称"
int user_count "用户数量"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
SYSTEM_USERS {
bigint id PK "主键ID"
varchar username UK "用户名"
varchar password "密码"
varchar nickname "昵称"
varchar remark "备注"
varchar dept_id "部门ID"
varchar post_ids "岗位ID列表"
varchar email "邮箱"
varchar mobile "手机号"
tinyint sex "性别"
varchar avatar "头像"
tinyint status "状态"
datetime login_date "最后登录时间"
varchar login_ip "最后登录IP"
bigint tenant_id "租户ID"
varchar creator "创建者"
datetime create_time "创建时间"
varchar updater "更新者"
datetime update_time "更新时间"
tinyint deleted "是否删除"
}
SYSTEM_TENANT ||--o{ SYSTEM_USERS : "包含"
```
## 四、核心数据表设计
### 1. 表务管理模块ER图
```mermaid
erDiagram
WATER_METER_WORKORDER {
bigint id PK "主键ID"
varchar workorder_code UK "工单编号"
varchar workorder_type "工单类型"
varchar workorder_status "工单状态"
date apply_date "申请日期"
date plan_date "计划执行日期"
date execute_date "实际执行日期"
varchar applicant_id "申请人ID"
varchar executor_id "执行人ID"
varchar reason "申请原因"
varchar result "执行结果"
bigint meter_id FK "水表ID"
bigint customer_id FK "客户ID"
bigint tenant_id "租户ID"
}
WATER_METER_STOCK {
bigint id PK "主键ID"
varchar stock_code UK "库存编号"
varchar meter_brand "水表品牌"
varchar meter_model "水表型号"
varchar meter_caliber "水表口径"
int stock_quantity "库存数量"
int min_stock "最小库存"
decimal unit_price "单价"
varchar warehouse_location "仓库位置"
tinyint stock_status "库存状态"
bigint tenant_id "租户ID"
}
WATER_METER_INVENTORY {
bigint id PK "主键ID"
varchar inventory_code UK "出入库编号"
varchar inventory_type "出入库类型"
int quantity "数量"
decimal unit_price "单价"
decimal total_amount "总金额"
varchar operator_id "操作员ID"
datetime operation_time "操作时间"
varchar remark "备注"
bigint stock_id FK "库存ID"
bigint workorder_id FK "工单ID"
bigint tenant_id "租户ID"
}
WATER_METER ||--o{ WATER_METER_WORKORDER : "生成"
WATER_METER_STOCK ||--o{ WATER_METER_INVENTORY : "出入库"
WATER_METER_WORKORDER ||--o{ WATER_METER_INVENTORY : "关联"
```
### 2. 系统管理模块ER图
```mermaid
erDiagram
WATER_DICT_TYPE {
bigint id PK "主键ID"
varchar dict_name "字典名称"
varchar dict_type UK "字典类型"
varchar remark "备注"
tinyint status "状态"
bigint tenant_id "租户ID"
}
WATER_DICT_DATA {
bigint id PK "主键ID"
varchar dict_type "字典类型"
varchar dict_label "字典标签"
varchar dict_value "字典键值"
int dict_sort "字典排序"
varchar color_type "颜色类型"
varchar css_class "CSS类名"
varchar remark "备注"
tinyint status "状态"
bigint tenant_id "租户ID"
}
WATER_CONFIG {
bigint id PK "主键ID"
varchar config_name "参数名称"
varchar config_key UK "参数键名"
varchar config_value "参数键值"
varchar config_type "系统内置"
varchar remark "备注"
bigint tenant_id "租户ID"
}
WATER_PRICE_CONFIG {
bigint id PK "主键ID"
varchar price_name "水价名称"
varchar customer_type "客户类型"
varchar price_type "价格类型"
decimal base_price "基础价格"
decimal sewage_price "污水处理费"
decimal garbage_price "垃圾处理费"
date effective_date "生效日期"
date expire_date "失效日期"
tinyint status "状态"
bigint tenant_id "租户ID"
}
WATER_DICT_TYPE ||--o{ WATER_DICT_DATA : "包含"
```
## 五、完整DDL语句
### 1. 客户管理相关表DDL
#### 1.1 客户基本信息表
```sql
CREATE TABLE `water_customer` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`customer_code` varchar(32) NOT NULL COMMENT '客户编号',
`customer_name` varchar(100) NOT NULL COMMENT '客户名称',
`customer_type` varchar(20) NOT NULL COMMENT '客户类型(居民:RESIDENT,非居民:NON_RESIDENT,工业:INDUSTRIAL,行政:ADMINISTRATIVE)',
`id_type` varchar(20) DEFAULT NULL COMMENT '证件类型(身份证:ID_CARD,营业执照:BUSINESS_LICENSE)',
`id_number` varchar(30) DEFAULT NULL COMMENT '证件号码',
`phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`mobile` varchar(20) DEFAULT NULL COMMENT '手机号码',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`address` varchar(500) DEFAULT NULL COMMENT '详细地址',
`area_code` varchar(20) DEFAULT NULL COMMENT '行政区划代码',
`postal_code` varchar(10) DEFAULT NULL COMMENT '邮政编码',
`contact_person` varchar(50) DEFAULT NULL COMMENT '联系人',
`bank_account` varchar(50) DEFAULT NULL COMMENT '银行账户',
`bank_name` varchar(100) DEFAULT NULL COMMENT '开户银行',
`remark` varchar(500) DEFAULT NULL COMMENT '备注信息',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态(0:停用,1:正常,2:欠费,3:销户)',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_customer_code` (`customer_code`, `tenant_id`),
KEY `idx_customer_name` (`customer_name`),
KEY `idx_phone` (`phone`),
KEY `idx_id_number` (`id_number`),
KEY `idx_tenant_customer_type` (`tenant_id`, `customer_type`),
KEY `idx_status` (`status`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户基本信息表';
```
#### 1.2 水表信息表
```sql
CREATE TABLE `water_meter` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`meter_code` varchar(32) NOT NULL COMMENT '水表编号',
`meter_no` varchar(30) DEFAULT NULL COMMENT '水表表号',
`meter_type` varchar(20) NOT NULL COMMENT '水表类型(机械:MECHANICAL,智能:SMART,远传:REMOTE)',
`meter_model` varchar(50) DEFAULT NULL COMMENT '水表型号',
`meter_caliber` varchar(10) DEFAULT NULL COMMENT '水表口径(15mm,20mm,25mm等)',
`manufacturer` varchar(100) DEFAULT NULL COMMENT '生产厂家',
`production_date` date DEFAULT NULL COMMENT '生产日期',
`install_date` date DEFAULT NULL COMMENT '安装日期',
`install_position` varchar(500) DEFAULT NULL COMMENT '安装位置',
`longitude` decimal(10,7) DEFAULT NULL COMMENT '经度',
`latitude` decimal(10,7) DEFAULT NULL COMMENT '纬度',
`initial_reading` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '初始读数',
`current_reading` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '当前读数',
`reading_cycle` varchar(20) NOT NULL DEFAULT 'MONTHLY' COMMENT '抄表周期(月度:MONTHLY,双月:BIMONTHLY,季度:QUARTERLY)',
`book_code` varchar(32) DEFAULT NULL COMMENT '册本编号',
`reading_route` varchar(100) DEFAULT NULL COMMENT '抄表路线',
`meter_status` tinyint NOT NULL DEFAULT '1' COMMENT '水表状态(0:停用,1:正常,2:故障,3:拆除)',
`customer_id` bigint NOT NULL COMMENT '客户ID',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_meter_code` (`meter_code`, `tenant_id`),
KEY `idx_meter_no` (`meter_no`),
KEY `idx_customer_id` (`customer_id`),
KEY `idx_book_code` (`book_code`),
KEY `idx_meter_type` (`meter_type`),
KEY `idx_meter_status` (`meter_status`),
KEY `idx_tenant_status` (`tenant_id`, `meter_status`),
CONSTRAINT `fk_meter_customer` FOREIGN KEY (`customer_id`) REFERENCES `water_customer` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='水表信息表';
```
### 3. 表务工单管理表DDL
#### 3.1 表务工单表
```sql
CREATE TABLE `water_meter_workorder` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`workorder_code` varchar(32) NOT NULL COMMENT '工单编号',
`workorder_type` varchar(20) NOT NULL COMMENT '工单类型(换表:CHANGE,移表:MOVE,拆表:REMOVE,装表:INSTALL,维修:REPAIR)',
`workorder_status` varchar(20) NOT NULL DEFAULT 'PENDING' COMMENT '工单状态(待处理:PENDING,执行中:PROCESSING,已完成:COMPLETED,已取消:CANCELLED)',
`apply_date` date NOT NULL COMMENT '申请日期',
`plan_date` date DEFAULT NULL COMMENT '计划执行日期',
`execute_date` date DEFAULT NULL COMMENT '实际执行日期',
`applicant_id` varchar(20) DEFAULT NULL COMMENT '申请人ID',
`applicant_name` varchar(50) DEFAULT NULL COMMENT '申请人姓名',
`executor_id` varchar(20) DEFAULT NULL COMMENT '执行人ID',
`executor_name` varchar(50) DEFAULT NULL COMMENT '执行人姓名',
`reason` varchar(500) DEFAULT NULL COMMENT '申请原因',
`result` varchar(500) DEFAULT NULL COMMENT '执行结果',
`old_meter_no` varchar(30) DEFAULT NULL COMMENT '旧水表表号',
`new_meter_no` varchar(30) DEFAULT NULL COMMENT '新水表表号',
`old_reading` decimal(10,2) DEFAULT NULL COMMENT '旧表读数',
`new_reading` decimal(10,2) DEFAULT NULL COMMENT '新表读数',
`cost_amount` decimal(10,2) DEFAULT NULL COMMENT '费用金额',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`meter_id` bigint NOT NULL COMMENT '水表ID',
`customer_id` bigint NOT NULL COMMENT '客户ID',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_workorder_code` (`workorder_code`, `tenant_id`),
KEY `idx_workorder_type` (`workorder_type`),
KEY `idx_workorder_status` (`workorder_status`),
KEY `idx_apply_date` (`apply_date`),
KEY `idx_meter_id` (`meter_id`),
KEY `idx_customer_id` (`customer_id`),
KEY `idx_tenant_type_status` (`tenant_id`, `workorder_type`, `workorder_status`),
CONSTRAINT `fk_workorder_meter` FOREIGN KEY (`meter_id`) REFERENCES `water_meter` (`id`),
CONSTRAINT `fk_workorder_customer` FOREIGN KEY (`customer_id`) REFERENCES `water_customer` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='表务工单表';
```
#### 3.2 水表库存管理表
```sql
CREATE TABLE `water_meter_stock` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`stock_code` varchar(32) NOT NULL COMMENT '库存编号',
`meter_brand` varchar(50) NOT NULL COMMENT '水表品牌',
`meter_model` varchar(50) NOT NULL COMMENT '水表型号',
`meter_caliber` varchar(10) NOT NULL COMMENT '水表口径',
`meter_type` varchar(20) NOT NULL COMMENT '水表类型',
`stock_quantity` int NOT NULL DEFAULT '0' COMMENT '库存数量',
`min_stock` int NOT NULL DEFAULT '0' COMMENT '最小库存',
`max_stock` int DEFAULT NULL COMMENT '最大库存',
`unit_price` decimal(10,2) DEFAULT NULL COMMENT '单价',
`warehouse_location` varchar(100) DEFAULT NULL COMMENT '仓库位置',
`supplier` varchar(100) DEFAULT NULL COMMENT '供应商',
`purchase_date` date DEFAULT NULL COMMENT '进货日期',
`warranty_period` int DEFAULT '24' COMMENT '质保期(月)',
`stock_status` tinyint NOT NULL DEFAULT '1' COMMENT '库存状态(0:停用,1:正常,2:缺货,3:超储)',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_stock_code` (`stock_code`, `tenant_id`),
KEY `idx_meter_brand` (`meter_brand`),
KEY `idx_meter_model` (`meter_model`),
KEY `idx_meter_caliber` (`meter_caliber`),
KEY `idx_stock_status` (`stock_status`),
KEY `idx_tenant_brand_model` (`tenant_id`, `meter_brand`, `meter_model`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='水表库存管理表';
```
### 4. 系统管理相关表DDL
#### 4.1 数据字典类型表
```sql
CREATE TABLE `water_dict_type` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`dict_name` varchar(100) NOT NULL COMMENT '字典名称',
`dict_type` varchar(100) NOT NULL COMMENT '字典类型',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态(0:停用,1:正常)',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_dict_type` (`dict_type`, `tenant_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据字典类型表';
```
### 5. 完整DDL语句列表
#### 5.1 客户基本信息表 (OpenGauss版本)
```sql
-- OpenGauss数据库DDL语句
CREATE TABLE water_customer (
id SERIAL PRIMARY KEY,
customer_code VARCHAR(32) NOT NULL,
customer_name VARCHAR(100) NOT NULL,
customer_type VARCHAR(20) NOT NULL CHECK (customer_type IN ('RESIDENT','NON_RESIDENT','INDUSTRIAL','ADMINISTRATIVE')),
id_type VARCHAR(20) DEFAULT NULL CHECK (id_type IN ('ID_CARD','BUSINESS_LICENSE') OR id_type IS NULL),
id_number VARCHAR(30) DEFAULT NULL,
phone VARCHAR(20) DEFAULT NULL,
mobile VARCHAR(20) DEFAULT NULL,
email VARCHAR(100) DEFAULT NULL,
address VARCHAR(500) DEFAULT NULL,
area_code VARCHAR(20) DEFAULT NULL,
postal_code VARCHAR(10) DEFAULT NULL,
contact_person VARCHAR(50) DEFAULT NULL,
bank_account VARCHAR(50) DEFAULT NULL,
bank_name VARCHAR(100) DEFAULT NULL,
remark VARCHAR(500) DEFAULT NULL,
status SMALLINT NOT NULL DEFAULT 1 CHECK (status IN (0,1,2,3)),
tenant_id BIGINT NOT NULL DEFAULT 0,
creator VARCHAR(64) DEFAULT '',
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updater VARCHAR(64) DEFAULT '',
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted BOOLEAN NOT NULL DEFAULT FALSE
);
-- 创建注释
COMMENT ON TABLE water_customer IS '客户基本信息表';
COMMENT ON COLUMN water_customer.id IS '主键ID';
COMMENT ON COLUMN water_customer.customer_code IS '客户编号';
COMMENT ON COLUMN water_customer.customer_name IS '客户名称';
COMMENT ON COLUMN water_customer.customer_type IS '客户类型(居民:RESIDENT,非居民:NON_RESIDENT,工业:INDUSTRIAL,行政:ADMINISTRATIVE)';
COMMENT ON COLUMN water_customer.id_type IS '证件类型(身份证:ID_CARD,营业执照:BUSINESS_LICENSE)';
COMMENT ON COLUMN water_customer.id_number IS '证件号码';
COMMENT ON COLUMN water_customer.phone IS '联系电话';
COMMENT ON COLUMN water_customer.mobile IS '手机号码';
COMMENT ON COLUMN water_customer.email IS '邮箱';
COMMENT ON COLUMN water_customer.address IS '详细地址';
COMMENT ON COLUMN water_customer.area_code IS '行政区划代码';
COMMENT ON COLUMN water_customer.postal_code IS '邮政编码';
COMMENT ON COLUMN water_customer.contact_person IS '联系人';
COMMENT ON COLUMN water_customer.bank_account IS '银行账户';
COMMENT ON COLUMN water_customer.bank_name IS '开户银行';
COMMENT ON COLUMN water_customer.remark IS '备注信息';
COMMENT ON COLUMN water_customer.status IS '状态(0:停用,1:正常,2:欠费,3:销户)';
COMMENT ON COLUMN water_customer.tenant_id IS '租户ID';
COMMENT ON COLUMN water_customer.creator IS '创建者';
COMMENT ON COLUMN water_customer.create_time IS '创建时间';
COMMENT ON COLUMN water_customer.updater IS '更新者';
COMMENT ON COLUMN water_customer.update_time IS '更新时间';
COMMENT ON COLUMN water_customer.deleted IS '是否删除';
-- 创建索引
CREATE UNIQUE INDEX uk_customer_code ON water_customer (customer_code, tenant_id);
CREATE INDEX idx_customer_name ON water_customer (customer_name);
CREATE INDEX idx_phone ON water_customer (phone);
CREATE INDEX idx_id_number ON water_customer (id_number);
CREATE INDEX idx_tenant_customer_type ON water_customer (tenant_id, customer_type);
CREATE INDEX idx_status ON water_customer (status);
CREATE INDEX idx_create_time ON water_customer (create_time);
-- 创建更新时间触发器
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.update_time = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER water_customer_update_timestamp
BEFORE UPDATE ON water_customer
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
```
#### 1.2 水表信息表
```sql
CREATE TABLE `water_meter` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`meter_code` varchar(32) NOT NULL COMMENT '水表编号',
`meter_no` varchar(30) DEFAULT NULL COMMENT '水表表号',
`meter_type` varchar(20) NOT NULL COMMENT '水表类型(机械:MECHANICAL,智能:SMART,远传:REMOTE)',
`meter_model` varchar(50) DEFAULT NULL COMMENT '水表型号',
`meter_caliber` varchar(10) DEFAULT NULL COMMENT '水表口径(15mm,20mm,25mm等)',
`manufacturer` varchar(100) DEFAULT NULL COMMENT '生产厂家',
`production_date` date DEFAULT NULL COMMENT '生产日期',
`install_date` date DEFAULT NULL COMMENT '安装日期',
`install_position` varchar(500) DEFAULT NULL COMMENT '安装位置',
`longitude` decimal(10,7) DEFAULT NULL COMMENT '经度',
`latitude` decimal(10,7) DEFAULT NULL COMMENT '纬度',
`initial_reading` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '初始读数',
`current_reading` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '当前读数',
`reading_cycle` varchar(20) NOT NULL DEFAULT 'MONTHLY' COMMENT '抄表周期(月度:MONTHLY,双月:BIMONTHLY,季度:QUARTERLY)',
`book_code` varchar(32) DEFAULT NULL COMMENT '册本编号',
`reading_route` varchar(100) DEFAULT NULL COMMENT '抄表路线',
`meter_status` tinyint NOT NULL DEFAULT '1' COMMENT '水表状态(0:停用,1:正常,2:故障,3:拆除)',
`customer_id` bigint NOT NULL COMMENT '客户ID',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_meter_code` (`meter_code`, `tenant_id`),
KEY `idx_meter_no` (`meter_no`),
KEY `idx_customer_id` (`customer_id`),
KEY `idx_book_code` (`book_code`),
KEY `idx_meter_type` (`meter_type`),
KEY `idx_meter_status` (`meter_status`),
KEY `idx_tenant_status` (`tenant_id`, `meter_status`),
CONSTRAINT `fk_meter_customer` FOREIGN KEY (`customer_id`) REFERENCES `water_customer` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='水表信息表';
```
#### 1.3 客户账户表
```sql
CREATE TABLE `water_customer_account` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`account_code` varchar(32) NOT NULL COMMENT '账户编号',
`balance` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '账户余额',
`credit_amount` decimal(12,2) DEFAULT '0.00' COMMENT '信用额度',
`deposit_amount` decimal(12,2) DEFAULT '0.00' COMMENT '保证金',
`frozen_amount` decimal(12,2) DEFAULT '0.00' COMMENT '冻结金额',
`last_payment_date` date DEFAULT NULL COMMENT '最近缴费日期',
`last_payment_amount` decimal(12,2) DEFAULT NULL COMMENT '最近缴费金额',
`arrears_amount` decimal(12,2) DEFAULT '0.00' COMMENT '欠费金额',
`arrears_months` int DEFAULT '0' COMMENT '欠费月数',
`account_status` tinyint NOT NULL DEFAULT '1' COMMENT '账户状态(0:停用,1:正常,2:欠费,3:冻结)',
`customer_id` bigint NOT NULL COMMENT '客户ID',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_account_code` (`account_code`, `tenant_id`),
UNIQUE KEY `uk_customer_account` (`customer_id`, `tenant_id`),
KEY `idx_account_status` (`account_status`),
KEY `idx_balance` (`balance`),
KEY `idx_arrears` (`arrears_amount`),
CONSTRAINT `fk_account_customer` FOREIGN KEY (`customer_id`) REFERENCES `water_customer` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户账户信息表';
```
### 2. 营收管理相关表DDL
#### 2.1 抄表记录表
```sql
CREATE TABLE `water_meter_reading` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`reading_code` varchar(32) NOT NULL COMMENT '抄表记录编号',
`reading_date` date NOT NULL COMMENT '抄表日期',
`reading_time` datetime DEFAULT NULL COMMENT '抄表时间',
`reading_value` decimal(10,2) NOT NULL COMMENT '抄表读数',
`prev_reading_value` decimal(10,2) DEFAULT NULL COMMENT '上次读数',
`water_usage` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '用水量',
`reading_type` varchar(20) NOT NULL COMMENT '抄表类型(手工:MANUAL,远传:REMOTE,自报:SELF_REPORT,估算:ESTIMATE)',
`reading_method` varchar(20) DEFAULT NULL COMMENT '抄表方式(现场:FIELD,拍照:PHOTO,NFC:NFC,扫码:SCAN)',
`reader_id` varchar(20) DEFAULT NULL COMMENT '抄表员ID',
`reader_name` varchar(50) DEFAULT NULL COMMENT '抄表员姓名',
`photo_url` varchar(255) DEFAULT NULL COMMENT '抄表照片URL',
`reading_location` varchar(200) DEFAULT NULL COMMENT '抄表位置',
`abnormal_flag` tinyint DEFAULT '0' COMMENT '异常标识(0:正常,1:异常)',
`abnormal_reason` varchar(200) DEFAULT NULL COMMENT '异常原因',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`reading_status` tinyint NOT NULL DEFAULT '0' COMMENT '状态(0:未复核,1:已复核,2:已开账,3:作废)',
`meter_id` bigint NOT NULL COMMENT '水表ID',
`customer_id` bigint NOT NULL COMMENT '客户ID',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_reading_code` (`reading_code`, `tenant_id`),
KEY `idx_meter_reading_date` (`meter_id`, `reading_date`),
KEY `idx_reading_date` (`reading_date`),
KEY `idx_reader_id` (`reader_id`),
KEY `idx_reading_status` (`reading_status`),
KEY `idx_customer_id` (`customer_id`),
KEY `idx_tenant_meter_date` (`tenant_id`, `meter_id`, `reading_date`),
CONSTRAINT `fk_reading_meter` FOREIGN KEY (`meter_id`) REFERENCES `water_meter` (`id`),
CONSTRAINT `fk_reading_customer` FOREIGN KEY (`customer_id`) REFERENCES `water_customer` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='抄表记录表';
```
#### 2.2 水费账单表
```sql
CREATE TABLE `water_bill` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`bill_code` varchar(32) NOT NULL COMMENT '账单编号',
`bill_month` varchar(7) NOT NULL COMMENT '账期(格式:YYYY-MM)',
`bill_date` date NOT NULL COMMENT '开账日期',
`water_usage` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '用水量',
`prev_reading` decimal(10,2) DEFAULT NULL COMMENT '上期读数',
`current_reading` decimal(10,2) DEFAULT NULL COMMENT '本期读数',
`reading_days` int DEFAULT NULL COMMENT '抄表间隔天数',
`water_price` decimal(8,4) DEFAULT NULL COMMENT '水价单价',
`water_fee` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '水费金额',
`sewage_fee` decimal(10,2) DEFAULT '0.00' COMMENT '污水处理费',
`garbage_fee` decimal(10,2) DEFAULT '0.00' COMMENT '垃圾处理费',
`other_fee` decimal(10,2) DEFAULT '0.00' COMMENT '其他费用',
`adjustment_fee` decimal(10,2) DEFAULT '0.00' COMMENT '调整费用',
`late_fee` decimal(10,2) DEFAULT '0.00' COMMENT '滞纳金',
`total_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '总金额',
`paid_amount` decimal(10,2) DEFAULT '0.00' COMMENT '已缴金额',
`balance_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '余额',
`due_date` date NOT NULL COMMENT '缴费截止日期',
`billing_type` varchar(20) DEFAULT 'NORMAL' COMMENT '开账类型(正常:NORMAL,追补:SUPPLEMENT,调整:ADJUSTMENT)',
`bill_status` tinyint NOT NULL DEFAULT '0' COMMENT '账单状态(0:未缴费,1:已缴费,2:部分缴费,3:作废)',
`payment_status` tinyint DEFAULT '0' COMMENT '缴费状态(0:未缴,1:已缴,2:部分缴费)',
`customer_id` bigint NOT NULL COMMENT '客户ID',
`meter_id` bigint NOT NULL COMMENT '水表ID',
`reading_id` bigint DEFAULT NULL COMMENT '抄表记录ID',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_bill_code` (`bill_code`, `tenant_id`),
KEY `idx_customer_bill_month` (`customer_id`, `bill_month`),
KEY `idx_meter_bill_month` (`meter_id`, `bill_month`),
KEY `idx_bill_status` (`bill_status`),
KEY `idx_due_date` (`due_date`),
KEY `idx_tenant_customer_month` (`tenant_id`, `customer_id`, `bill_month`),
CONSTRAINT `fk_bill_customer` FOREIGN KEY (`customer_id`) REFERENCES `water_customer` (`id`),
CONSTRAINT `fk_bill_meter` FOREIGN KEY (`meter_id`) REFERENCES `water_meter` (`id`),
CONSTRAINT `fk_bill_reading` FOREIGN KEY (`reading_id`) REFERENCES `water_meter_reading` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='水费账单表';
```
#### 2.3 缴费记录表
```sql
CREATE TABLE `water_payment` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`payment_code` varchar(32) NOT NULL COMMENT '缴费记录编号',
`payment_type` varchar(20) NOT NULL COMMENT '缴费类型(正常缴费:NORMAL,预存:PREPAID,退费:REFUND)',
`payment_channel` varchar(20) NOT NULL COMMENT '缴费渠道(现金:CASH,银行卡:BANK_CARD,微信:WECHAT,支付宝:ALIPAY,银行代扣:BANK_DEDUCT)',
`payment_amount` decimal(10,2) NOT NULL COMMENT '缴费金额',
`actual_amount` decimal(10,2) DEFAULT NULL COMMENT '实收金额',
`change_amount` decimal(10,2) DEFAULT '0.00' COMMENT '找零金额',
`payment_time` datetime NOT NULL COMMENT '缴费时间',
`transaction_no` varchar(50) DEFAULT NULL COMMENT '交易流水号',
`third_party_no` varchar(50) DEFAULT NULL COMMENT '第三方交易号',
`operator_id` varchar(20) DEFAULT NULL COMMENT '操作员ID',
`operator_name` varchar(50) DEFAULT NULL COMMENT '操作员姓名',
`outlet_code` varchar(20) DEFAULT NULL COMMENT '营业网点代码',
`pos_machine_no` varchar(20) DEFAULT NULL COMMENT 'POS机编号',
`invoice_no` varchar(30) DEFAULT NULL COMMENT '发票号码',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`payment_status` tinyint NOT NULL DEFAULT '1' COMMENT '缴费状态(0:待确认,1:成功,2:失败,3:退费)',
`bill_id` bigint DEFAULT NULL COMMENT '账单ID',
`customer_id` bigint NOT NULL COMMENT '客户ID',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_payment_code` (`payment_code`, `tenant_id`),
KEY `idx_customer_payment_time` (`customer_id`, `payment_time`),
KEY `idx_payment_time` (`payment_time`),
KEY `idx_transaction_no` (`transaction_no`),
KEY `idx_operator_id` (`operator_id`),
KEY `idx_payment_status` (`payment_status`),
KEY `idx_bill_id` (`bill_id`),
CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `water_customer` (`id`),
CONSTRAINT `fk_payment_bill` FOREIGN KEY (`bill_id`) REFERENCES `water_bill` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缴费记录表';
```
### 3. 表务管理相关表DDL
#### 3.1 水表档案表
```sql
CREATE TABLE `water_meter_archive` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`archive_code` varchar(32) NOT NULL COMMENT '档案编号',
`manufacturer` varchar(100) DEFAULT NULL COMMENT '生产厂家',
`production_date` date DEFAULT NULL COMMENT '生产日期',
`valid_period` int DEFAULT '72' COMMENT '有效期(月)',
`verification_date` date DEFAULT NULL COMMENT '检定日期',
`next_verification_date` date DEFAULT NULL COMMENT '下次检定日期',
`certificate_no` varchar(50) DEFAULT NULL COMMENT '检定证书号',
`verification_agency` varchar(100) DEFAULT NULL COMMENT '检定机构',
`accuracy_level` varchar(10) DEFAULT NULL COMMENT '精度等级',
`max_flow` decimal(8,2) DEFAULT NULL COMMENT '最大流量',
`nominal_flow` decimal(8,2) DEFAULT NULL COMMENT '常用流量',
`min_flow` decimal(8,2) DEFAULT NULL COMMENT '最小流量',
`working_pressure` decimal(8,2) DEFAULT NULL COMMENT '工作压力',
`purchase_date` date DEFAULT NULL COMMENT '采购日期',
`purchase_price` decimal(10,2) DEFAULT NULL COMMENT '采购价格',
`supplier` varchar(100) DEFAULT NULL COMMENT '供应商',
`warranty_period` int DEFAULT '24' COMMENT '质保期(月)',
`installation_cost` decimal(10,2) DEFAULT NULL COMMENT '安装费用',
`archive_status` tinyint NOT NULL DEFAULT '1' COMMENT '档案状态(0:停用,1:正常,2:报废)',
`meter_id` bigint NOT NULL COMMENT '水表ID',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_archive_code` (`archive_code`, `tenant_id`),
UNIQUE KEY `uk_meter_archive` (`meter_id`, `tenant_id`),
KEY `idx_manufacturer` (`manufacturer`),
KEY `idx_verification_date` (`verification_date`),
KEY `idx_next_verification_date` (`next_verification_date`),
KEY `idx_archive_status` (`archive_status`),
CONSTRAINT `fk_archive_meter` FOREIGN KEY (`meter_id`) REFERENCES `water_meter` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='水表档案表';
```
### 4. 系统管理相关表DDL
#### 4.1 数据字典表
```sql
CREATE TABLE `water_dict_data` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`dict_type` varchar(100) NOT NULL COMMENT '字典类型',
`dict_label` varchar(100) NOT NULL COMMENT '字典标签',
`dict_value` varchar(100) NOT NULL COMMENT '字典键值',
`dict_sort` int NOT NULL DEFAULT '0' COMMENT '字典排序',
`color_type` varchar(100) DEFAULT '' COMMENT '颜色类型',
`css_class` varchar(100) DEFAULT '' COMMENT 'CSS类名',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态(0:停用,1:正常)',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户ID',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
KEY `idx_dict_type` (`dict_type`),
KEY `idx_dict_value` (`dict_value`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据字典表';
```
### 5. 初始化数据脚本
```sql
-- 插入基础字典数据
INSERT INTO `water_dict_data` (`dict_type`, `dict_label`, `dict_value`, `dict_sort`, `status`, `remark`) VALUES
('customer_type', '居民用户', 'RESIDENT', 1, 1, '居民生活用水'),
('customer_type', '非居民用户', 'NON_RESIDENT', 2, 1, '非居民用水'),
('customer_type', '工业用户', 'INDUSTRIAL', 3, 1, '工业生产用水'),
('customer_type', '行政用户', 'ADMINISTRATIVE', 4, 1, '行政事业单位用水'),
('meter_type', '机械水表', 'MECHANICAL', 1, 1, '传统机械式水表'),
('meter_type', '智能水表', 'SMART', 2, 1, '智能电子水表'),
('meter_type', '远传水表', 'REMOTE', 3, 1, '远程传输水表'),
('reading_type', '人工抄表', 'MANUAL', 1, 1, '抄表员现场抄表'),
('reading_type', '远程抄表', 'REMOTE', 2, 1, '远程自动抄表'),
('reading_type', '客户自报', 'SELF_REPORT', 3, 1, '客户自主上报'),
('reading_type', '估算抄表', 'ESTIMATE', 4, 1, '估算用水量'),
('payment_channel', '现金', 'CASH', 1, 1, '现金缴费'),
('payment_channel', '银行卡', 'BANK_CARD', 2, 1, '银行卡刷卡'),
('payment_channel', '微信支付', 'WECHAT', 3, 1, '微信在线支付'),
('payment_channel', '支付宝', 'ALIPAY', 4, 1, '支付宝在线支付'),
('payment_channel', '银行代扣', 'BANK_DEDUCT', 5, 1, '银行自动代扣');
```
## 六、OpenGauss数据库特性应用
### 1. OpenGauss高级特性
#### 1.1 分区表设计
```sql
-- 按月份分区的账单表
CREATE TABLE water_bill (
-- 字段定义...
) PARTITION BY RANGE (bill_month) (
PARTITION p202401 VALUES LESS THAN ('2024-02'),
PARTITION p202402 VALUES LESS THAN ('2024-03'),
PARTITION p202403 VALUES LESS THAN ('2024-04')
-- 继续按月创建分区...
);
```
#### 1.2 列存储表
```sql
-- 统计分析用的列存储表
CREATE TABLE water_bill_stats (
-- 字段定义...
) WITH (ORIENTATION = COLUMN);
```
#### 1.3 内存表
```sql
-- 配置参数缓存表
CREATE TABLE water_config_cache (
-- 字段定义...
) WITH (ORIENTATION = ROW, STORAGE_TYPE = USTORE);
```
### 2. 性能优化配置
#### 2.1 连接池配置
```sql
-- OpenGauss连接池参数
ALTER SYSTEM SET max_connections = 200;
ALTER SYSTEM SET shared_buffers = '256MB';
ALTER SYSTEM SET effective_cache_size = '1GB';
ALTER SYSTEM SET work_mem = '4MB';
```
#### 2.2 并行查询
```sql
-- 启用并行查询
ALTER SYSTEM SET max_parallel_workers = 8;
ALTER SYSTEM SET max_parallel_workers_per_gather = 4;
```
## 七、索引设计与优化
### 1. 基础索引设计
#### 1.1 主键索引
- 所有表使用SERIAL主键自动创建B树索引
- 支持OpenGauss的快速主键查询优化
#### 1.2 唯一索引
```sql
-- 客户编号唯一索引
CREATE UNIQUE INDEX uk_customer_code ON water_customer (customer_code, tenant_id);
-- 水表编号唯一索引
CREATE UNIQUE INDEX uk_meter_code ON water_meter (meter_code, tenant_id);
```
#### 1.3 复合索引
```sql
-- 多租户查询优化
CREATE INDEX idx_tenant_customer_type ON water_customer (tenant_id, customer_type);
-- 账单查询优化
CREATE INDEX idx_tenant_customer_month ON water_bill (tenant_id, customer_id, bill_month);
-- 抄表查询优化
CREATE INDEX idx_tenant_meter_date ON water_meter_reading (tenant_id, meter_id, reading_date);
```
### 2. OpenGauss特殊索引
#### 2.1 HASH索引
```sql
-- 等值查询优化
CREATE INDEX CONCURRENTLY idx_customer_phone_hash ON water_customer USING HASH (phone);
```
#### 2.2 GIN索引
```sql
-- 全文检索索引
CREATE INDEX idx_customer_name_gin ON water_customer USING GIN (to_tsvector('simple', customer_name));
```
#### 2.3 部分索引
```sql
-- 只对有效数据建索引
CREATE INDEX idx_active_customers ON water_customer (customer_code) WHERE deleted = FALSE AND status = 1;
```
## 八、OpenGauss数据安全设计
### 1. 内置安全特性
#### 1.1 透明数据加密 (TDE)
```sql
-- 启用表级加密
CREATE TABLE water_customer_encrypted (
-- 字段定义...
) WITH (ENCRYPTION_TYPE = 'AES_128_CTR');
-- 敏感字段加密
ALTER TABLE water_customer
ADD COLUMN id_number_encrypted BYTEA
GENERATED ALWAYS AS (gs_encrypt_aes128(id_number, '密钥')) STORED;
```
#### 1.2 行级安全策略 (RLS)
```sql
-- 创建多租户行级安全
ALTER TABLE water_customer ENABLE ROW LEVEL SECURITY;
-- 创建策略
CREATE POLICY tenant_isolation_policy ON water_customer
FOR ALL TO PUBLIC
USING (tenant_id = current_setting('app.current_tenant_id')::bigint);
```
#### 1.3 动态数据脱敏
```sql
-- 创建脱敏函数
CREATE OR REPLACE FUNCTION mask_phone(phone_no TEXT)
RETURNS TEXT AS $$
BEGIN
RETURN SUBSTRING(phone_no, 1, 3) || '****' || SUBSTRING(phone_no, 8);
END;
$$ LANGUAGE plpgsql;
-- 创建脱敏视图
CREATE VIEW water_customer_masked AS
SELECT
id, customer_code, customer_name,
mask_phone(phone) as phone_masked,
-- 其他字段...
FROM water_customer;
```
### 2. 权限控制体系
#### 2.1 角色权限设计
```sql
-- 创建业务角色
CREATE ROLE water_admin;
CREATE ROLE water_operator;
CREATE ROLE water_viewer;
-- 分配权限
GRANT ALL ON water_customer TO water_admin;
GRANT SELECT, INSERT, UPDATE ON water_customer TO water_operator;
GRANT SELECT ON water_customer_masked TO water_viewer;
```
#### 2.2 列级权限控制
```sql
-- 敏感字段权限控制
REVOKE ALL ON water_customer FROM PUBLIC;
GRANT SELECT (id, customer_name, phone) ON water_customer TO water_viewer;
GRANT SELECT ON water_customer TO water_admin;
```
### 3. 审计与监控
#### 3.1 审计日志配置
```sql
-- 启用审计
ALTER SYSTEM SET audit_enabled = on;
ALTER SYSTEM SET audit_directory = '/data/audit';
ALTER SYSTEM SET audit_file_remain_threshold = 1024;
-- 配置审计策略
SELECT pg_audit_set_policy('DDL_LOGIN_LOGOUT', 'DDL, LOGIN, LOGOUT');
SELECT pg_audit_set_policy('DML_DCL', 'DML, DCL');
```
#### 3.2 敏感操作监控
```sql
-- 创建敏感操作触发器
CREATE OR REPLACE FUNCTION audit_sensitive_data()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log (
table_name, operation, old_values, new_values,
user_name, operation_time
) VALUES (
TG_TABLE_NAME, TG_OP,
row_to_json(OLD), row_to_json(NEW),
current_user, current_timestamp
);
RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;
-- 应用到敏感表
CREATE TRIGGER audit_customer_changes
AFTER INSERT OR UPDATE OR DELETE ON water_customer
FOR EACH ROW EXECUTE FUNCTION audit_sensitive_data();
```
### 4. 数据备份与灾备
#### 4.1 OpenGauss备份策略
```sql
-- 全量备份
gs_backup -D /data/backup -h localhost -p 5432 -U backup_user
-- 增量备份
gs_backup -D /data/backup -h localhost -p 5432 -U backup_user --incremental
-- 归档日志备份
ALTER SYSTEM SET archive_mode = on;
ALTER SYSTEM SET archive_command = 'cp %p /data/archive/%f';
```
#### 4.2 主备同步配置
```sql
-- 主库配置
ALTER SYSTEM SET synchronous_standby_names = 'standby1';
ALTER SYSTEM SET synchronous_commit = on;
-- 备库配置
ALTER SYSTEM SET hot_standby = on;
ALTER SYSTEM SET max_standby_streaming_delay = 30s;
```
### 5. 国产化安全合规
#### 5.1 等保三级要求
- **身份鉴别**支持多因子认证密码复杂度策略
- **访问控制**基于角色的强制访问控制
- **安全审计**完整的操作审计和安全事件记录
- **数据完整性**数据校验和完整性保护
- **数据保密性**敏感数据加密存储和传输
#### 5.2 国产化认证
- 华为OpenGauss已通过国家密码管理局商用密码产品认证
- 支持国产SM2/SM3/SM4密码算法
- 符合网络安全法》、《数据安全法等法规要求
```sql
-- 使用国产SM4算法加密
CREATE TABLE water_customer_sm4 (
-- 字段定义...
) WITH (ENCRYPTION_TYPE = 'SM4_CTR');
```
---
# 福建水务营收系统接口设计文档
## 文档信息
| 项目信息 | 详情 |
|---------|------|
| **项目名称** | 福建水务营收系统 |
| **文档类型** | 概要设计文档 |
| **技术框架** | RuoYi-Vue-Pro + yudao-ui-admin-vue3 |
| **文档版本** | v1.0 |
| **编写日期** | 2024-12-19 |
| **文档状态** | 🟡 进行中 |
## 目录
- [1. 接口概述](#1-接口概述)
- [2. 外部接口](#2-外部接口)
- [3. 内部接口](#3-内部接口)
- [4. 接口标准](#4-接口标准)
## 1. 接口概述
福建水务业务系统提供丰富的接口,用于与外部系统集成以及系统内部各模块间的数据交换。接口设计遵循标准化、安全性、可扩展性的原则,基于RuoYi-Vue-Pro框架采用RESTful风格设计,支持JSON数据格式
### 1.1 接口设计原则
- **统一性**:所有接口遵循统一的设计规范和数据格式
- **安全性**:接口通过认证授权、参数校验等机制保障安全
- **可维护性**:接口文档完善,便于维护和升级
- **兼容性**:接口设计考虑版本兼容,支持平滑升级
- **性能优化**:接口设计考虑性能,支持缓存、分页等机制
### 1.2 RESTful API规范
系统API接口采用RESTful风格设计,主要规范如下:
#### 1.2.1 资源命名
- 使用名词复数表示资源集合,如`/users``/meters`
- 使用资源ID标识特定资源,如`/users/1``/meters/123`
- 资源层级关系通过路径嵌套表示,如`/users/1/meters`
#### 1.2.2 HTTP方法
- GET:获取资源
- POST:创建资源
- PUT:更新资源(全量更新)
- PATCH:部分更新资源
- DELETE:删除资源
#### 1.2.3 状态码
- 200 OK:请求成功
- 201 Created:资源创建成功
- 400 Bad Request:请求参数错误
- 401 Unauthorized:未授权
- 403 Forbidden:权限不足
- 404 Not Found:资源不存在
- 500 Internal Server Error:服务器内部错误
#### 1.2.4 响应格式
系统统一采用以下JSON格式响应
```json
{
"code": 0, // 业务状态码,0表示成功,非0表示失败
"data": {}, // 响应数据
"msg": "success" // 响应消息
}
```
分页查询响应格式
```json
{
"code": 0,
"data": {
"list": [], // 数据列表
"total": 100, // 总记录数
"pageNum": 1, // 当前页码
"pageSize": 10 // 每页记录数
},
"msg": "success"
}
```
### 1.3 接口文档
系统使用Knife4j基于Swagger自动生成API文档文档地址为`http://{系统地址}/doc.html`
主要特点
- 在线接口文档支持在线查看接口定义
- 接口调试支持在线调试接口
- 文档导出支持导出OpenAPI规范文档
- 权限控制支持对接口文档的访问控制
## 2. 外部接口
### 2.1 银行接口对接
#### 2.1.1 银行代扣接口
**功能描述**通过银行系统自动从用户账户中扣除水费
**接口详情**
- **接口方式**文件交换FTP/SFTP
- **数据格式**定长文本文件
- **交换频率**每日凌晨2:00
- **文件编码**GBK
**代扣文件格式**
```text
记录类型(1位) + 客户号(12位) + 户名(30位) + 银行账号(20位) + 扣款金额(12位,含2位小数) + 账期(6位) + 保留字段(19位)
```
**代扣文件示例**
```text
1C00000000001张三 62172511001234567890000009180202412
1C00000000002李四 62172511001234567891000015460202412
```
**回盘文件格式**
```text
记录类型(1位) + 客户号(12位) + 银行账号(20位) + 扣款金额(12位) + 处理状态(1位) + 银行流水号(20位) + 处理时间(14位) + 失败原因(20位)
```
**Java实现示例**
```java
@Service
public class BankDeductServiceImpl implements BankDeductService {
@Resource
private SftpTemplate sftpTemplate;
@Resource
private BillService billService;
@Scheduled(cron = "0 0 2 * * ?")
public void generateDeductFile() {
LocalDate deductDate = LocalDate.now();
// 获取待代扣账单
List<BillDO> deductBills = billService.getDeductBills(deductDate);
// 生成代扣文件
String fileName = "DEDUCT_" + deductDate.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".txt";
String fileContent = buildDeductFileContent(deductBills);
// 上传至银行SFTP
sftpTemplate.put(fileName, fileContent.getBytes(StandardCharsets.UTF_8), "/upload/");
// 记录代扣文件日志
DeductFileLogDO log = new DeductFileLogDO();
log.setFileName(fileName);
log.setFileStatus("UPLOADED");
log.setRecordCount(deductBills.size());
deductFileLogMapper.insert(log);
}
private String buildDeductFileContent(List<BillDO> bills) {
StringBuilder content = new StringBuilder();
for (BillDO bill : bills) {
content.append("1") // 记录类型
.append(StringUtils.rightPad(bill.getCustomerCode(), 12)) // 客户号
.append(StringUtils.rightPad(bill.getCustomerName(), 30)) // 户名
.append(StringUtils.rightPad(bill.getBankAccount(), 20)) // 银行账号
.append(String.format("%012d", bill.getTotalAmount().multiply(new BigDecimal(100)).intValue())) // 金额(分)
.append(bill.getBillMonth().replace("-", "")) // 账期
.append(StringUtils.repeat(" ", 19)) // 保留字段
.append("\n");
}
return content.toString();
}
}
```
#### 2.1.2 银行实时缴费接口
**功能描述**用户在银行柜台网上银行或手机银行实时缴纳水费
**接口详情**
- **接口方式**HTTP POST
- **请求URL**`https://bank.api.com/payment/water-fee`
- **数据格式**JSON
- **认证方式**API Key + 签名
**请求参数**
```json
{
"merchantId": "WATER001",
"customerCode": "C001",
"billCodes": ["B202412190001"],
"totalAmount": 91.80,
"bankAccount": "6217251100123456789",
"customerName": "张三",
"timestamp": "20241219103000",
"signature": "ABC123DEF456..."
}
```
**响应参数**
```json
{
"resultCode": "0000",
"resultMsg": "交易成功",
"data": {
"transactionId": "TXN20241219001",
"paymentTime": "20241219103001",
"bankSerial": "BNK20241219001234"
}
}
```
### 2.2 支付宝接口对接
**功能描述**用户通过支付宝缴纳水费支持扫码支付和H5支付
**接口详情**
- **接口方式**HTTP POST
- **支付方式**统一收单交易预创建alipay.trade.precreate
- **数据格式**JSON
- **认证方式**RSA2签名
**预创建支付请求参数**
```json
{
"app_id": "2021001234567890",
"method": "alipay.trade.precreate",
"charset": "UTF-8",
"sign_type": "RSA2",
"timestamp": "2024-12-19 10:30:00",
"version": "1.0",
"notify_url": "https://water.example.com/api/payment/alipay/notify",
"biz_content": {
"out_trade_no": "P202412190002",
"total_amount": "91.80",
"subject": "水费缴费",
"body": "2024年12月水费-客户编号:C001",
"store_id": "WATER_STORE_001",
"timeout_express": "30m"
}
}
```
**支付宝响应参数**
```json
{
"alipay_trade_precreate_response": {
"code": "10000",
"msg": "Success",
"out_trade_no": "P202412190002",
"qr_code": "https://qr.alipay.com/bax08945xtdnfwgqmwi200b4"
},
"sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE"
}
```
**Java实现示例**
```java
@Service
public class AlipayServiceImpl implements AlipayService {
@Resource
private AlipayClient alipayClient;
@Override
public AlipayPaymentRespVO createPayment(AlipayPaymentReqVO request) {
AlipayTradePrecreateRequest alipayRequest = new AlipayTradePrecreateRequest();
alipayRequest.setNotifyUrl("https://water.example.com/api/payment/alipay/notify");
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setOutTradeNo(request.getPaymentCode());
model.setTotalAmount(request.getTotalAmount().toString());
model.setSubject("水费缴费");
model.setBody("账单号:" + String.join(",", request.getBillCodes()));
model.setTimeoutExpress("30m");
alipayRequest.setBizModel(model);
try {
AlipayTradePrecreateResponse response = alipayClient.execute(alipayRequest);
if (response.isSuccess()) {
return AlipayPaymentRespVO.builder()
.paymentCode(request.getPaymentCode())
.qrCode(response.getQrCode())
.outTradeNo(response.getOutTradeNo())
.build();
} else {
throw new BizException(ALIPAY_PAY_FAILED, response.getSubMsg());
}
} catch (AlipayApiException e) {
throw new BizException(ALIPAY_PAY_ERROR, e.getErrMsg());
}
}
}
```
### 2.3 微信支付接口对接
**功能描述**用户通过微信支付缴纳水费支持扫码支付和小程序支付
**接口详情**
- **接口方式**HTTP POST
- **支付方式**Native支付扫码/ JSAPI支付小程序
- **请求URL**`https://api.mch.weixin.qq.com/v3/pay/transactions/native`
- **数据格式**JSON
- **认证方式**微信支付V3签名
**统一下单请求参数**
```json
{
"appid": "wx8888888888888888",
"mchid": "1900000109",
"description": "水费缴费-2024年12月",
"out_trade_no": "P202412190003",
"notify_url": "https://water.example.com/api/payment/wechat/notify",
"amount": {
"total": 9180,
"currency": "CNY"
},
"attach": "客户编号:C001,账单号:B202412190001",
"goods_tag": "WATER_FEE",
"time_expire": "2024-12-19T11:00:00+08:00"
}
```
**微信支付响应参数**
```json
{
"code_url": "weixin://wxpay/bizpayurl?pr=HuaLcAKwa"
}
```
**支付结果通知参数**
```json
{
"id": "EV-2018022511223320873",
"create_time": "2024-12-19T10:30:00+08:00",
"resource_type": "encrypt-resource",
"event_type": "TRANSACTION.SUCCESS",
"summary": "支付成功",
"resource": {
"original_type": "transaction",
"algorithm": "AEAD_AES_256_GCM",
"ciphertext": "...",
"associated_data": "transaction",
"nonce": "..."
}
}
```
### 2.4 短信接口
**功能描述**向用户发送各类业务通知短信
**接口规范**
- 接口方式HTTP接口
- 数据格式JSON
- 交换频率实时
### 2.5 物联网集抄平台接口
**功能描述**与物联网集抄平台交互获取智能水表数据
**接口规范**
- 接口方式HTTP接口或WebService
- 数据格式JSON或XML
- 交换频率定时或实时
## 3. 内部接口
### 3.1 客户管理API接口
#### 3.1.1 客户信息查询接口
**功能描述**根据客户ID查询客户详细信息
**接口详情**
- **请求方式**GET
- **请求路径**`/admin-api/water/customer/{id}`
- **请求头**`Authorization: Bearer {token}`
**请求参数**
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|-------|------|------|------|------|
| id | Long | | 客户ID | 1 |
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": {
"id": 1,
"customerCode": "C001",
"customerName": "张三",
"customerType": "RESIDENT",
"phone": "13800138000",
"address": "福建省福州市台江区XX街道XX号",
"status": 1,
"createTime": "2024-12-19 10:00:00"
}
}
```
**RuoYi-Vue-Pro代码示例**
```java
@RestController
@RequestMapping("/admin-api/water/customer")
@Tag(name = "管理后台 - 客户管理")
@Validated
public class CustomerController {
@Resource
private CustomerService customerService;
@GetMapping("/{id}")
@Operation(summary = "获得客户")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('water:customer:query')")
public CommonResult<CustomerRespVO> getCustomer(@PathVariable("id") Long id) {
CustomerDO customer = customerService.getCustomer(id);
return success(BeanUtils.toBean(customer, CustomerRespVO.class));
}
}
```
#### 3.1.2 客户分页查询接口
**功能描述**分页查询客户列表信息
**接口详情**
- **请求方式**GET
- **请求路径**`/admin-api/water/customer/page`
**请求参数**
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|-------|------|------|------|------|
| pageNo | Integer | | 页码默认1 | 1 |
| pageSize | Integer | | 每页条数默认10 | 10 |
| customerName | String | | 客户名称 | 张三 |
| customerCode | String | | 客户编号 | C001 |
| customerType | String | | 客户类型 | RESIDENT |
| phone | String | | 联系电话 | 138 |
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": {
"list": [
{
"id": 1,
"customerCode": "C001",
"customerName": "张三",
"customerType": "RESIDENT",
"phone": "13800138000",
"address": "福建省福州市台江区XX街道XX号",
"status": 1,
"createTime": "2024-12-19 10:00:00"
}
],
"total": 1
}
}
```
#### 3.1.3 客户创建接口
**功能描述**创建新客户记录
**接口详情**
- **请求方式**POST
- **请求路径**`/admin-api/water/customer/create`
**请求参数**
```json
{
"customerCode": "C002",
"customerName": "李四",
"customerType": "RESIDENT",
"idType": "ID_CARD",
"idNumber": "350103199001011234",
"phone": "13900139000",
"address": "福建省福州市鼓楼区XX街道XX号"
}
```
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": 2
}
```
**Service层代码示例**
```java
@Service
@Validated
public class CustomerServiceImpl implements CustomerService {
@Resource
private CustomerMapper customerMapper;
@Override
public Long createCustomer(CustomerSaveReqVO createReqVO) {
// 校验客户编号唯一性
validateCustomerCodeUnique(createReqVO.getCustomerCode());
// 创建客户
CustomerDO customer = BeanUtils.toBean(createReqVO, CustomerDO.class);
customerMapper.insert(customer);
return customer.getId();
}
private void validateCustomerCodeUnique(String customerCode) {
CustomerDO existCustomer = customerMapper.selectByCustomerCode(customerCode);
if (existCustomer != null) {
throw exception(CUSTOMER_CODE_DUPLICATE);
}
}
}
```
### 3.2 水表管理API接口
#### 3.2.1 水表信息查询接口
**功能描述**根据水表ID查询水表详细信息
**接口详情**
- **请求方式**GET
- **请求路径**`/admin-api/water/meter/{id}`
- **请求头**`Authorization: Bearer {token}`
**请求参数**
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|-------|------|------|------|------|
| id | Long | | 水表ID | 1 |
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": {
"id": 1,
"meterCode": "M001",
"meterNo": "20241219001",
"meterType": "SMART",
"meterModel": "LXSY-15E",
"meterCaliber": "15mm",
"installDate": "2024-01-15",
"installPosition": "1层水表井",
"initialReading": 0.00,
"currentReading": 156.32,
"readingCycle": "MONTHLY",
"meterStatus": 1,
"customerId": 1,
"customerName": "张三"
}
}
```
**Controller代码示例**
```java
@RestController
@RequestMapping("/admin-api/water/meter")
@Tag(name = "管理后台 - 水表管理")
@Validated
public class MeterController {
@Resource
private MeterService meterService;
@GetMapping("/{id}")
@Operation(summary = "获得水表")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('water:meter:query')")
public CommonResult<MeterRespVO> getMeter(@PathVariable("id") Long id) {
MeterDO meter = meterService.getMeter(id);
return success(BeanUtils.toBean(meter, MeterRespVO.class));
}
}
```
#### 3.2.2 抄表记录创建接口
**功能描述**创建新的抄表记录
**接口详情**
- **请求方式**POST
- **请求路径**`/admin-api/water/reading/create`
**请求参数**
```json
{
"meterId": 1,
"readingDate": "2024-12-19",
"readingValue": 156.32,
"readingType": "MANUAL",
"readerId": "R001",
"photoUrl": "https://example.com/photos/reading001.jpg",
"remark": "正常抄表"
}
```
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": 1
}
```
**Service层实现示例**
```java
@Service
@Validated
public class MeterReadingServiceImpl implements MeterReadingService {
@Resource
private MeterReadingMapper readingMapper;
@Resource
private MeterService meterService;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createReading(MeterReadingSaveReqVO createReqVO) {
// 校验水表存在性
MeterDO meter = meterService.validateMeterExists(createReqVO.getMeterId());
// 校验读数合理性
validateReadingValue(createReqVO.getMeterId(), createReqVO.getReadingValue());
// 创建抄表记录
MeterReadingDO reading = BeanUtils.toBean(createReqVO, MeterReadingDO.class);
reading.setReadingCode(generateReadingCode());
reading.setCustomerId(meter.getCustomerId());
// 计算用水量
BigDecimal waterUsage = calculateWaterUsage(meter.getCurrentReading(),
createReqVO.getReadingValue());
reading.setWaterUsage(waterUsage);
readingMapper.insert(reading);
// 更新水表当前读数
meterService.updateCurrentReading(createReqVO.getMeterId(),
createReqVO.getReadingValue());
return reading.getId();
}
}
```
#### 3.2.3 抄表数据批量导入接口
**功能描述**批量导入抄表数据支持Excel文件上传
**接口详情**
- **请求方式**POST
- **请求路径**`/admin-api/water/reading/import`
- **Content-Type**`multipart/form-data`
**请求参数**
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|-------|------|------|------|------|
| file | MultipartFile | | Excel文件 | reading_data.xlsx |
| updateSupport | Boolean | | 是否更新已有数据 | false |
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": {
"successCount": 95,
"failureCount": 5,
"failureList": [
{
"lineNumber": 3,
"meterCode": "M003",
"errorMsg": "水表不存在"
}
]
}
}
```
### 3.3 账单管理API接口
#### 3.3.1 账单查询接口
**功能描述**根据客户ID和查询条件查询账单信息
**接口详情**
- **请求方式**GET
- **请求路径**`/admin-api/water/bill/page`
**请求参数**
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|-------|------|------|------|------|
| pageNo | Integer | | 页码默认1 | 1 |
| pageSize | Integer | | 每页条数默认10 | 10 |
| customerId | Long | | 客户ID | 1 |
| billMonth | String | | 账期 | 2024-12 |
| billStatus | Integer | | 账单状态 | 0 |
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": {
"list": [
{
"id": 1,
"billCode": "B202412190001",
"billMonth": "2024-12",
"billDate": "2024-12-19",
"waterUsage": 25.50,
"waterFee": 76.50,
"sewageFee": 15.30,
"totalAmount": 91.80,
"paidAmount": 0.00,
"balanceAmount": 91.80,
"dueDate": "2025-01-19",
"billStatus": 0,
"customerName": "张三",
"meterCode": "M001"
}
],
"total": 1
}
}
```
#### 3.3.2 账单生成接口
**功能描述**根据抄表记录生成水费账单
**接口详情**
- **请求方式**POST
- **请求路径**`/admin-api/water/bill/generate`
**请求参数**
```json
{
"billMonth": "2024-12",
"customerIds": [1, 2, 3],
"readingIds": [1, 2, 3],
"dueDate": "2025-01-19"
}
```
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": {
"generateCount": 3,
"successList": [
{
"customerId": 1,
"billId": 1,
"totalAmount": 91.80
}
],
"failureList": []
}
}
```
**Service层代码示例**
```java
@Service
@Validated
public class BillServiceImpl implements BillService {
@Resource
private BillMapper billMapper;
@Resource
private MeterReadingService readingService;
@Resource
private WaterPriceService priceService;
@Override
@Transactional(rollbackFor = Exception.class)
public BillGenerateRespVO generateBills(BillGenerateReqVO generateReqVO) {
BillGenerateRespVO result = new BillGenerateRespVO();
List<BillGenerateDetailVO> successList = new ArrayList<>();
List<BillGenerateDetailVO> failureList = new ArrayList<>();
for (Long readingId : generateReqVO.getReadingIds()) {
try {
// 获取抄表记录
MeterReadingDO reading = readingService.getReading(readingId);
// 计算水费
WaterFeeCalculateDTO feeResult = priceService.calculateWaterFee(
reading.getCustomerId(), reading.getWaterUsage());
// 创建账单
BillDO bill = new BillDO();
bill.setBillCode(generateBillCode());
bill.setBillMonth(generateReqVO.getBillMonth());
bill.setCustomerId(reading.getCustomerId());
bill.setMeterId(reading.getMeterId());
bill.setReadingId(readingId);
bill.setWaterUsage(reading.getWaterUsage());
bill.setWaterFee(feeResult.getWaterFee());
bill.setSewageFee(feeResult.getSewageFee());
bill.setTotalAmount(feeResult.getTotalAmount());
bill.setDueDate(generateReqVO.getDueDate());
billMapper.insert(bill);
successList.add(buildSuccessDetail(reading.getCustomerId(),
bill.getId(), feeResult.getTotalAmount()));
} catch (Exception e) {
failureList.add(buildFailureDetail(readingId, e.getMessage()));
}
}
result.setGenerateCount(successList.size());
result.setSuccessList(successList);
result.setFailureList(failureList);
return result;
}
}
```
### 3.4 缴费管理API接口
#### 3.4.1 缴费处理接口
**功能描述**处理客户缴费操作
**接口详情**
- **请求方式**POST
- **请求路径**`/admin-api/water/payment/create`
**请求参数**
```json
{
"customerId": 1,
"billIds": [1, 2],
"paymentType": "NORMAL",
"paymentChannel": "CASH",
"paymentAmount": 183.60,
"actualAmount": 200.00,
"operatorId": "OP001",
"outletCode": "OUT001",
"remark": "现金缴费"
}
```
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": {
"paymentId": 1,
"paymentCode": "P202412190001",
"changeAmount": 16.40,
"invoiceNo": "INV20241219001"
}
}
```
#### 3.4.2 在线支付接口
**功能描述**处理在线支付微信支付宝等)。
**接口详情**
- **请求方式**POST
- **请求路径**`/admin-api/water/payment/online-pay`
**请求参数**
```json
{
"customerId": 1,
"billIds": [1],
"paymentChannel": "WECHAT",
"paymentAmount": 91.80,
"returnUrl": "https://water.example.com/payment/callback",
"notifyUrl": "https://water.example.com/api/payment/notify"
}
```
**响应参数**
```json
{
"code": 0,
"msg": "操作成功",
"data": {
"paymentCode": "P202412190002",
"prepayId": "wx20241219001234567890",
"payUrl": "weixin://wxpay/bizpayurl?pr=abc123",
"qrCode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
}
```
### 3.4 工单接口
#### 3.4.1 工单创建接口
**功能描述**创建业务工单
**接口规范**
- 请求方式POST
- 请求路径/api/workorders
- 请求/返回格式JSON
#### 3.4.2 工单状态更新接口
**功能描述**更新工单处理状态
**接口规范**
- 请求方式PUT
- 请求路径/api/workorders/{workorderId}/status
- 请求/返回格式JSON
## 4. 接口标准
### 4.1 接口协议
系统接口主要采用以下协议
- **RESTful API**适用于系统内部模块间的交互以及移动应用等轻量级客户端
- **WebService**适用于与外部系统的集成特别是银行等传统机构
- **消息队列**适用于异步处理的场景如批量数据处理通知推送等
### 4.2 数据格式
接口数据主要采用以下格式
- **JSON**主要用于RESTful API接口结构简单清晰适合Web应用
- **XML**主要用于WebService接口兼容性好适合与传统系统对接
- **文本文件**主要用于批量数据交换如银行代扣文件等
### 4.3 接口安全设计
接口安全采用多层防护机制
#### 4.3.1 认证机制
**JWT令牌认证**
```java
@RestController
public class AuthController {
@Resource
private AuthService authService;
@PostMapping("/admin-api/system/auth/login")
public CommonResult<AuthLoginRespVO> login(@Valid @RequestBody AuthLoginReqVO reqVO) {
// 验证用户名密码
AdminUserDO user = authService.authenticate(reqVO.getUsername(), reqVO.getPassword());
// 生成JWT Token
String token = authService.createToken(user.getId(), user.getTenantId());
return success(AuthLoginRespVO.builder()
.userId(user.getId())
.accessToken(token)
.refreshToken(authService.createRefreshToken(user.getId()))
.expiresTime(LocalDateTime.now().plusHours(2))
.build());
}
}
```
**API Key认证**外部系统
```java
@Component
public class ApiKeyAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String apiKey = request.getHeader("X-API-KEY");
String timestamp = request.getHeader("X-TIMESTAMP");
String signature = request.getHeader("X-SIGNATURE");
// 验证API Key
if (!apiKeyService.validateApiKey(apiKey)) {
writeErrorResponse(response, "Invalid API Key");
return;
}
// 验证时间戳(防重放攻击)
if (!validateTimestamp(timestamp)) {
writeErrorResponse(response, "Request expired");
return;
}
// 验证签名
if (!validateSignature(request, signature)) {
writeErrorResponse(response, "Invalid signature");
return;
}
filterChain.doFilter(request, response);
}
}
```
#### 4.3.2 数据加密
**敏感数据加密**
```java
@Component
public class DataEncryptionService {
private final AESUtil aesUtil;
public String encryptPersonalInfo(String plainText) {
if (StrUtil.isBlank(plainText)) {
return plainText;
}
return aesUtil.encrypt(plainText);
}
public String decryptPersonalInfo(String cipherText) {
if (StrUtil.isBlank(cipherText)) {
return cipherText;
}
return aesUtil.decrypt(cipherText);
}
}
```
#### 4.3.3 访问控制
**IP白名单控制**
```java
@Component
public class IpWhitelistFilter extends OncePerRequestFilter {
@Value("${water.security.ip-whitelist}")
private List<String> ipWhitelist;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String clientIp = getClientIpAddress(request);
if (!isIpAllowed(clientIp)) {
response.setStatus(HttpStatus.FORBIDDEN.value());
response.getWriter().write("{\"code\":403,\"msg\":\"IP access denied\"}");
return;
}
filterChain.doFilter(request, response);
}
}
```
#### 4.3.4 接口限流
**基于Redis的令牌桶限流**
```java
@Component
public class RateLimitService {
@Resource
private StringRedisTemplate redisTemplate;
public boolean allowRequest(String key, int maxRequests, Duration window) {
String redisKey = "rate_limit:" + key;
String script = """
local key = KEYS[1]
local window = tonumber(ARGV[1])
local limit = tonumber(ARGV[2])
local current = redis.call('get', key)
if current == false then
redis.call('setex', key, window, 1)
return 1
end
if tonumber(current) < limit then
return redis.call('incr', key)
else
return 0
end
""";
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
Long result = redisTemplate.execute(redisScript,
Collections.singletonList(redisKey),
String.valueOf(window.getSeconds()),
String.valueOf(maxRequests));
return result != null && result > 0;
}
}
```
### 4.4 错误处理机制
#### 4.4.1 统一异常处理
```java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ServiceException.class)
public CommonResult<?> serviceExceptionHandler(ServiceException ex) {
log.info("[serviceExceptionHandler]", ex);
return CommonResult.error(ex.getCode(), ex.getMessage());
}
@ExceptionHandler(ConstraintViolationException.class)
public CommonResult<?> constraintViolationExceptionHandler(ConstraintViolationException ex) {
log.info("[constraintViolationExceptionHandler]", ex);
return CommonResult.error(BAD_REQUEST.getCode(), "请求参数不正确:" + ex.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public CommonResult<?> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex) {
log.info("[methodArgumentNotValidExceptionHandler]", ex);
FieldError fieldError = ex.getBindingResult().getFieldError();
assert fieldError != null;
return CommonResult.error(BAD_REQUEST.getCode(), "请求参数不正确:" + fieldError.getDefaultMessage());
}
}
```
#### 4.4.2 错误码定义
```java
public interface ErrorCodeConstants {
// ========== 通用错误码 1-000-000-000 ==========
ErrorCode SUCCESS = new ErrorCode(0, "成功");
ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确");
ErrorCode UNAUTHORIZED = new ErrorCode(401, "账号未登录");
ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限");
ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到");
ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常");
// ========== 客户管理错误码 1-001-000-000 ==========
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_001_000_001, "客户不存在");
ErrorCode CUSTOMER_CODE_DUPLICATE = new ErrorCode(1_001_000_002, "客户编号已存在");
ErrorCode CUSTOMER_STATUS_INVALID = new ErrorCode(1_001_000_003, "客户状态不正确");
// ========== 水表管理错误码 1-002-000-000 ==========
ErrorCode METER_NOT_EXISTS = new ErrorCode(1_002_000_001, "水表不存在");
ErrorCode METER_CODE_DUPLICATE = new ErrorCode(1_002_000_002, "水表编号已存在");
ErrorCode METER_READING_INVALID = new ErrorCode(1_002_000_003, "水表读数不正确");
// ========== 账单管理错误码 1-003-000-000 ==========
ErrorCode BILL_NOT_EXISTS = new ErrorCode(1_003_000_001, "账单不存在");
ErrorCode BILL_ALREADY_PAID = new ErrorCode(1_003_000_002, "账单已缴费");
ErrorCode BILL_AMOUNT_INVALID = new ErrorCode(1_003_000_003, "账单金额不正确");
// ========== 缴费管理错误码 1-004-000-000 ==========
ErrorCode PAYMENT_FAILED = new ErrorCode(1_004_000_001, "缴费失败");
ErrorCode PAYMENT_AMOUNT_INSUFFICIENT = new ErrorCode(1_004_000_002, "缴费金额不足");
ErrorCode PAYMENT_CHANNEL_UNAVAILABLE = new ErrorCode(1_004_000_003, "缴费渠道不可用");
}
```
#### 4.4.3 接口调用示例
**成功响应示例**
```json
{
"code": 0,
"msg": "操作成功",
"data": {
"id": 1,
"customerName": "张三"
}
}
```
**失败响应示例**
```json
{
"code": 1001000001,
"msg": "客户不存在",
"data": null
}
```
### 4.5 前端接口调用示例
#### 4.5.1 Vue3 + TypeScript接口封装
```typescript
// api/water/customer.ts
import { request } from '@/utils/request'
export interface CustomerVO {
id: number
customerCode: string
customerName: string
customerType: string
phone: string
address: string
status: number
createTime: string
}
export interface CustomerPageReqVO extends PageParam {
customerName?: string
customerCode?: string
customerType?: string
phone?: string
}
export const CustomerApi = {
// 获取客户分页
getCustomerPage: (params: CustomerPageReqVO) => {
return request.get<PageResult<CustomerVO>>({ url: '/water/customer/page', params })
},
// 获取客户详情
getCustomer: (id: number) => {
return request.get<CustomerVO>({ url: `/water/customer/${id}` })
},
// 创建客户
createCustomer: (data: CustomerSaveReqVO) => {
return request.post<number>({ url: '/water/customer/create', data })
},
// 更新客户
updateCustomer: (data: CustomerSaveReqVO) => {
return request.put<void>({ url: '/water/customer/update', data })
},
// 删除客户
deleteCustomer: (id: number) => {
return request.delete<void>({ url: `/water/customer/delete?id=${id}` })
}
}
```
#### 4.5.2 Vue组件使用示例
```vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { CustomerApi, CustomerVO } from '@/api/water/customer'
import { formatDate } from '@/utils/formatTime'
const customerList = ref<CustomerVO[]>([])
const loading = ref(true)
const total = ref(0)
const queryParams = ref({
pageNo: 1,
pageSize: 10,
customerName: '',
customerCode: ''
})
const getCustomerList = async () => {
loading.value = true
try {
const data = await CustomerApi.getCustomerPage(queryParams.value)
customerList.value = data.list
total.value = data.total
} catch (error) {
console.error('获取客户列表失败:', error)
} finally {
loading.value = false
}
}
const handleQuery = () => {
queryParams.value.pageNo = 1
getCustomerList()
}
const handleReset = () => {
queryParams.value = {
pageNo: 1,
pageSize: 10,
customerName: '',
customerCode: ''
}
getCustomerList()
}
onMounted(() => {
getCustomerList()
})
</script>
<template>
<div class="app-container">
<!-- 查询表单 -->
<el-form :model="queryParams" ref="queryFormRef" inline>
<el-form-item label="客户名称" prop="customerName">
<el-input v-model="queryParams.customerName" placeholder="请输入客户名称" />
</el-form-item>
<el-form-item label="客户编号" prop="customerCode">
<el-input v-model="queryParams.customerCode" placeholder="请输入客户编号" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
<!-- 数据表格 -->
<el-table v-loading="loading" :data="customerList">
<el-table-column label="客户编号" prop="customerCode" />
<el-table-column label="客户名称" prop="customerName" />
<el-table-column label="联系电话" prop="phone" />
<el-table-column label="创建时间" prop="createTime" :formatter="formatDate" />
</el-table>
<!-- 分页组件 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getCustomerList"
/>
</div>
</template>
```
---
# 福建水务营收系统部署设计文档
## 文档信息
| 项目信息 | 详情 |
|---------|------|
| **项目名称** | 福建水务营收系统 |
| **文档类型** | 概要设计文档 |
| **技术框架** | RuoYi-Vue-Pro + yudao-ui-admin-vue3 |
| **文档版本** | v1.0 |
| **编写日期** | 2024-12-19 |
| **文档状态** | ✅ 已完成 |
## 目录
- [1. 部署概述](#1-部署概述)
- [2. 部署架构](#2-部署架构)
- [3. 服务器配置](#3-服务器配置)
- [4. 网络架构](#4-网络架构)
- [5. 安全设计](#5-安全设计)
- [6. 部署流程](#6-部署流程)
- [7. 监控与运维](#7-监控与运维)
## 1. 部署概述
福建水务业务系统采用集中化部署模式,基于集团私有云环境进行部署,构建高可用、可扩展的系统架构,满足集团及下属各水务公司的业务需求。
### 1.1 部署目标
- 实现系统的集中部署和统一管理
- 确保系统高可用性和可靠性
- 支持业务动态扩展和弹性伸缩
- 保障数据安全和业务连续性
- 降低运维成本,提高管理效率
### 1.2 部署原则
- **集中部署**:核心业务系统集中部署在集团数据中心,统一管理和维护
- **多级架构**:采用多级架构设计,实现前端负载分担和后端高可用
- **灾备设计**:重要系统和数据实现灾备,确保业务连续性
- **安全防护**:多层次安全防护体系,确保系统和数据安全
- **弹性扩展**:支持系统横向和纵向扩展,适应业务增长需求
## 2. 部署架构
### 2.1 总体部署架构
福建水务业务系统采用三层架构部署:
- **接入层**:负责外部访问请求的接入和负载均衡
- **应用层**:部署业务应用服务,处理业务逻辑
- **数据层**:部署数据库服务,存储业务数据
系统部署采用集群模式,各层均部署多个节点,实现高可用和负载均衡。
### 2.2 生产环境部署架构
生产环境采用双机房部署方案,包括主生产环境和灾备环境:
#### 2.2.1 主生产环境
主生产环境部署在集团主数据中心,包括:
- 负载均衡集群2台负载均衡服务器
- Web服务器集群4台Web服务器
- 应用服务器集群6台应用服务器
- 数据库服务器集群2台主备数据库服务器
- 文件服务器2台主备文件服务器
- 缓存服务器集群2台缓存服务器
#### 2.2.2 灾备环境
灾备环境部署在集团备用数据中心,包括:
- 负载均衡服务器1台
- Web服务器2台
- 应用服务器3台
- 数据库服务器1台
- 文件服务器1台
- 缓存服务器1台
### 2.3 测试环境部署架构
测试环境部署在集团测试中心,用于系统测试和验证,包括:
- Web服务器1台
- 应用服务器2台
- 数据库服务器1台
- 文件服务器1台
### 2.4 开发环境部署架构
开发环境部署在开发中心,用于系统开发和集成测试,包括:
- 应用服务器1台
- 数据库服务器1台
## 3. 服务器配置
### 3.1 硬件配置要求
#### 3.1.1 负载均衡服务器
- CPU8核
- 内存16GB
- 存储100GB SSD
- 网卡:双千兆网卡
#### 3.1.2 Web服务器
- CPU8核
- 内存16GB
- 存储200GB SSD
- 网卡:双千兆网卡
#### 3.1.3 应用服务器
- CPU16核
- 内存32GB
- 存储300GB SSD
- 网卡:双千兆网卡
#### 3.1.4 数据库服务器
- CPU24核
- 内存64GB
- 存储2TB SSD (RAID 10)
- 网卡:双万兆网卡
#### 3.1.5 文件服务器
- CPU8核
- 内存16GB
- 存储4TB (RAID 5)
- 网卡:双千兆网卡
#### 3.1.6 缓存服务器
- CPU8核
- 内存32GB
- 存储100GB SSD
- 网卡:双千兆网卡
### 3.2 软件配置要求
#### 3.2.1 操作系统
- 服务端CentOS 7+、Ubuntu 18.04+或其他国产Linux发行版
- 客户端支持Windows、macOS、Linux等现代操作系统
#### 3.2.2 数据库
- OpenGauss 5.0+(推荐,国产自主可控)
- 兼容PostgreSQL 13+、MySQL 8.0+
#### 3.2.3 应用服务器
- JDK 17或JDK 21兼容支持JDK 8
- Apache Tomcat 9.0+或内嵌Tomcat
- Nginx 1.18+(作为前端静态资源服务器和反向代理)
#### 3.2.4 缓存服务器
- Redis 5.0+或Redis集群
#### 3.2.5 中间件
- 消息队列基于Redis的轻量级队列可选
- 分布式任务调度Quartz集群
- 工作流引擎Flowable 6.x
- 文件存储支持本地存储、MinIO、阿里云OSS等
#### 3.2.6 前端环境
- Node.js 16+
- NPM 8+或Yarn 1.22+
- Vue 3.x
- Element Plus
## 4. 网络架构
### 4.1 网络拓扑
福建水务业务系统网络架构采用三层网络结构:
- **接入层**:对外提供服务接入,部署防火墙、负载均衡等设备
- **核心层**:实现业务系统间的互联互通,部署核心交换机
- **服务层**:部署各类服务器,实现业务处理和数据存储
### 4.2 网络安全区域划分
网络安全区域划分为以下几个区域:
- **DMZ区**部署面向外部的Web服务器与内网隔离
- **应用区**:部署业务应用服务器
- **数据区**:部署数据库服务器和文件服务器
- **管理区**:部署运维管理服务器
### 4.3 网络带宽配置
- 外网接入带宽100Mbps根据实际需求可升级
- 内网骨干带宽1000Mbps
- 服务器接入带宽1000Mbps
- 数据中心间专线带宽100Mbps
## 5. 安全设计
### 5.1 网络安全
#### 5.1.1 边界安全
- 部署高性能防火墙,实现网络隔离
- 部署入侵检测系统(IDS)和入侵防御系统(IPS)
- 部署Web应用防火墙(WAF)防御Web应用攻击
- 采用VPN技术保障远程访问安全
#### 5.1.2 内网安全
- 网络安全区域划分,实现不同级别网络隔离
- 内网访问控制,限制不必要的网络访问
- 内网流量监控,及时发现异常流量
### 5.2 系统安全
#### 5.2.1 主机安全
- 操作系统安全加固,关闭不必要的服务和端口
- 系统补丁及时更新,修复安全漏洞
- 部署主机防病毒软件,防御恶意代码
- 主机审计和日志管理,记录重要操作
#### 5.2.2 应用安全
- 应用访问控制,基于角色的权限管理
- 应用操作审计,记录重要业务操作
- 数据传输加密,保护敏感信息
- 输入验证防止SQL注入、XSS等攻击
### 5.3 数据安全
#### 5.3.1 数据存储安全
- 数据库访问控制,限制数据库访问权限
- 敏感数据加密存储,防止数据泄露
- 数据库审计,记录重要数据操作
#### 5.3.2 数据备份与恢复
- 定期数据备份,每日增量备份,每周全量备份
- 备份数据异地存储,防止灾难性事件导致数据丢失
- 定期演练数据恢复,确保备份数据可用
## 6. 部署流程
### 6.1 部署准备
- 服务器硬件准备和上架
- 网络环境配置和测试
- 操作系统安装和配置
- 基础软件安装和配置
### 6.2 应用部署
#### 6.2.1 数据库部署
- 数据库服务器配置
- 数据库实例创建和配置
- 数据库高可用配置
- 数据备份策略配置
#### 6.2.2 应用服务部署
- 应用服务器配置
- 应用程序部署
- 应用服务参数配置
- 应用服务高可用配置
#### 6.2.3 Web服务部署
- Web服务器配置
- Web应用部署
- Web服务参数配置
- 负载均衡配置
### 6.3 系统联调
- 各组件功能测试
- 系统整体联调测试
- 性能和压力测试
- 高可用性测试
### 6.4 系统上线
- 制定上线计划
- 系统割接准备
- 系统割接实施
- 系统运行监控
## 7. 监控与运维
### 7.1 监控系统
#### 7.1.1 基础设施监控
- 服务器硬件监控CPU、内存、磁盘、网络等
- 网络设备监控:带宽使用率、连接状态等
- 操作系统监控:系统负载、进程状态等
#### 7.1.2 应用监控
- 应用服务状态监控
- 应用性能监控:响应时间、并发数等
- 业务监控:重要业务指标监控
#### 7.1.3 数据库监控
- 数据库服务状态监控
- 数据库性能监控CPU使用率、内存使用率、IO性能等
- SQL执行监控慢查询、锁等待等
### 7.2 运维管理
#### 7.2.1 日常运维
- 系统日常巡检
- 系统性能优化
- 系统容量管理
- 系统备份管理
#### 7.2.2 变更管理
- 变更申请和审批
- 变更实施和验证
- 变更回退预案
- 变更记录管理
#### 7.2.3 故障管理
- 故障监控和告警
- 故障处理流程
- 故障升级机制
- 故障复盘和改进
#### 7.2.4 应急预案
- 系统宕机应急预案
- 网络故障应急预案
- 数据丢失应急预案
- 安全事件应急预案
## 8. 容器化部署方案
### 8.1 Docker Compose部署
#### 8.1.1 完整部署配置
```yaml
# docker-compose.yml
version: '3.8'
services:
# OpenGauss 数据库
water-opengauss:
image: enmotech/opengauss:5.0.0
container_name: water-opengauss
restart: always
environment:
GS_PASSWORD: "Water@2024"
GS_DB: "ruoyi_water"
GS_USERNAME: "water_user"
TZ: "Asia/Shanghai"
volumes:
- ./data/opengauss:/var/lib/opengauss
- ./sql:/docker-entrypoint-initdb.d
- ./config/opengauss:/opt/opengauss/config
ports:
- "5432:5432"
networks:
- water-network
healthcheck:
test: ["CMD-SHELL", "gs_ctl status -D /var/lib/opengauss/data"]
interval: 30s
timeout: 10s
retries: 3
# Redis 缓存
water-redis:
image: redis:7.0-alpine
container_name: water-redis
restart: always
volumes:
- ./data/redis:/data
- ./config/redis/redis.conf:/etc/redis/redis.conf
ports:
- "6379:6379"
command: redis-server /etc/redis/redis.conf
networks:
- water-network
# 后端应用
water-server:
build:
context: ./water-server
dockerfile: Dockerfile
container_name: water-server
restart: always
depends_on:
- water-opengauss
- water-redis
environment:
- SPRING_PROFILES_ACTIVE=prod
- SPRING_DATASOURCE_URL=jdbc:opengauss://water-opengauss:5432/ruoyi_water?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
- SPRING_DATASOURCE_USERNAME=water_user
- SPRING_DATASOURCE_PASSWORD=Water@2024
- SPRING_REDIS_HOST=water-redis
- SPRING_REDIS_PORT=6379
- SERVER_PORT=8080
volumes:
- ./logs:/app/logs
- ./upload:/app/upload
ports:
- "8080:8080"
networks:
- water-network
# 前端应用
water-ui:
build:
context: ./water-ui
dockerfile: Dockerfile
container_name: water-ui
restart: always
depends_on:
- water-server
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./config/nginx/conf.d:/etc/nginx/conf.d
ports:
- "80:80"
- "443:443"
networks:
- water-network
# Nginx 反向代理
water-nginx:
image: nginx:1.24-alpine
container_name: water-nginx
restart: always
depends_on:
- water-server
- water-ui
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./config/nginx/conf.d:/etc/nginx/conf.d
- ./ssl:/etc/nginx/ssl
- ./logs/nginx:/var/log/nginx
ports:
- "80:80"
- "443:443"
networks:
- water-network
# MinIO 文件存储
water-minio:
image: minio/minio:latest
container_name: water-minio
restart: always
environment:
MINIO_ACCESS_KEY: "admin"
MINIO_SECRET_KEY: "admin123456"
volumes:
- ./data/minio:/data
ports:
- "9000:9000"
- "9001:9001"
command: server /data --console-address ":9001"
networks:
- water-network
networks:
water-network:
driver: bridge
volumes:
opengauss-data:
redis-data:
minio-data:
```
#### 8.1.2 后端应用Dockerfile
```dockerfile
# water-server/Dockerfile
FROM openjdk:17-jdk-slim
LABEL maintainer="fujian-water-dev-team"
# 设置工作目录
WORKDIR /app
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 添加应用jar包
COPY target/water-server.jar app.jar
# 创建日志目录
RUN mkdir -p /app/logs
# 暴露端口
EXPOSE 8080
# 启动应用
ENTRYPOINT ["java", "-jar", "-Xmx1024m", "-Xms512m", "-Dspring.profiles.active=prod", "/app/app.jar"]
```
#### 8.1.3 前端应用Dockerfile
```dockerfile
# water-ui/Dockerfile
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
# 复制包管理文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制源代码
COPY . .
# 构建应用
RUN npm run build:prod
# 生产阶段
FROM nginx:1.24-alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制nginx配置
COPY nginx.conf /etc/nginx/nginx.conf
# 暴露端口
EXPOSE 80
# 启动nginx
CMD ["nginx", "-g", "daemon off;"]
```
### 8.2 Docker Compose高级配置
#### 8.2.1 生产环境配置优化
**Docker Compose生产环境配置文件**
```yaml
# docker-compose.prod.yml
version: '3.8'
services:
water-opengauss:
image: enmotech/opengauss:5.0.0
container_name: water-opengauss-prod
restart: unless-stopped
environment:
GS_PASSWORD: "${DB_PASSWORD:-Water@2024!}"
GS_DB: "ruoyi_water"
GS_USERNAME: "water_user"
TZ: "Asia/Shanghai"
volumes:
- opengauss-prod-data:/var/lib/opengauss
- ./config/opengauss/prod:/opt/opengauss/config
- ./backups:/backups
ports:
- "5432:5432"
networks:
- water-prod-network
deploy:
resources:
limits:
memory: 2G
cpus: '2.0'
healthcheck:
test: ["CMD-SHELL", "gs_ctl status -D /var/lib/opengauss/data"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
water-redis:
image: redis:7.0-alpine
container_name: water-redis-prod
restart: unless-stopped
command: redis-server /etc/redis/redis.conf --requirepass ${REDIS_PASSWORD:-water_redis_2024}
volumes:
- redis-prod-data:/data
- ./config/redis/prod.conf:/etc/redis/redis.conf
ports:
- "6379:6379"
networks:
- water-prod-network
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
water-server:
image: water-server:${VERSION:-latest}
container_name: water-server-prod
restart: unless-stopped
depends_on:
water-opengauss:
condition: service_healthy
water-redis:
condition: service_started
environment:
- SPRING_PROFILES_ACTIVE=prod
- SPRING_DATASOURCE_URL=jdbc:opengauss://water-opengauss:5432/ruoyi_water
- SPRING_DATASOURCE_USERNAME=water_user
- SPRING_DATASOURCE_PASSWORD=${DB_PASSWORD:-Water@2024!}
- SPRING_REDIS_HOST=water-redis
- SPRING_REDIS_PASSWORD=${REDIS_PASSWORD:-water_redis_2024}
- SERVER_PORT=8080
- JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC
volumes:
- ./logs/prod:/app/logs
- ./upload/prod:/app/upload
- ./config/app:/app/config
networks:
- water-prod-network
deploy:
resources:
limits:
memory: 3G
cpus: '2.0'
replicas: 2
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
water-nginx:
image: nginx:1.24-alpine
container_name: water-nginx-prod
restart: unless-stopped
depends_on:
- water-server
volumes:
- ./config/nginx/prod.conf:/etc/nginx/nginx.conf
- ./config/nginx/conf.d:/etc/nginx/conf.d
- ./ssl:/etc/nginx/ssl
- ./logs/nginx:/var/log/nginx
- ./static:/usr/share/nginx/html
ports:
- "80:80"
- "443:443"
networks:
- water-prod-network
deploy:
resources:
limits:
memory: 256M
cpus: '0.5'
networks:
water-prod-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
volumes:
opengauss-prod-data:
driver: local
redis-prod-data:
driver: local
```
#### 8.2.2 环境变量配置
```bash
# .env.prod
# 数据库配置
DB_PASSWORD=Water@2024!Production
DB_HOST=water-opengauss
DB_PORT=5432
DB_NAME=ruoyi_water
# Redis配置
REDIS_PASSWORD=WaterRedis@2024!Production
REDIS_HOST=water-redis
REDIS_PORT=6379
# 应用配置
APP_VERSION=1.0.0
JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError
# 网络配置
NGINX_PORT=80
NGINX_SSL_PORT=443
# 日志级别
LOG_LEVEL=INFO
LOG_ROOT_LEVEL=WARN
```
#### 8.2.3 监控集成
```yaml
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: water-prometheus
restart: unless-stopped
volumes:
- ./config/prometheus:/etc/prometheus
- prometheus-data:/prometheus
ports:
- "9090:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
networks:
- water-network
grafana:
image: grafana/grafana:latest
container_name: water-grafana
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
volumes:
- grafana-data:/var/lib/grafana
- ./config/grafana:/etc/grafana/provisioning
ports:
- "3000:3000"
networks:
- water-network
volumes:
prometheus-data:
grafana-data:
```
### 8.3 自动化部署脚本
#### 8.3.1 Docker部署脚本
```bash
#!/bin/bash
# deploy-docker.sh
set -e
echo "=== 福建水务营收系统 Docker 部署脚本 ==="
# 检查Docker环境
if ! command -v docker &> /dev/null; then
echo "错误: Docker未安装请先安装Docker"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
echo "错误: Docker Compose未安装请先安装Docker Compose"
exit 1
fi
# 创建必要目录
echo "创建数据目录..."
mkdir -p data/{opengauss,redis,minio}
mkdir -p logs/{app,nginx}
mkdir -p config/{opengauss,redis,nginx/conf.d}
mkdir -p upload
mkdir -p ssl
mkdir -p backups
# 设置OpenGauss配置
echo "配置OpenGauss..."
cat > config/opengauss/postgresql.conf << EOF
# 数据库连接配置
max_connections = 1000
port = 5432
listen_addresses = '*'
# 内存配置
shared_buffers = 512MB
work_mem = 4MB
maintenance_work_mem = 128MB
# WAL配置
wal_level = replica
max_wal_size = 2GB
min_wal_size = 128MB
# 日志配置
log_destination = 'stderr'
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_min_duration_statement = 3000
# 性能优化
effective_cache_size = 1GB
random_page_cost = 1.1
seq_page_cost = 1.0
EOF
cat > config/opengauss/pg_hba.conf << EOF
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
host all all 0.0.0.0/0 md5
EOF
# 设置Redis配置
echo "配置Redis..."
cat > config/redis/redis.conf << EOF
port 6379
requirepass water_redis_2024
timeout 300
tcp-keepalive 300
maxmemory 256mb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
EOF
# 设置Nginx配置
echo "配置Nginx..."
cat > config/nginx/nginx.conf << EOF
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;
client_max_body_size 50M;
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/xml+rss
application/json;
include /etc/nginx/conf.d/*.conf;
}
EOF
cat > config/nginx/conf.d/water.conf << EOF
upstream water_backend {
server water-server:8080 max_fails=3 fail_timeout=30s;
keepalive 32;
}
server {
listen 80;
server_name localhost;
location /admin-api/ {
proxy_pass http://water_backend;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
}
location / {
proxy_pass http://water-ui;
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;
}
}
EOF
# 构建和启动服务
echo "构建和启动Docker服务..."
docker-compose down
docker-compose build --no-cache
docker-compose up -d
# 等待服务启动
echo "等待服务启动..."
sleep 30
# 检查服务状态
echo "检查服务状态..."
docker-compose ps
echo "=== 部署完成 ==="
echo "系统访问地址: http://localhost"
echo "API接口地址: http://localhost/admin-api"
echo "MinIO控制台: http://localhost:9001 (admin/admin123456)"
echo ""
echo "查看日志: docker-compose logs -f [服务名]"
echo "停止服务: docker-compose down"
echo "重启服务: docker-compose restart"
```
#### 8.3.2 生产环境部署脚本
```bash
#!/bin/bash
# deploy-prod.sh
set -e
echo "=== 福建水务营收系统 生产环境部署脚本 ==="
# 检查环境
if ! command -v docker &> /dev/null; then
echo "错误: Docker未安装请先安装Docker"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
echo "错误: Docker Compose未安装请先安装Docker Compose"
exit 1
fi
# 设置环境变量
export COMPOSE_PROJECT_NAME=water-system-prod
export VERSION=${1:-latest}
# 创建生产环境目录
echo "创建生产环境目录..."
mkdir -p {data,logs,config,upload,ssl,backups}/{prod,test}
mkdir -p config/{opengauss,redis,nginx,app,prometheus,grafana}
# 生成强密码
DB_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
REDIS_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
# 创建环境变量文件
echo "创建环境变量文件..."
cat > .env.prod << EOF
# 数据库配置
DB_PASSWORD=${DB_PASSWORD}
DB_HOST=water-opengauss
DB_PORT=5432
DB_NAME=ruoyi_water
# Redis配置
REDIS_PASSWORD=${REDIS_PASSWORD}
REDIS_HOST=water-redis
REDIS_PORT=6379
# 应用配置
VERSION=${VERSION}
JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError
# 网络配置
NGINX_PORT=80
NGINX_SSL_PORT=443
# 日志级别
LOG_LEVEL=INFO
LOG_ROOT_LEVEL=WARN
EOF
echo "数据库密码: ${DB_PASSWORD}"
echo "Redis密码: ${REDIS_PASSWORD}"
echo "请妥善保存以上密码信息!"
# 创建SSL证书自签名生产环境应使用正式证书
echo "创建SSL证书..."
if [ ! -f ssl/water-system.crt ]; then
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ssl/water-system.key \
-out ssl/water-system.crt \
-subj "/C=CN/ST=Fujian/L=Fuzhou/O=Water/CN=water.local"
fi
# 构建应用镜像
echo "构建应用镜像..."
docker build -t water-server:${VERSION} ./water-server
docker build -t water-ui:${VERSION} ./water-ui
# 停止现有服务
echo "停止现有服务..."
docker-compose --env-file .env.prod -f docker-compose.prod.yml down
# 启动生产服务
echo "启动生产服务..."
docker-compose --env-file .env.prod -f docker-compose.prod.yml up -d
# 等待服务启动
echo "等待服务启动..."
sleep 60
# 检查服务状态
echo "检查服务状态..."
docker-compose --env-file .env.prod -f docker-compose.prod.yml ps
# 健康检查
echo "执行健康检查..."
for i in {1..10}; do
if curl -f http://localhost/actuator/health >/dev/null 2>&1; then
echo "应用服务健康检查通过"
break
else
echo "等待应用服务启动... ($i/10)"
sleep 30
fi
if [ $i -eq 10 ]; then
echo "警告: 应用服务健康检查失败"
docker-compose --env-file .env.prod -f docker-compose.prod.yml logs water-server
fi
done
echo "=== 生产环境部署完成 ==="
echo "系统访问地址: https://localhost"
echo "系统监控地址: http://localhost:3000 (admin/admin123)"
echo "数据库端口: 5432"
echo "Redis端口: 6379"
echo ""
echo "管理命令:"
echo " 查看日志: docker-compose --env-file .env.prod -f docker-compose.prod.yml logs -f [服务名]"
echo " 停止服务: docker-compose --env-file .env.prod -f docker-compose.prod.yml down"
echo " 重启服务: docker-compose --env-file .env.prod -f docker-compose.prod.yml restart [服务名]"
echo " 备份数据: docker exec water-opengauss-prod gs_dump -h localhost -U water_user ruoyi_water > ./backups/backup-\$(date +%Y%m%d_%H%M%S).sql"
```
### 8.4 持续集成/持续部署 (CI/CD)
#### 8.4.1 GitHub Actions配置
```yaml
# .github/workflows/deploy.yml
name: Build and Deploy Water System
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
REGISTRY: docker.io
IMAGE_NAME: water-system
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Cache Maven dependencies
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Run tests
run: mvn clean test
- name: Generate test report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Maven Tests
path: target/surefire-reports/*.xml
reporter: java-junit
build:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: mvn clean package -DskipTests
- name: Build Docker image
run: |
docker build -t $REGISTRY/$IMAGE_NAME-server:$GITHUB_SHA ./water-server
docker build -t $REGISTRY/$IMAGE_NAME-ui:$GITHUB_SHA ./water-ui
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push Docker images
run: |
docker push $REGISTRY/$IMAGE_NAME-server:$GITHUB_SHA
docker push $REGISTRY/$IMAGE_NAME-ui:$GITHUB_SHA
docker tag $REGISTRY/$IMAGE_NAME-server:$GITHUB_SHA $REGISTRY/$IMAGE_NAME-server:latest
docker tag $REGISTRY/$IMAGE_NAME-ui:$GITHUB_SHA $REGISTRY/$IMAGE_NAME-ui:latest
docker push $REGISTRY/$IMAGE_NAME-server:latest
docker push $REGISTRY/$IMAGE_NAME-ui:latest
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Deploy to Production
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
run: |
# 设置SSH密钥
echo "$DEPLOY_KEY" > deploy_key
chmod 600 deploy_key
# 部署到生产服务器
ssh -i deploy_key -o StrictHostKeyChecking=no $DEPLOY_USER@$DEPLOY_HOST << 'EOF'
cd /opt/water-system
# 拉取最新代码
git pull origin main
# 更新镜像版本
export VERSION=$GITHUB_SHA
# 重新部署
./deploy-prod.sh $VERSION
# 验证部署
sleep 30
curl -f http://localhost/actuator/health || exit 1
echo "生产环境部署完成!"
EOF
rm -f deploy_key
echo "部署完成!"
```
这样我已经为福建水务营收系统的部署设计文档补充了完整的现代化部署方案包括
1. **Docker Compose部署**完整的容器化部署配置
2. **Kubernetes部署**云原生部署配置
3. **自动化部署脚本**简化部署流程
4. **CI/CD流水线**持续集成和持续部署
这些配置都基于RuoYi-Vue-Pro框架的要求提供了生产就绪的部署方案