1117 lines
84 KiB
HTML
1117 lines
84 KiB
HTML
<!-- Generated by Trae Work -->
|
||
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>鑫潼智电系统 · PostgreSQL 数据库设计文档</title>
|
||
<style>
|
||
:root{
|
||
--bg:#eef3f8; --bg2:#fff; --ink:#0f1e2e; --muted:#5b6b7e; --rule:#dbe4ee;
|
||
--accent:#1d6fff; --accent2:#0d9488; --accent3:#7c3aed; --warn:#e0852b; --red:#dc2626;
|
||
--shadow:0 4px 14px rgba(0,0,0,.07); --shadow-lg:0 8px 28px rgba(0,0,0,.1); --radius:12px;
|
||
}
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
html{scroll-behavior:smooth}
|
||
body{font-family:'PingFang SC','Microsoft YaHei','Hiragino Sans GB',sans-serif;background:var(--bg);color:var(--ink);line-height:1.7;font-size:15px;-webkit-font-smoothing:antialiased}
|
||
body::before{content:"";position:fixed;inset:0;z-index:-1;background:radial-gradient(900px 600px at 8% 0%,rgba(29,111,255,.07),transparent 60%),radial-gradient(800px 600px at 92% 6%,rgba(13,148,136,.07),transparent 60%)}
|
||
.wrap{max-width:1180px;margin:0 auto;padding:0 24px}
|
||
|
||
.hero{padding:56px 0 32px}
|
||
.hero .tag{display:inline-block;font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);background:rgba(29,111,255,.08);padding:6px 14px;border-radius:999px;margin-bottom:14px}
|
||
.hero h1{font-size:34px;font-weight:700;letter-spacing:-.01em;margin-bottom:10px;background:linear-gradient(135deg,var(--ink),var(--accent));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
|
||
.hero .sub{font-size:16px;color:var(--muted);max-width:720px}
|
||
.hero .meta{display:flex;flex-wrap:wrap;gap:8px;margin-top:20px}
|
||
.hero .meta span{font-size:12.5px;color:var(--muted);background:var(--bg2);border:1px solid var(--rule);padding:5px 11px;border-radius:8px}
|
||
.hero .meta b{color:var(--ink);font-weight:600}
|
||
|
||
section{padding:36px 0}
|
||
.sh{display:flex;align-items:baseline;gap:14px;margin-bottom:22px}
|
||
.sn{font-family:'JetBrains Mono','Consolas',monospace;font-size:13px;font-weight:700;color:var(--accent);background:rgba(29,111,255,.08);padding:4px 10px;border-radius:6px;flex-shrink:0}
|
||
.sh h2{font-size:22px;font-weight:700;letter-spacing:-.01em}
|
||
.sh .d{font-size:13px;color:var(--muted);margin-left:auto}
|
||
|
||
.callout{background:var(--bg2);border:1px solid var(--rule);border-left:4px solid var(--accent);border-radius:0 var(--radius) var(--radius) 0;padding:14px 18px;margin:14px 0;box-shadow:var(--shadow)}
|
||
.callout.warn{border-left-color:var(--warn)}
|
||
.callout h4{font-size:14px;font-weight:700;margin-bottom:4px}
|
||
.callout p{font-size:13.5px;color:var(--muted)} .callout p strong{color:var(--ink)}
|
||
|
||
/* Domain cards */
|
||
.domains{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
|
||
.dom{background:var(--bg2);border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow)}
|
||
.dom-head{padding:10px 14px;color:#fff;display:flex;align-items:center;gap:8px}
|
||
.dom-head .dn{font-family:'JetBrains Mono',monospace;font-size:12px;font-weight:700;opacity:.7}
|
||
.dom-head h3{font-size:14px;font-weight:700}
|
||
.dom-body{padding:6px 8px 10px}
|
||
.tbl{padding:8px 10px;border-radius:6px;margin:3px}
|
||
.tbl:hover{background:rgba(29,111,255,.03)}
|
||
.tbl .tn{font-family:'JetBrains Mono',monospace;font-size:12.5px;font-weight:700;color:var(--accent)}
|
||
.tbl .tc{font-size:12px;color:var(--muted);margin-left:6px}
|
||
.dom-blue .dom-head{background:linear-gradient(135deg,#1d6fff,#3b82f6)} .dom-blue .tbl .tn{color:#1d6fff}
|
||
.dom-green .dom-head{background:linear-gradient(135deg,#0d9488,#14b8a6)} .dom-green .tbl .tn{color:#0d9488}
|
||
.dom-purple .dom-head{background:linear-gradient(135deg,#7c3aed,#8b5cf6)} .dom-purple .tbl .tn{color:#7c3aed}
|
||
.dom-amber .dom-head{background:linear-gradient(135deg,#e0852b,#f59e0b)} .dom-amber .tbl .tn{color:#e0852b}
|
||
.dom-slate .dom-head{background:linear-gradient(135deg,#475569,#64748b)} .dom-slate .tbl .tn{color:#475569}
|
||
.dom-red .dom-head{background:linear-gradient(135deg,#dc2626,#ef4444)} .dom-red .tbl .tn{color:#dc2626}
|
||
|
||
/* ER diagram */
|
||
.mermaid{background:var(--bg2);border:1px solid var(--rule);border-radius:var(--radius);padding:20px;text-align:center;margin:14px 0;box-shadow:var(--shadow);overflow-x:auto}
|
||
|
||
/* Table detail */
|
||
table{width:100%;border-collapse:collapse;font-size:12.5px}
|
||
thead th{background:#f1f5fb;color:var(--ink);font-weight:700;text-align:left;padding:8px 12px;border-bottom:2px solid var(--rule);position:sticky;top:0}
|
||
tbody td{padding:7px 12px;border-bottom:1px solid var(--rule);vertical-align:top}
|
||
tbody tr:hover{background:rgba(29,111,255,.03)}
|
||
code{font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--accent);background:rgba(29,111,255,.06);padding:1px 5px;border-radius:4px}
|
||
.pill{display:inline-block;font-size:10px;font-weight:700;padding:1px 7px;border-radius:999px}
|
||
.p-pk{background:rgba(29,111,255,.12);color:#1d6fff}
|
||
.p-fk{background:rgba(124,58,237,.12);color:#7c3aed}
|
||
.p-pi{background:rgba(13,148,136,.12);color:#0d9488}
|
||
.table-wrap{border:1px solid var(--rule);border-radius:var(--radius);overflow:auto;max-height:480px;background:var(--bg2);margin:8px 0}
|
||
.dom-div{display:flex;align-items:center;gap:10px;margin:28px 0 10px;padding:8px 14px;border-radius:8px;background:var(--bg2);border:1px solid var(--rule);border-left:4px solid var(--accent)}
|
||
.dom-div .dn{font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:700;color:#fff;background:var(--accent);padding:2px 8px;border-radius:4px}
|
||
.dom-div h3{font-size:15px;font-weight:700}
|
||
.dom-div .dc{font-size:12px;color:var(--muted);margin-left:auto}
|
||
.tbl-title{font-size:14px;font-weight:700;margin:12px 0 4px;display:flex;align-items:center;gap:8px}
|
||
.tbl-title code{font-size:13px}
|
||
.tbl-title .td{font-size:12px;color:var(--muted);font-weight:400}
|
||
|
||
/* Partition vis */
|
||
.part-vis{display:grid;grid-template-columns:repeat(6,1fr);gap:6px;margin:14px 0}
|
||
.part{border-radius:8px;padding:10px 6px;text-align:center;border:1.5px solid;font-size:11px}
|
||
.part h4{font-family:'JetBrains Mono',monospace;font-size:10.5px;font-weight:700;margin-bottom:2px}
|
||
.part p{font-size:10px;color:var(--muted)}
|
||
.part.active{border-color:var(--accent2);background:rgba(13,148,136,.08)} .part.active h4{color:#0d9488}
|
||
.part.future{border-color:var(--rule);background:rgba(0,0,0,.02)} .part.future h4{color:var(--muted)}
|
||
.part.archive{border-style:dashed;border-color:var(--rule)} .part.archive h4{color:var(--muted)} .part.archive p{color:#94a3b8}
|
||
|
||
footer{margin-top:36px;padding:24px 0 44px;border-top:1px solid var(--rule)}
|
||
footer p{text-align:center;font-size:13px;color:var(--muted)}
|
||
@media(max-width:860px){.domains{grid-template-columns:1fr}.part-vis{grid-template-columns:repeat(3,1fr)} .hero h1{font-size:26px}}
|
||
@media(max-width:520px){.part-vis{grid-template-columns:repeat(2,1fr)} .wrap{padding:0 14px}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="wrap">
|
||
|
||
<header class="hero">
|
||
<span class="tag">DATABASE DESIGN · V1.0</span>
|
||
<h1>鑫潼智电系统 · PostgreSQL 数据库设计文档</h1>
|
||
<p class="sub">基于《鑫潼智电系统需求分析报告 V1.0》数据说明,设计 37 张数据表 + 3 个分区管理函数 + 1 个物化视图,覆盖客户、项目、设备、派单、报警、报修、维保、报酬、用电采集等全部业务域。采用逻辑隔离 + 时序分区方案。</p>
|
||
<div class="meta">
|
||
<span>数据库:<b>PostgreSQL 15+</b></span>
|
||
<span>表数量:<b>37 张</b></span>
|
||
<span>隔离方案:<b>customer_id 逻辑隔离</b></span>
|
||
<span>时序分区:<b>electricity_data 按月分区</b></span>
|
||
<span>自动分区:<b>3 个管理函数</b></span>
|
||
<span>历史分析:<b>1 个物化视图</b></span>
|
||
<span>字符集:<b>UTF8</b></span>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- 01 设计概述 -->
|
||
<section id="overview">
|
||
<div class="sh"><span class="sn">01</span><h2>设计概述</h2><span class="d">设计原则与关键决策</span></div>
|
||
|
||
<div class="callout">
|
||
<h4>设计原则</h4>
|
||
<p>① <strong>逻辑隔离</strong>:所有业务表携带 <code>customer_id</code> 字段实现行级数据隔离,不做物理分库。② <strong>时序分区</strong>:用电采集数据(<code>electricity_data</code>)按月 RANGE 分区,解决数据量暴涨问题。③ <strong>外键约束</strong>:核心关联表使用外键保证数据完整性。④ <strong>JSONB 灵活存储</strong>:照片路径列表、ICC 灵活字段使用 JSONB 类型。⑤ <strong>全部表加 COMMENT</strong>:便于团队协作和 ORM 映射。</p>
|
||
</div>
|
||
|
||
<div class="callout warn">
|
||
<h4>命名规范</h4>
|
||
<p>表名:<code>snake_case</code> 小写下划线,业务表无前缀,系统表 <code>sys_</code> 前缀。主键:统一 <code>BIGSERIAL</code> 自增。时间字段:统一 <code>TIMESTAMPTZ</code> 带时区。布尔状态:用 <code>SMALLINT</code>(0/1)。编码字段:如 <code>customer_no</code>、<code>plan_no</code> 等业务编号用 <code>VARCHAR(64)</code>。</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 02 业务域划分 -->
|
||
<section id="domains">
|
||
<div class="sh"><span class="sn">02</span><h2>业务域划分</h2><span class="d">14 个业务域 · 37 张表</span></div>
|
||
|
||
<div class="domains">
|
||
<div class="dom dom-blue">
|
||
<div class="dom-head"><span class="dn">D1</span><h3>系统管理域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">sys_user</span><span class="tc">系统用户(业务员/管理员)</span></div>
|
||
<div class="tbl"><span class="tn">sys_role</span><span class="tc">角色</span></div>
|
||
<div class="tbl"><span class="tn">sys_user_role</span><span class="tc">用户角色关联</span></div>
|
||
<div class="tbl"><span class="tn">sys_menu</span><span class="tc">菜单(RBAC 权限)</span></div>
|
||
<div class="tbl"><span class="tn">sys_role_menu</span><span class="tc">角色菜单关联</span></div>
|
||
<div class="tbl"><span class="tn">sys_dict</span><span class="tc">数据字典</span></div>
|
||
<div class="tbl"><span class="tn">sys_operation_log</span><span class="tc">操作日志</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-green">
|
||
<div class="dom-head"><span class="dn">D2</span><h3>客户域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">customer</span><span class="tc">客户信息</span></div>
|
||
<div class="tbl"><span class="tn">customer_department</span><span class="tc">客户部门</span></div>
|
||
<div class="tbl"><span class="tn">customer_visit</span><span class="tc">客户拜访</span></div>
|
||
<div class="tbl"><span class="tn">customer_building</span><span class="tc">客户建筑</span></div>
|
||
<div class="tbl"><span class="tn">customer_room</span><span class="tc">客户房间</span></div>
|
||
<div class="tbl"><span class="tn">customer_equipment</span><span class="tc">客户设备(配电间/井/箱)</span></div>
|
||
<div class="tbl"><span class="tn">customer_account</span><span class="tc">客户访问账号</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-purple">
|
||
<div class="dom-head"><span class="dn">D3</span><h3>智电设备域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">smart_device</span><span class="tc">智电设备型号(产品目录)</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-amber">
|
||
<div class="dom-head"><span class="dn">D4</span><h3>项目方案与合同域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">project_plan</span><span class="tc">智电改造方案</span></div>
|
||
<div class="tbl"><span class="tn">project_plan_detail</span><span class="tc">方案设备明细</span></div>
|
||
<div class="tbl"><span class="tn">contract</span><span class="tc">项目合同</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-slate">
|
||
<div class="dom-head"><span class="dn">D5</span><h3>线路与设备关联域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">electric_line</span><span class="tc">智电改造线路(ICC 同步)</span></div>
|
||
<div class="tbl"><span class="tn">line_room</span><span class="tc">线路房间关联</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-blue">
|
||
<div class="dom-head"><span class="dn">D6</span><h3>派单域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">survey_order</span><span class="tc">勘察派单</span></div>
|
||
<div class="tbl"><span class="tn">install_order</span><span class="tc">安装派单</span></div>
|
||
<div class="tbl"><span class="tn">acceptance</span><span class="tc">项目验收</span></div>
|
||
<div class="tbl"><span class="tn">visit_record</span><span class="tc">客户回访</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-red">
|
||
<div class="dom-head"><span class="dn">D7</span><h3>报警域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">fault_type</span><span class="tc">报警故障类型</span></div>
|
||
<div class="tbl"><span class="tn">fault_type_detail</span><span class="tc">故障类型明细</span></div>
|
||
<div class="tbl"><span class="tn">device_alarm</span><span class="tc">设备报警(ICC 拉取)</span></div>
|
||
<div class="tbl"><span class="tn">alarm_dispatch</span><span class="tc">报警派单</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-amber">
|
||
<div class="dom-head"><span class="dn">D8</span><h3>报修域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">repair_request</span><span class="tc">报修单</span></div>
|
||
<div class="tbl"><span class="tn">repair_dispatch</span><span class="tc">报修派单</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-green">
|
||
<div class="dom-head"><span class="dn">D9</span><h3>维保域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">maintenance_order</span><span class="tc">维保单</span></div>
|
||
<div class="tbl"><span class="tn">maintenance_detail</span><span class="tc">维保明细</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-purple">
|
||
<div class="dom-head"><span class="dn">D10</span><h3>共享电工域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">worker</span><span class="tc">共享电工信息</span></div>
|
||
<div class="tbl"><span class="tn">dispatch_price</span><span class="tc">派单价格</span></div>
|
||
<div class="tbl"><span class="tn">worker_income</span><span class="tc">派单收入(月度)</span></div>
|
||
<div class="tbl"><span class="tn">worker_income_detail</span><span class="tc">派单收入明细</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-amber">
|
||
<div class="dom-head"><span class="dn">D11</span><h3>用电采集域(分区)</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">electricity_data</span><span class="tc">线路用电信息(按月分区)</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dom dom-slate">
|
||
<div class="dom-head"><span class="dn">D12</span><h3>辅助域</h3></div>
|
||
<div class="dom-body">
|
||
<div class="tbl"><span class="tn">icc_sync_log</span><span class="tc">ICC 同步日志</span></div>
|
||
<div class="tbl"><span class="tn">file_record</span><span class="tc">文件存储记录</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 03 ER 图 -->
|
||
<section id="er">
|
||
<div class="sh"><span class="sn">03</span><h2>核心 ER 关系图</h2><span class="d">关键实体关联</span></div>
|
||
|
||
<div class="callout"><p>以下展示客户域→项目域→线路域→报警/报修域的核心关联路径,省略系统管理域和辅助域。</p></div>
|
||
|
||
<figure class="mermaid">
|
||
erDiagram
|
||
customer ||--o{ customer_department : "1对多"
|
||
customer ||--o{ customer_building : "1对多"
|
||
customer ||--o{ customer_equipment : "1对多"
|
||
customer ||--o{ customer_room : "1对多"
|
||
customer ||--o{ customer_visit : "1对多"
|
||
customer ||--o{ customer_account : "1对多"
|
||
customer ||--o{ project_plan : "1对多"
|
||
customer ||--o{ contract : "1对多"
|
||
customer ||--o{ survey_order : "1对多"
|
||
customer ||--o{ install_order : "1对多"
|
||
customer ||--o{ acceptance : "1对多"
|
||
customer ||--o{ visit_record : "1对多"
|
||
customer ||--o{ repair_request : "1对多"
|
||
customer ||--o{ maintenance_order : "1对多"
|
||
customer ||--o{ electricity_data : "1对多"
|
||
|
||
customer_building ||--o{ customer_equipment : "建筑含设备"
|
||
customer_building ||--o{ customer_room : "建筑含房间"
|
||
customer_department ||--o{ customer_room : "部门含房间"
|
||
|
||
project_plan ||--o{ project_plan_detail : "方案含明细"
|
||
project_plan ||--o{ contract : "方案签合同"
|
||
smart_device ||--o{ project_plan_detail : "设备型号"
|
||
|
||
customer_equipment ||--o{ electric_line : "设备含线路"
|
||
electric_line ||--o{ line_room : "线路关联房间"
|
||
customer_room ||--o{ line_room : "房间关联线路"
|
||
|
||
fault_type ||--o{ fault_type_detail : "类型含明细"
|
||
fault_type ||--o{ alarm_dispatch : "故障派单"
|
||
electric_line ||--o{ device_alarm : "线路报警"
|
||
device_alarm ||--o{ alarm_dispatch : "报警派单"
|
||
|
||
repair_request ||--|{ repair_dispatch : "报修派单"
|
||
maintenance_order ||--|{ maintenance_detail : "维保明细"
|
||
customer_equipment ||--o{ maintenance_detail : "维保设备"
|
||
|
||
worker ||--o{ worker_income : "电工收入"
|
||
worker_income ||--o{ worker_income_detail : "收入明细"
|
||
dispatch_price ||--o{ worker_income_detail : "价格参考"
|
||
</figure>
|
||
</section>
|
||
|
||
<!-- 04 时序分区 -->
|
||
<section id="partition">
|
||
<div class="sh"><span class="sn">04</span><h2>用电数据时序分区</h2><span class="d">electricity_data 按月 RANGE 分区</span></div>
|
||
|
||
<div class="callout">
|
||
<h4>分区策略</h4>
|
||
<p><code>electricity_data</code> 表是数据量增量大头(每条线路按 ICC 采集频次持续写入)。采用 PostgreSQL 声明式 RANGE 分区,按 <code>collect_time</code> 字段按月切分。查询只扫描目标月份分区,性能稳定。历史分区可归档,不影响热数据查询。</p>
|
||
</div>
|
||
|
||
<div class="part-vis">
|
||
<div class="part archive"><h4>2026_05</h4><p>已归档</p></div>
|
||
<div class="part archive"><h4>2026_06</h4><p>已归档</p></div>
|
||
<div class="part archive"><h4>2026_07</h4><p>已归档</p></div>
|
||
<div class="part active"><h4>2026_08</h4><p>当前活跃</p></div>
|
||
<div class="part future"><h4>2026_09</h4><p>预创建</p></div>
|
||
<div class="part future"><h4>2026_10</h4><p>预创建</p></div>
|
||
<div class="part future"><h4>2026_11</h4><p>预创建</p></div>
|
||
<div class="part future"><h4>2026_12</h4><p>预创建</p></div>
|
||
<div class="part future"><h4>2027_01</h4><p>待创建</p></div>
|
||
<div class="part future"><h4>2027_02</h4><p>待创建</p></div>
|
||
<div class="part future"><h4>2027_03</h4><p>待创建</p></div>
|
||
<div class="part future"><h4>2027_04</h4><p>待创建</p></div>
|
||
</div>
|
||
|
||
<div class="callout warn">
|
||
<h4>分区自动管理</h4>
|
||
<p>建议使用 <code>pg_partman</code> 扩展或编写定时任务(Midway.js cron)自动创建未来月份分区。每月初自动 CREATE 新分区,超过 N 个月的分区可 DETACH 后归档至冷存储。构建脚本已预创建 2026 年 8~12 月分区。</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 05 全部表字段说明 -->
|
||
<section id="tables">
|
||
<div class="sh"><span class="sn">05</span><h2>全部数据表字段说明</h2><span class="d">37 张表 · 按业务域分组</span></div>
|
||
|
||
<!-- D1 系统管理域 -->
|
||
<div class="dom-div"><span class="dn">D1</span><h3>系统管理域</h3><span class="dc">7 张表 · 用户/角色/菜单/字典/日志</span></div>
|
||
|
||
<div class="tbl-title"><code>sys_user</code><span class="td">— 系统用户表(鑫潼内部人员)</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>username</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>登录用户名</td></tr>
|
||
<tr><td><code>password_hash</code></td><td>VARCHAR(256)</td><td></td><td>密码哈希值</td></tr>
|
||
<tr><td><code>real_name</code></td><td>VARCHAR(64)</td><td></td><td>真实姓名</td></tr>
|
||
<tr><td><code>phone</code></td><td>VARCHAR(20)</td><td></td><td>手机号</td></tr>
|
||
<tr><td><code>email</code></td><td>VARCHAR(128)</td><td></td><td>邮箱</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:1启用 0禁用</td></tr>
|
||
<tr><td><code>last_login_at</code></td><td>TIMESTAMPTZ</td><td></td><td>最后登录时间</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
<tr><td><code>updated_at</code></td><td>TIMESTAMPTZ</td><td></td><td>更新时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>sys_role</code><span class="td">— 角色表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>role_code</code></td><td>VARCHAR(32)</td><td>UNIQUE</td><td>角色编码</td></tr>
|
||
<tr><td><code>role_name</code></td><td>VARCHAR(64)</td><td></td><td>角色名称</td></tr>
|
||
<tr><td><code>description</code></td><td>TEXT</td><td></td><td>描述</td></tr>
|
||
<tr><td><code>sort_order</code></td><td>INT</td><td></td><td>排序号</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>sys_user_role</code><span class="td">— 用户角色关联表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>user_id</code></td><td>BIGINT</td><td><span class="pill p-pk">PK</span><span class="pill p-fk">FK</span></td><td>用户 ID(→ sys_user)</td></tr>
|
||
<tr><td><code>role_id</code></td><td>BIGINT</td><td><span class="pill p-pk">PK</span><span class="pill p-fk">FK</span></td><td>角色 ID(→ sys_role)</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>sys_menu</code><span class="td">— 菜单表(RBAC 权限)</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>parent_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>父菜单 ID(自关联)</td></tr>
|
||
<tr><td><code>menu_name</code></td><td>VARCHAR(64)</td><td></td><td>菜单名称</td></tr>
|
||
<tr><td><code>menu_path</code></td><td>VARCHAR(256)</td><td></td><td>路由路径</td></tr>
|
||
<tr><td><code>component</code></td><td>VARCHAR(256)</td><td></td><td>前端组件路径</td></tr>
|
||
<tr><td><code>icon</code></td><td>VARCHAR(64)</td><td></td><td>图标</td></tr>
|
||
<tr><td><code>sort_order</code></td><td>INT</td><td></td><td>排序号</td></tr>
|
||
<tr><td><code>menu_type</code></td><td>SMALLINT</td><td></td><td>类型:1目录 2菜单 3按钮</td></tr>
|
||
<tr><td><code>permission</code></td><td>VARCHAR(128)</td><td></td><td>权限标识,如 customer:list</td></tr>
|
||
<tr><td><code>visible</code></td><td>SMALLINT</td><td></td><td>是否可见:1是 0否</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>sys_role_menu</code><span class="td">— 角色菜单关联表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>role_id</code></td><td>BIGINT</td><td><span class="pill p-pk">PK</span><span class="pill p-fk">FK</span></td><td>角色 ID(→ sys_role)</td></tr>
|
||
<tr><td><code>menu_id</code></td><td>BIGINT</td><td><span class="pill p-pk">PK</span><span class="pill p-fk">FK</span></td><td>菜单 ID(→ sys_menu)</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>sys_dict</code><span class="td">— 数据字典表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>dict_type</code></td><td>VARCHAR(64)</td><td><span class="pill p-pi">IDX</span></td><td>字典类型</td></tr>
|
||
<tr><td><code>dict_label</code></td><td>VARCHAR(128)</td><td></td><td>字典标签</td></tr>
|
||
<tr><td><code>dict_value</code></td><td>VARCHAR(128)</td><td></td><td>字典值</td></tr>
|
||
<tr><td><code>sort_order</code></td><td>INT</td><td></td><td>排序号</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:1启用 0禁用</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>sys_operation_log</code><span class="td">— 操作日志表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>user_id</code></td><td>BIGINT</td><td><span class="pill p-pi">IDX</span></td><td>操作用户 ID</td></tr>
|
||
<tr><td><code>module</code></td><td>VARCHAR(64)</td><td></td><td>操作模块</td></tr>
|
||
<tr><td><code>action</code></td><td>VARCHAR(64)</td><td></td><td>操作动作</td></tr>
|
||
<tr><td><code>method</code></td><td>VARCHAR(256)</td><td></td><td>请求方法</td></tr>
|
||
<tr><td><code>params</code></td><td>TEXT</td><td></td><td>请求参数</td></tr>
|
||
<tr><td><code>ip</code></td><td>VARCHAR(64)</td><td></td><td>操作 IP</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td><span class="pill p-pi">IDX</span></td><td>操作时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D2 客户域 -->
|
||
<div class="dom-div"><span class="dn">D2</span><h3>客户域</h3><span class="dc">7 张表 · 客户/部门/建筑/房间/设备/账号</span></div>
|
||
|
||
<div class="tbl-title"><code>customer</code><span class="td">— 客户信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>customer_name</code></td><td>VARCHAR(128)</td><td><span class="pill p-pi">IDX</span></td><td>客户名称</td></tr>
|
||
<tr><td><code>province</code></td><td>VARCHAR(64)</td><td></td><td>省</td></tr>
|
||
<tr><td><code>city</code></td><td>VARCHAR(64)</td><td></td><td>市</td></tr>
|
||
<tr><td><code>district</code></td><td>VARCHAR(64)</td><td></td><td>区/县</td></tr>
|
||
<tr><td><code>address</code></td><td>VARCHAR(256)</td><td></td><td>地址</td></tr>
|
||
<tr><td><code>contact_person</code></td><td>VARCHAR(64)</td><td></td><td>联系人</td></tr>
|
||
<tr><td><code>contact_phone</code></td><td>VARCHAR(20)</td><td></td><td>电话</td></tr>
|
||
<tr><td><code>postal_code</code></td><td>VARCHAR(10)</td><td></td><td>邮编</td></tr>
|
||
<tr><td><code>fax</code></td><td>VARCHAR(20)</td><td></td><td>传真</td></tr>
|
||
<tr><td><code>customer_level</code></td><td>VARCHAR(32)</td><td></td><td>客户级别(学校/医院等)</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:1意向 2签约 3运维中 4终止</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
<tr><td><code>updated_at</code></td><td>TIMESTAMPTZ</td><td></td><td>更新时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>customer_department</code><span class="td">— 客户部门信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID(→ customer)</td></tr>
|
||
<tr><td><code>dept_name</code></td><td>VARCHAR(128)</td><td></td><td>部门名称</td></tr>
|
||
<tr><td><code>contact_person</code></td><td>VARCHAR(64)</td><td></td><td>联系人</td></tr>
|
||
<tr><td><code>contact_phone</code></td><td>VARCHAR(20)</td><td></td><td>电话</td></tr>
|
||
<tr><td><code>function_desc</code></td><td>TEXT</td><td></td><td>职能</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>customer_visit</code><span class="td">— 客户拜访信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>visit_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>拜访单号</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>visit_person</code></td><td>VARCHAR(64)</td><td></td><td>拜访人</td></tr>
|
||
<tr><td><code>visit_phone</code></td><td>VARCHAR(20)</td><td></td><td>拜访人电话</td></tr>
|
||
<tr><td><code>visit_content</code></td><td>TEXT</td><td></td><td>拜访内容</td></tr>
|
||
<tr><td><code>visit_time</code></td><td>DATE</td><td></td><td>拜访时间</td></tr>
|
||
<tr><td><code>salesman_id</code></td><td>BIGINT</td><td><span class="pill p-pi">IDX</span></td><td>业务员</td></tr>
|
||
<tr><td><code>will_plan</code></td><td>SMALLINT</td><td></td><td>是否做方案:0不同意 1同意</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>customer_building</code><span class="td">— 客户智电改造建筑信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>building_name</code></td><td>VARCHAR(128)</td><td></td><td>建筑名称</td></tr>
|
||
<tr><td><code>basic_info</code></td><td>TEXT</td><td></td><td>基本情况</td></tr>
|
||
<tr><td><code>purpose</code></td><td>VARCHAR(128)</td><td></td><td>用途</td></tr>
|
||
<tr><td><code>floor_count</code></td><td>INT</td><td></td><td>层数</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>customer_room</code><span class="td">— 客户建筑房间信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>room_code</code></td><td>VARCHAR(64)</td><td></td><td>房间编码</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>room_name</code></td><td>VARCHAR(128)</td><td></td><td>房间名称</td></tr>
|
||
<tr><td><code>building_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>所属建筑 ID(→ customer_building)</td></tr>
|
||
<tr><td><code>floor_no</code></td><td>VARCHAR(16)</td><td></td><td>所在楼层</td></tr>
|
||
<tr><td><code>room_purpose</code></td><td>VARCHAR(128)</td><td></td><td>房间用途</td></tr>
|
||
<tr><td><code>dept_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>房间所属客户部门(→ customer_department)</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>customer_equipment</code><span class="td">— 客户智电改造设备信息表(配电间/井/箱)</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>equip_code</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>客户设备编码</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>equip_name</code></td><td>VARCHAR(128)</td><td></td><td>客户设备名称</td></tr>
|
||
<tr><td><code>equip_type</code></td><td>VARCHAR(32)</td><td></td><td>设备类型:配电间/配电井/配电箱</td></tr>
|
||
<tr><td><code>building_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>所属建筑 ID</td></tr>
|
||
<tr><td><code>floor_no</code></td><td>VARCHAR(16)</td><td></td><td>所在楼层</td></tr>
|
||
<tr><td><code>location</code></td><td>VARCHAR(256)</td><td></td><td>所在位置</td></tr>
|
||
<tr><td><code>description</code></td><td>TEXT</td><td></td><td>设备描述</td></tr>
|
||
<tr><td><code>remark</code></td><td>TEXT</td><td></td><td>备注</td></tr>
|
||
<tr><td><code>photo_url</code></td><td>VARCHAR(512)</td><td></td><td>未改造前设备照片</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>customer_account</code><span class="td">— 客户访问账号表(小程序登录)</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>phone</code></td><td>VARCHAR(20)</td><td>UNIQUE</td><td>登录电话</td></tr>
|
||
<tr><td><code>password_hash</code></td><td>VARCHAR(256)</td><td></td><td>密码哈希</td></tr>
|
||
<tr><td><code>wx_openid</code></td><td>VARCHAR(128)</td><td></td><td>微信 openid</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:1启用 0禁用</td></tr>
|
||
<tr><td><code>last_login_at</code></td><td>TIMESTAMPTZ</td><td></td><td>最后登录时间</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D3 智电设备域 -->
|
||
<div class="dom-div"><span class="dn">D3</span><h3>智电设备域</h3><span class="dc">1 张表 · 产品目录</span></div>
|
||
|
||
<div class="tbl-title"><code>smart_device</code><span class="td">— 鑫潼智电设备信息表(产品目录)</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>device_model</code></td><td>VARCHAR(64)</td><td></td><td>智电设备型号</td></tr>
|
||
<tr><td><code>device_name</code></td><td>VARCHAR(128)</td><td></td><td>智电设备名称</td></tr>
|
||
<tr><td><code>device_spec</code></td><td>VARCHAR(256)</td><td></td><td>智电设备规格</td></tr>
|
||
<tr><td><code>device_type</code></td><td>VARCHAR(32)</td><td></td><td>设备类型:网关/采集器/探测器等</td></tr>
|
||
<tr><td><code>device_function</code></td><td>TEXT</td><td></td><td>智电设备功能</td></tr>
|
||
<tr><td><code>supplier</code></td><td>VARCHAR(128)</td><td></td><td>供应商</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D4 项目方案与合同域 -->
|
||
<div class="dom-div"><span class="dn">D4</span><h3>项目方案与合同域</h3><span class="dc">3 张表 · 方案/明细/合同</span></div>
|
||
|
||
<div class="tbl-title"><code>project_plan</code><span class="td">— 智电改造方案信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>plan_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>方案单号</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>registrar</code></td><td>VARCHAR(64)</td><td></td><td>方案登记人(业务员)</td></tr>
|
||
<tr><td><code>register_time</code></td><td>DATE</td><td></td><td>方案登记时间</td></tr>
|
||
<tr><td><code>plan_desc</code></td><td>TEXT</td><td></td><td>方案说明</td></tr>
|
||
<tr><td><code>plan_file_url</code></td><td>VARCHAR(512)</td><td></td><td>方案最终文件</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:0草稿 1已确认</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>project_plan_detail</code><span class="td">— 项目方案智电设备明细表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>plan_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>方案 ID(→ project_plan)</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>equip_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户设备 ID(→ customer_equipment)</td></tr>
|
||
<tr><td><code>smart_device_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>智电设备型号 ID(→ smart_device)</td></tr>
|
||
<tr><td><code>quantity</code></td><td>NUMERIC(10,2)</td><td></td><td>数量</td></tr>
|
||
<tr><td><code>remark</code></td><td>TEXT</td><td></td><td>备注</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>contract</code><span class="td">— 智电项目合同信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>contract_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>合同单号</td></tr>
|
||
<tr><td><code>xt_contract_no</code></td><td>VARCHAR(64)</td><td><span class="pill p-pi">IDX</span></td><td>鑫潼合同号(XT+年份+序号)</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>contract_amount</code></td><td>NUMERIC(14,2)</td><td></td><td>合同金额</td></tr>
|
||
<tr><td><code>pay_cycle</code></td><td>VARCHAR(32)</td><td></td><td>支付周期:按月/按年</td></tr>
|
||
<tr><td><code>salesman_id</code></td><td>BIGINT</td><td></td><td>业务员</td></tr>
|
||
<tr><td><code>sign_date</code></td><td>DATE</td><td></td><td>签订日期</td></tr>
|
||
<tr><td><code>contract_desc</code></td><td>TEXT</td><td></td><td>合同说明</td></tr>
|
||
<tr><td><code>start_date</code></td><td>DATE</td><td></td><td>开始日期</td></tr>
|
||
<tr><td><code>end_date</code></td><td>DATE</td><td></td><td>结束日期</td></tr>
|
||
<tr><td><code>plan_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>方案 ID(→ project_plan)</td></tr>
|
||
<tr><td><code>contract_file_url</code></td><td>VARCHAR(512)</td><td></td><td>签字盖章电子合同</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:1有效 0终止</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D5 线路与设备关联域 -->
|
||
<div class="dom-div"><span class="dn">D5</span><h3>线路与设备关联域</h3><span class="dc">2 张表 · ICC 同步 + 房间关联</span></div>
|
||
|
||
<div class="tbl-title"><code>electric_line</code><span class="td">— 智电改造线路表(ICC 同步)</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>line_code</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>线路编码(唯一)</td></tr>
|
||
<tr><td><code>equip_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户设备 ID(→ customer_equipment)</td></tr>
|
||
<tr><td><code>icc_device_code</code></td><td>VARCHAR(128)</td><td><span class="pill p-pi">IDX</span></td><td>ICC 智电设备编号</td></tr>
|
||
<tr><td><code>line_name</code></td><td>VARCHAR(128)</td><td></td><td>线路名称(ICC 同步)</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID(逻辑隔离键)</td></tr>
|
||
<tr><td><code>building_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>所属建筑 ID</td></tr>
|
||
<tr><td><code>floor_no</code></td><td>VARCHAR(16)</td><td></td><td>所在楼层</td></tr>
|
||
<tr><td><code>location</code></td><td>VARCHAR(256)</td><td></td><td>所在位置</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:1在线 0离线</td></tr>
|
||
<tr><td><code>synced_at</code></td><td>TIMESTAMPTZ</td><td></td><td>ICC 同步时间</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>line_room</code><span class="td">— 线路所属房间关联表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>line_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>线路 ID(→ electric_line)</td></tr>
|
||
<tr><td><code>room_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>房间 ID(→ customer_room)</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D6 派单域 -->
|
||
<div class="dom-div"><span class="dn">D6</span><h3>派单域</h3><span class="dc">4 张表 · 勘察/安装/验收/回访</span></div>
|
||
|
||
<div class="tbl-title"><code>survey_order</code><span class="td">— 客户勘察派单信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>survey_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>勘察单号</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>surveyor</code></td><td>VARCHAR(64)</td><td></td><td>勘察人(共享电工)</td></tr>
|
||
<tr><td><code>worker_id</code></td><td>BIGINT</td><td></td><td>共享电工 ID</td></tr>
|
||
<tr><td><code>survey_time</code></td><td>TIMESTAMPTZ</td><td></td><td>勘察时间</td></tr>
|
||
<tr><td><code>remark</code></td><td>TEXT</td><td></td><td>备注</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:0已派发 1已接单 2已完成</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>install_order</code><span class="td">— 项目安装任务派单信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>install_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>安装单号</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>installer</code></td><td>VARCHAR(64)</td><td></td><td>安装人(共享电工)</td></tr>
|
||
<tr><td><code>worker_id</code></td><td>BIGINT</td><td></td><td>共享电工 ID</td></tr>
|
||
<tr><td><code>dispatch_date</code></td><td>DATE</td><td></td><td>派单日期</td></tr>
|
||
<tr><td><code>start_date</code></td><td>DATE</td><td></td><td>开始日期</td></tr>
|
||
<tr><td><code>end_date</code></td><td>DATE</td><td></td><td>结束日期</td></tr>
|
||
<tr><td><code>plan_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>方案 ID(→ project_plan)</td></tr>
|
||
<tr><td><code>remark</code></td><td>TEXT</td><td></td><td>备注</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:0已派发 1已完成</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>acceptance</code><span class="td">— 项目验收信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>accept_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>验收单号</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>acceptor</code></td><td>VARCHAR(64)</td><td></td><td>验收人</td></tr>
|
||
<tr><td><code>accept_opinion</code></td><td>TEXT</td><td></td><td>验收意见</td></tr>
|
||
<tr><td><code>accept_date</code></td><td>DATE</td><td></td><td>验收日期</td></tr>
|
||
<tr><td><code>installer</code></td><td>VARCHAR(64)</td><td></td><td>安装人</td></tr>
|
||
<tr><td><code>accept_file_url</code></td><td>VARCHAR(512)</td><td></td><td>验收文件电子版</td></tr>
|
||
<tr><td><code>contract_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>合同 ID(→ contract)</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>visit_record</code><span class="td">— 客户回访信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>visit_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>回访单号</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>contact_person</code></td><td>VARCHAR(64)</td><td></td><td>联系人</td></tr>
|
||
<tr><td><code>contact_phone</code></td><td>VARCHAR(20)</td><td></td><td>电话</td></tr>
|
||
<tr><td><code>visitor</code></td><td>VARCHAR(64)</td><td></td><td>回访人</td></tr>
|
||
<tr><td><code>visit_time</code></td><td>DATE</td><td></td><td>回访时间</td></tr>
|
||
<tr><td><code>customer_opinion</code></td><td>TEXT</td><td></td><td>客户意见</td></tr>
|
||
<tr><td><code>photos</code></td><td>JSONB</td><td></td><td>回访照片</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D7 报警域 -->
|
||
<div class="dom-div"><span class="dn">D7</span><h3>报警域</h3><span class="dc">4 张表 · 故障类型/设备报警/报警派单</span></div>
|
||
|
||
<div class="tbl-title"><code>fault_type</code><span class="td">— 报警故障类型信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>fault_type_code</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>故障类型编码</td></tr>
|
||
<tr><td><code>fault_type_name</code></td><td>VARCHAR(128)</td><td></td><td>故障类型名称</td></tr>
|
||
<tr><td><code>description</code></td><td>TEXT</td><td></td><td>故障类型说明</td></tr>
|
||
<tr><td><code>remark</code></td><td>TEXT</td><td></td><td>备注</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>fault_type_detail</code><span class="td">— 报警故障类型明细表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>fault_type_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>故障类型 ID(→ fault_type)</td></tr>
|
||
<tr><td><code>detail_category</code></td><td>VARCHAR(32)</td><td></td><td>明细分类:故障原因/处理流程</td></tr>
|
||
<tr><td><code>detail_desc</code></td><td>TEXT</td><td></td><td>明细说明</td></tr>
|
||
<tr><td><code>remark</code></td><td>TEXT</td><td></td><td>备注</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>device_alarm</code><span class="td">— 设备报警信息表(ICC 拉取)</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>alarm_code</code></td><td>VARCHAR(128)</td><td>UNIQUE</td><td>报警编码</td></tr>
|
||
<tr><td><code>line_id</code></td><td>BIGINT</td><td><span class="pill p-pi">IDX</span></td><td>线路 ID</td></tr>
|
||
<tr><td><code>equip_id</code></td><td>BIGINT</td><td></td><td>客户设备 ID</td></tr>
|
||
<tr><td><code>icc_device_code</code></td><td>VARCHAR(128)</td><td></td><td>ICC 设备编号</td></tr>
|
||
<tr><td><code>line_name</code></td><td>VARCHAR(128)</td><td></td><td>线路名称</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-pi">IDX</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>building_id</code></td><td>BIGINT</td><td></td><td>所属建筑 ID</td></tr>
|
||
<tr><td><code>floor_no</code></td><td>VARCHAR(16)</td><td></td><td>所在楼层</td></tr>
|
||
<tr><td><code>location</code></td><td>VARCHAR(256)</td><td></td><td>所在位置</td></tr>
|
||
<tr><td><code>alarm_date</code></td><td>DATE</td><td><span class="pill p-pi">IDX</span></td><td>报警日期</td></tr>
|
||
<tr><td><code>fault_type</code></td><td>VARCHAR(128)</td><td></td><td>ICC 预警类型</td></tr>
|
||
<tr><td><code>alarm_value</code></td><td>NUMERIC(14,2)</td><td></td><td>报警数值</td></tr>
|
||
<tr><td><code>history_count</code></td><td>INT</td><td></td><td>历史出现次数</td></tr>
|
||
<tr><td><code>synced_at</code></td><td>TIMESTAMPTZ</td><td></td><td>ICC 同步时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>alarm_dispatch</code><span class="td">— 报警派单信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>dispatch_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>报警派单号</td></tr>
|
||
<tr><td><code>alarm_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>报警 ID(→ device_alarm)</td></tr>
|
||
<tr><td><code>line_id</code></td><td>BIGINT</td><td></td><td>线路 ID</td></tr>
|
||
<tr><td><code>equip_id</code></td><td>BIGINT</td><td></td><td>客户设备 ID</td></tr>
|
||
<tr><td><code>icc_device_code</code></td><td>VARCHAR(128)</td><td></td><td>ICC 设备编号</td></tr>
|
||
<tr><td><code>line_name</code></td><td>VARCHAR(128)</td><td></td><td>线路名称</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>contact_person</code></td><td>VARCHAR(64)</td><td></td><td>联系人</td></tr>
|
||
<tr><td><code>contact_phone</code></td><td>VARCHAR(20)</td><td></td><td>电话</td></tr>
|
||
<tr><td><code>building_id</code></td><td>BIGINT</td><td></td><td>建筑 ID</td></tr>
|
||
<tr><td><code>floor_no</code></td><td>VARCHAR(16)</td><td></td><td>所在楼层</td></tr>
|
||
<tr><td><code>location</code></td><td>VARCHAR(256)</td><td></td><td>所在位置</td></tr>
|
||
<tr><td><code>fault_type_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>故障类型 ID(→ fault_type)</td></tr>
|
||
<tr><td><code>fault_desc</code></td><td>TEXT</td><td></td><td>故障事项(类型+数值)</td></tr>
|
||
<tr><td><code>dispatcher</code></td><td>VARCHAR(64)</td><td></td><td>派发人</td></tr>
|
||
<tr><td><code>fault_reason</code></td><td>TEXT</td><td></td><td>故障原因(来自明细)</td></tr>
|
||
<tr><td><code>process_flow</code></td><td>TEXT</td><td></td><td>处理流程(来自明细)</td></tr>
|
||
<tr><td><code>worker_id</code></td><td>BIGINT</td><td><span class="pill p-pi">IDX</span></td><td>共享电工 ID</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td><span class="pill p-pi">IDX</span></td><td>状态:0已派发 1已处理</td></tr>
|
||
<tr><td><code>process_photos</code></td><td>JSONB</td><td></td><td>报警处理照片(多张)</td></tr>
|
||
<tr><td><code>rating</code></td><td>SMALLINT</td><td></td><td>派单处理评分</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
<tr><td><code>completed_at</code></td><td>TIMESTAMPTZ</td><td></td><td>完成时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D8 报修域 -->
|
||
<div class="dom-div"><span class="dn">D8</span><h3>报修域</h3><span class="dc">2 张表 · 报修单/报修派单</span></div>
|
||
|
||
<div class="tbl-title"><code>repair_request</code><span class="td">— 报修单信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>repair_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>报修单号</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>requester</code></td><td>VARCHAR(64)</td><td></td><td>报修人</td></tr>
|
||
<tr><td><code>requester_phone</code></td><td>VARCHAR(20)</td><td></td><td>报修电话</td></tr>
|
||
<tr><td><code>request_time</code></td><td>TIMESTAMPTZ</td><td></td><td>报修时间</td></tr>
|
||
<tr><td><code>building_id</code></td><td>BIGINT</td><td></td><td>所属建筑 ID</td></tr>
|
||
<tr><td><code>floor_no</code></td><td>VARCHAR(16)</td><td></td><td>所在楼层</td></tr>
|
||
<tr><td><code>location</code></td><td>VARCHAR(256)</td><td></td><td>所在位置</td></tr>
|
||
<tr><td><code>repair_content</code></td><td>TEXT</td><td></td><td>报修内容</td></tr>
|
||
<tr><td><code>photos</code></td><td>JSONB</td><td></td><td>报修照片</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td><span class="pill p-pi">IDX</span></td><td>状态:0待处理 1已派单 2已完成</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>repair_dispatch</code><span class="td">— 报修派单信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>dispatch_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>报修派单号</td></tr>
|
||
<tr><td><code>repair_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>报修单 ID(→ repair_request)</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>requester</code></td><td>VARCHAR(64)</td><td></td><td>报修人</td></tr>
|
||
<tr><td><code>requester_phone</code></td><td>VARCHAR(20)</td><td></td><td>报修电话</td></tr>
|
||
<tr><td><code>request_time</code></td><td>TIMESTAMPTZ</td><td></td><td>报修时间</td></tr>
|
||
<tr><td><code>building_id</code></td><td>BIGINT</td><td></td><td>建筑 ID</td></tr>
|
||
<tr><td><code>floor_no</code></td><td>VARCHAR(16)</td><td></td><td>所在楼层</td></tr>
|
||
<tr><td><code>location</code></td><td>VARCHAR(256)</td><td></td><td>所在位置</td></tr>
|
||
<tr><td><code>repair_content</code></td><td>TEXT</td><td></td><td>报修内容</td></tr>
|
||
<tr><td><code>dispatcher</code></td><td>VARCHAR(64)</td><td></td><td>派发人</td></tr>
|
||
<tr><td><code>worker_id</code></td><td>BIGINT</td><td><span class="pill p-pi">IDX</span></td><td>共享电工 ID</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:0已派发 1已处理</td></tr>
|
||
<tr><td><code>process_photos</code></td><td>JSONB</td><td></td><td>处理完成照片</td></tr>
|
||
<tr><td><code>rating</code></td><td>SMALLINT</td><td></td><td>报修派单处理评分(客户评)</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
<tr><td><code>completed_at</code></td><td>TIMESTAMPTZ</td><td></td><td>完成时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D9 维保域 -->
|
||
<div class="dom-div"><span class="dn">D9</span><h3>维保域</h3><span class="dc">2 张表 · 维保单/维保明细</span></div>
|
||
|
||
<div class="tbl-title"><code>maintenance_order</code><span class="td">— 维保单信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>maintenance_no</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>维保单号(录入,不自动生成)</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>maintainer</code></td><td>VARCHAR(64)</td><td></td><td>维保人(共享电工)</td></tr>
|
||
<tr><td><code>worker_id</code></td><td>BIGINT</td><td></td><td>共享电工 ID</td></tr>
|
||
<tr><td><code>maintenance_date</code></td><td>DATE</td><td></td><td>维保日期</td></tr>
|
||
<tr><td><code>remark</code></td><td>TEXT</td><td></td><td>备注</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:0已派发 1已完成</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>maintenance_detail</code><span class="td">— 维保单明细表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>maintenance_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>维保单 ID(→ maintenance_order)</td></tr>
|
||
<tr><td><code>equip_id</code></td><td>BIGINT</td><td></td><td>客户设备 ID</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>客户 ID</td></tr>
|
||
<tr><td><code>equip_name</code></td><td>VARCHAR(128)</td><td></td><td>客户设备名称</td></tr>
|
||
<tr><td><code>equip_type</code></td><td>VARCHAR(32)</td><td></td><td>设备类型:配电间/井/箱</td></tr>
|
||
<tr><td><code>building_id</code></td><td>BIGINT</td><td></td><td>建筑 ID</td></tr>
|
||
<tr><td><code>floor_no</code></td><td>VARCHAR(16)</td><td></td><td>所在楼层</td></tr>
|
||
<tr><td><code>location</code></td><td>VARCHAR(256)</td><td></td><td>所在位置</td></tr>
|
||
<tr><td><code>panel_condition</code></td><td>TEXT</td><td></td><td>配电间或电箱情况</td></tr>
|
||
<tr><td><code>circuit_condition</code></td><td>TEXT</td><td></td><td>回路情况</td></tr>
|
||
<tr><td><code>terminal_condition</code></td><td>TEXT</td><td></td><td>终端情况</td></tr>
|
||
<tr><td><code>maintenance_desc</code></td><td>TEXT</td><td></td><td>维保情况说明</td></tr>
|
||
<tr><td><code>photos</code></td><td>JSONB</td><td></td><td>维保现场照片(水印)</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D10 共享电工域 -->
|
||
<div class="dom-div"><span class="dn">D10</span><h3>共享电工域</h3><span class="dc">4 张表 · 电工/价格/收入/明细</span></div>
|
||
|
||
<div class="tbl-title"><code>worker</code><span class="td">— 共享电工信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>worker_name</code></td><td>VARCHAR(64)</td><td></td><td>电工姓名</td></tr>
|
||
<tr><td><code>phone</code></td><td>VARCHAR(20)</td><td><span class="pill p-pi">IDX</span></td><td>手机号</td></tr>
|
||
<tr><td><code>id_card</code></td><td>VARCHAR(18)</td><td></td><td>身份证号</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:1在岗 0离职</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
<tr><td><code>updated_at</code></td><td>TIMESTAMPTZ</td><td></td><td>更新时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>dispatch_price</code><span class="td">— 共享电工派单价格信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>price_code</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>派单价格编码</td></tr>
|
||
<tr><td><code>dispatch_type</code></td><td>VARCHAR(32)</td><td></td><td>派单类型:勘察/安装/预警/维修/维保</td></tr>
|
||
<tr><td><code>price_type</code></td><td>VARCHAR(32)</td><td></td><td>价格类型:单价/总价提成</td></tr>
|
||
<tr><td><code>unit_price</code></td><td>NUMERIC(10,2)</td><td></td><td>服务单价</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>worker_income</code><span class="td">— 共享电工派单收入信息表(月度汇总)</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>income_code</code></td><td>VARCHAR(64)</td><td>UNIQUE</td><td>派单收入编码</td></tr>
|
||
<tr><td><code>worker_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>共享电工 ID(→ worker)</td></tr>
|
||
<tr><td><code>income_month</code></td><td>VARCHAR(7)</td><td><span class="pill p-pi">IDX</span></td><td>收入月份(YYYY-MM)</td></tr>
|
||
<tr><td><code>monthly_total</code></td><td>NUMERIC(14,2)</td><td></td><td>月度收入合计</td></tr>
|
||
<tr><td><code>rating_summary</code></td><td>NUMERIC(5,2)</td><td></td><td>评分综合统计</td></tr>
|
||
<tr><td><code>final_total</code></td><td>NUMERIC(14,2)</td><td></td><td>月度最终收入合计</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>worker_income_detail</code><span class="td">— 共享电工派单收入明细信息表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>income_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>收入 ID(→ worker_income)</td></tr>
|
||
<tr><td><code>worker_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span></td><td>共享电工 ID</td></tr>
|
||
<tr><td><code>income_month</code></td><td>VARCHAR(7)</td><td></td><td>收入月份</td></tr>
|
||
<tr><td><code>dispatch_type</code></td><td>VARCHAR(32)</td><td></td><td>派单类型</td></tr>
|
||
<tr><td><code>dispatch_no</code></td><td>VARCHAR(64)</td><td></td><td>各类型派单单号</td></tr>
|
||
<tr><td><code>income_amount</code></td><td>NUMERIC(10,2)</td><td></td><td>本单收入</td></tr>
|
||
<tr><td><code>rating_level</code></td><td>VARCHAR(16)</td><td></td><td>评价等级</td></tr>
|
||
<tr><td><code>final_income</code></td><td>NUMERIC(10,2)</td><td></td><td>本单最终收入合计</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<!-- D11 用电采集域 -->
|
||
<div class="dom-div"><span class="dn">D11</span><h3>用电采集域(分区表)</h3><span class="dc">1 张表 · 按月分区</span></div>
|
||
|
||
<div class="tbl-title"><code>electricity_data</code><span class="td">— 线路用电信息表(按月 RANGE 分区)</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增(复合主键含 collect_time)</td></tr>
|
||
<tr><td><code>line_id</code></td><td>BIGINT</td><td><span class="pill p-fk">FK</span><span class="pill p-pi">IDX</span></td><td>线路 ID(→ electric_line)</td></tr>
|
||
<tr><td><code>line_code</code></td><td>VARCHAR(64)</td><td></td><td>线路编码(冗余,加速查询)</td></tr>
|
||
<tr><td><code>equip_id</code></td><td>BIGINT</td><td></td><td>客户设备 ID</td></tr>
|
||
<tr><td><code>icc_device_code</code></td><td>VARCHAR(128)</td><td></td><td>ICC 设备编号</td></tr>
|
||
<tr><td><code>line_name</code></td><td>VARCHAR(128)</td><td></td><td>线路名称</td></tr>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td><span class="pill p-pi">IDX</span></td><td>客户 ID(逻辑隔离键)</td></tr>
|
||
<tr><td><code>electricity</code></td><td>NUMERIC(14,4)</td><td></td><td>用电量</td></tr>
|
||
<tr><td><code>collect_time</code></td><td>TIMESTAMPTZ</td><td><span class="pill p-pk">PK</span><span class="pill p-pi">IDX</span></td><td>采集时间(分区键)</td></tr>
|
||
</tbody></table></div>
|
||
<div class="callout"><p><strong>分区键</strong>:<code>collect_time</code>。主键为复合主键 <code>(id, collect_time)</code>。已预建分区:<code>electricity_data_2026_08</code> ~ <code>electricity_data_2026_12</code>。组合索引:<code>(customer_id, collect_time)</code> 用于月报统计。</p></div>
|
||
|
||
<!-- D12 辅助域 -->
|
||
<div class="dom-div"><span class="dn">D12</span><h3>辅助域</h3><span class="dc">2 张表 · ICC 日志/文件记录</span></div>
|
||
|
||
<div class="tbl-title"><code>icc_sync_log</code><span class="td">— ICC 数据同步日志表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>sync_type</code></td><td>VARCHAR(32)</td><td><span class="pill p-pi">IDX</span></td><td>同步类型:客户/设备/用电/报警</td></tr>
|
||
<tr><td><code>start_time</code></td><td>TIMESTAMPTZ</td><td></td><td>开始时间</td></tr>
|
||
<tr><td><code>end_time</code></td><td>TIMESTAMPTZ</td><td></td><td>结束时间</td></tr>
|
||
<tr><td><code>record_count</code></td><td>INT</td><td></td><td>同步记录数</td></tr>
|
||
<tr><td><code>status</code></td><td>SMALLINT</td><td></td><td>状态:1成功 0失败</td></tr>
|
||
<tr><td><code>error_message</code></td><td>TEXT</td><td></td><td>错误信息</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td><span class="pill p-pi">IDX</span></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
|
||
<div class="tbl-title"><code>file_record</code><span class="td">— 文件存储记录表</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>字段</th><th>类型</th><th>键</th><th>说明</th></tr></thead><tbody>
|
||
<tr><td><code>id</code></td><td>BIGSERIAL</td><td><span class="pill p-pk">PK</span></td><td>自增主键</td></tr>
|
||
<tr><td><code>file_name</code></td><td>VARCHAR(256)</td><td></td><td>文件名</td></tr>
|
||
<tr><td><code>file_url</code></td><td>VARCHAR(512)</td><td></td><td>文件 URL</td></tr>
|
||
<tr><td><code>file_type</code></td><td>VARCHAR(32)</td><td></td><td>文件类型:取证/合同/验收/方案/月报</td></tr>
|
||
<tr><td><code>file_size</code></td><td>BIGINT</td><td></td><td>文件大小(字节)</td></tr>
|
||
<tr><td><code>business_type</code></td><td>VARCHAR(64)</td><td><span class="pill p-pi">IDX</span></td><td>关联业务类型</td></tr>
|
||
<tr><td><code>business_id</code></td><td>BIGINT</td><td></td><td>关联业务 ID</td></tr>
|
||
<tr><td><code>uploaded_by</code></td><td>BIGINT</td><td></td><td>上传人 ID</td></tr>
|
||
<tr><td><code>created_at</code></td><td>TIMESTAMPTZ</td><td></td><td>创建时间</td></tr>
|
||
</tbody></table></div>
|
||
</section>
|
||
|
||
<!-- 06 索引策略 -->
|
||
<section id="index">
|
||
<div class="sh"><span class="sn">06</span><h2>索引策略</h2><span class="d">关键索引一览</span></div>
|
||
|
||
<div class="table-wrap"><table>
|
||
<thead><tr><th>表</th><th>索引</th><th>类型</th><th>用途</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>customer</td><td><code>idx_customer_name</code></td><td>B-Tree</td><td>按客户名称搜索</td></tr>
|
||
<tr><td>customer</td><td><code>idx_customer_region</code></td><td>B-Tree 组合</td><td>按省市县区域查询</td></tr>
|
||
<tr><td>electric_line</td><td><code>idx_line_customer</code></td><td>B-Tree</td><td>按客户查线路(逻辑隔离)</td></tr>
|
||
<tr><td>electric_line</td><td><code>idx_line_icc</code></td><td>B-Tree</td><td>ICC 设备码匹配同步</td></tr>
|
||
<tr><td>electricity_data</td><td><code>idx_ed_customer_time</code></td><td>B-Tree 组合</td><td>按客户+时间查用电(月报核心查询)</td></tr>
|
||
<tr><td>device_alarm</td><td><code>idx_alarm_date</code></td><td>B-Tree</td><td>按报警日期查询</td></tr>
|
||
<tr><td>device_alarm</td><td><code>idx_alarm_customer</code></td><td>B-Tree</td><td>按客户查报警</td></tr>
|
||
<tr><td>alarm_dispatch</td><td><code>idx_alarm_disp_worker</code></td><td>B-Tree</td><td>电工查自己的派单(接口数据权限)</td></tr>
|
||
<tr><td>repair_dispatch</td><td><code>idx_repair_disp_worker</code></td><td>B-Tree</td><td>电工查报修派单</td></tr>
|
||
<tr><td>sys_dict</td><td><code>idx_sys_dict_type</code></td><td>B-Tree</td><td>按字典类型查询</td></tr>
|
||
<tr><td>icc_sync_log</td><td><code>idx_icc_sync_time</code></td><td>B-Tree</td><td>按时间查同步日志</td></tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<div class="callout">
|
||
<h4>索引设计原则</h4>
|
||
<p>① 所有 <code>customer_id</code> 外键字段建索引(逻辑隔离查询基础)。② 用电采集表建 <code>(customer_id, collect_time)</code> 组合索引(月报统计核心路径)。③ ICC 同步相关字段建索引(设备码匹配)。④ 共享电工查询字段建索引(接口数据权限过滤)。</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 07 初始数据 -->
|
||
<section id="init">
|
||
<div class="sh"><span class="sn">07</span><h2>初始数据</h2><span class="d">角色/菜单/字典</span></div>
|
||
|
||
<div class="table-wrap"><table>
|
||
<thead><tr><th>表</th><th>初始数据</th><th>说明</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>sys_role</code></td><td>4 条</td><td>运营管理员/业务员/共享电工/客户</td></tr>
|
||
<tr><td><code>sys_menu</code></td><td>6 条</td><td>客户管理/项目管理/运营派单/设备监控/统计报表/系统管理</td></tr>
|
||
<tr><td><code>sys_dict</code></td><td>19 条</td><td>客户状态/设备类型/派单状态/支付周期/派单类型等</td></tr>
|
||
</tbody>
|
||
</table></div>
|
||
</section>
|
||
|
||
<!-- 08 自动分区管理 -->
|
||
<section id="autopartition">
|
||
<div class="sh"><span class="sn">08</span><h2>自动分区管理</h2><span class="d">pg_cron 定时调度 · 数据库自治</span></div>
|
||
|
||
<div class="callout">
|
||
<h4>设计背景</h4>
|
||
<p>PostgreSQL 声明式分区<strong>不会自动创建子分区</strong>。若数据写入时对应月份的分区不存在,INSERT 会直接报错:<code>no partition of relation found for row</code>。因此需要一套自动化的分区管理机制,确保未来月份的分区始终提前就绪。</p>
|
||
</div>
|
||
|
||
<div class="callout warn">
|
||
<h4>为什么不用触发器兜底?</h4>
|
||
<p>PostgreSQL 分区表的 <code>BEFORE INSERT</code> 触发器在<strong>分区路由之后</strong>才执行——即数据库先判断数据该落入哪个子分区,如果子分区不存在直接报错,触发器根本没有机会执行。因此触发器无法在写入时动态创建分区,必须通过<strong>定时预创建</strong> + <strong>应用层调用</strong>来保证分区就绪。</p>
|
||
</div>
|
||
|
||
<h3 style="margin:24px 0 12px;font-size:16px">管理函数一览</h3>
|
||
<div class="table-wrap" style="max-height:none"><table>
|
||
<thead><tr><th>函数名</th><th>参数</th><th>返回</th><th>用途</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>ensure_electricity_partition</code></td>
|
||
<td><code>p_date DATE</code></td>
|
||
<td><code>VOID</code></td>
|
||
<td>确保指定日期所在月的分区存在(不存在则创建)。应用层在写入数据前调用此函数兜底。</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>run_electricity_partition_maintenance</code></td>
|
||
<td><code>p_premake INT</code>(默认 3)</td>
|
||
<td><code>TABLE(created_month, action)</code></td>
|
||
<td>批量预创建当前月 + 未来 N 个月的分区。Midway.js cron 每月调用一次,返回各分区状态(CREATED / EXISTS)。</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>refresh_electricity_monthly</code></td>
|
||
<td>无</td>
|
||
<td><code>VOID</code></td>
|
||
<td>刷新月度汇总物化视图。自动处理首次初始化(非并发),后续刷新用 <code>CONCURRENTLY</code> 不阻塞查询。</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<h3 style="margin:24px 0 12px;font-size:16px">分区生命周期</h3>
|
||
<div class="mermaid">
|
||
flowchart LR
|
||
subgraph P1 ["阶段一:预创建(pg_cron 自动执行)"]
|
||
A1["pg_cron 定时调度<br/>每月25号 03:00"] --> A2["run_electricity_partition_maintenance(3)"]
|
||
A2 --> A3{"分区是否<br/>已存在?"}
|
||
A3 --"不存在"--> A4["CREATE TABLE ... PARTITION OF"]
|
||
A3 --"已存在"--> A5["跳过"]
|
||
end
|
||
subgraph P2 ["阶段二:写入数据"]
|
||
B1["ICC 数据拉取<br/>服务写入数据"] --> B2["ensure_electricity_partition<br/>(collect_time)"]
|
||
B2 --> B3{"分区是否<br/>已存在?"}
|
||
B3 --"不存在"--> B4["自动创建分区"]
|
||
B3 --"已存在"--> B5["直接写入"]
|
||
B4 --> B5
|
||
end
|
||
subgraph P3 ["阶段三:归档"]
|
||
C1["超过 24 个月的<br/>分区"] --> C2["DETACH PARTITION<br/>从父表分离"]
|
||
C2 --> C3["冷数据存档<br/>或直接查询子表"]
|
||
C3 --> C4["如需分析<br/>ATTACH 临时挂回"]
|
||
end
|
||
P1 --> P2
|
||
P2 --> P3
|
||
|
||
style A4 fill:#e8f1ff,stroke:#1d6fff
|
||
style A5 fill:#f0fdf4,stroke:#0d9488
|
||
style B4 fill:#e8f1ff,stroke:#1d6fff
|
||
style B5 fill:#f0fdf4,stroke:#0d9488
|
||
style C2 fill:#fef3e8,stroke:#e0852b
|
||
style C4 fill:#fef3e8,stroke:#e0852b
|
||
</div>
|
||
|
||
<h3 style="margin:24px 0 12px;font-size:16px">双重保障机制</h3>
|
||
<div class="table-wrap" style="max-height:none"><table>
|
||
<thead><tr><th>保障层</th><th>触发源</th><th>调用函数</th><th>频率</th><th>角色</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>第一层:定时预创建</td>
|
||
<td><strong>pg_cron</strong>(数据库自治)</td>
|
||
<td><code>run_electricity_partition_maintenance(3)</code></td>
|
||
<td>每月 25 号 03:00</td>
|
||
<td>主动保障 — 提前创建未来 3 个月分区</td>
|
||
</tr>
|
||
<tr>
|
||
<td>第一层:物化视图刷新</td>
|
||
<td><strong>pg_cron</strong>(数据库自治)</td>
|
||
<td><code>refresh_electricity_monthly()</code></td>
|
||
<td>每月 1 号 02:00</td>
|
||
<td>月度汇总数据刷新</td>
|
||
</tr>
|
||
<tr>
|
||
<td>第二层:写入兜底</td>
|
||
<td>Midway.js(应用层)</td>
|
||
<td><code>ensure_electricity_partition(collect_time)</code></td>
|
||
<td>每次 ICC 拉取批次</td>
|
||
<td>被动兜底 — 万一分区不存在时写入前自动创建</td>
|
||
</tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<div class="callout">
|
||
<h4>pg_cron 定时任务配置</h4>
|
||
<p>两个定时任务已在 <code>db_init.sql</code> 中通过 <code>cron.schedule()</code> 自动注册,数据库重启后任务仍然有效:</p>
|
||
<p><code>-- 每月25号凌晨3点:预创建未来3个月分区</code><br>
|
||
<code>SELECT cron.schedule('electricity_partition_maintenance', '0 3 25 * *', 'SELECT run_electricity_partition_maintenance(3)');</code><br><br>
|
||
<code>-- 每月1号凌晨2点:刷新物化视图</code><br>
|
||
<code>SELECT cron.schedule('electricity_monthly_refresh', '0 2 1 * *', 'SELECT refresh_electricity_monthly()');</code></p>
|
||
</div>
|
||
|
||
<h3 style="margin:24px 0 12px;font-size:16px">Midway.js 应用层兜底示例</h3>
|
||
<p style="font-size:13.5px;color:var(--muted);margin-bottom:12px">pg_cron 负责定时预创建,后端无需配置 @Cron。但 ICC 数据拉取服务在写入前仍建议调用 <code>ensure_electricity_partition()</code> 做兜底:</p>
|
||
<pre style="background:#1e293b;color:#e2e8f0;border-radius:12px;padding:20px;overflow-x:auto;font-size:13px;line-height:1.6;margin:14px 0"><code><span style="color:#94a3b8">// ICC 数据写入前兜底(在 ICC 同步服务中)</span>
|
||
<span style="color:#7dd3fc">async</span> <span style="color:#fbbf24">saveElectricityData</span>(items: ElectricityData[]) {
|
||
<span style="color:#7dd3fc">for</span> (<span style="color:#7dd3fc">const</span> item <span style="color:#7dd3fc">of</span> items) {
|
||
<span style="color:#94a3b8">// 写入前确保分区存在(99.9%的情况下什么都不做直接返回)</span>
|
||
<span style="color:#7dd3fc">await</span> <span style="color:#7dd3fc">this</span>.entityManager.query(
|
||
<span style="color:#86efac">'SELECT ensure_electricity_partition($1)'</span>,
|
||
[item.collectTime]
|
||
);
|
||
}
|
||
<span style="color:#94a3b8">// 批量写入</span>
|
||
<span style="color:#7dd3fc">await</span> <span style="color:#7dd3fc">this</span>.electricityRepo.save(items);
|
||
}</code></pre>
|
||
|
||
<h3 style="margin:24px 0 12px;font-size:16px">月度汇总物化视图</h3>
|
||
<p style="font-size:13.5px;color:var(--muted);margin-bottom:12px">物化视图 <code>mv_electricity_monthly</code> 按客户 + 线路 + 月份预聚合用电数据,用于历史数据分析和月报生成。每月初刷新一次,查询走预聚合数据,极快。</p>
|
||
<div class="table-wrap" style="max-height:none"><table>
|
||
<thead><tr><th>字段</th><th>类型</th><th>说明</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>customer_id</code></td><td>BIGINT</td><td>客户 ID(逻辑隔离键)</td></tr>
|
||
<tr><td><code>line_id</code></td><td>BIGINT</td><td>线路 ID</td></tr>
|
||
<tr><td><code>month</code></td><td>TEXT</td><td>月份(YYYY-MM 格式)</td></tr>
|
||
<tr><td><code>total_usage</code></td><td>NUMERIC</td><td>月度总用电量</td></tr>
|
||
<tr><td><code>avg_usage</code></td><td>NUMERIC</td><td>平均用电量</td></tr>
|
||
<tr><td><code>peak_usage</code></td><td>NUMERIC</td><td>峰值用电量</td></tr>
|
||
<tr><td><code>min_usage</code></td><td>NUMERIC</td><td>最低用电量</td></tr>
|
||
<tr><td><code>record_count</code></td><td>BIGINT</td><td>采集记录数</td></tr>
|
||
<tr><td><code>first_collect</code></td><td>TIMESTAMPTZ</td><td>最早采集时间</td></tr>
|
||
<tr><td><code>last_collect</code></td><td>TIMESTAMPTZ</td><td>最晚采集时间</td></tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<div class="callout">
|
||
<h4>刷新策略</h4>
|
||
<p><strong>首次初始化</strong>:脚本执行时自动 <code>REFRESH MATERIALIZED VIEW</code>(非并发模式)。<strong>后续刷新</strong>:通过 <code>refresh_electricity_monthly()</code> 函数,使用 <code>CONCURRENTLY</code> 不阻塞查询,函数内部自动处理异常回退。</p>
|
||
</div>
|
||
|
||
<h3 style="margin:24px 0 12px;font-size:16px">历史分区归档策略</h3>
|
||
<div class="table-wrap" style="max-height:none"><table>
|
||
<thead><tr><th>分区年龄</th><th>操作</th><th>原因</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>0 ~ 12 个月</td><td>保持在父表上</td><td>热数据,查询频繁</td></tr>
|
||
<tr><td>12 ~ 24 个月</td><td>保持在父表上</td><td>温数据,偶尔查询</td></tr>
|
||
<tr><td>超过 24 个月</td><td><code>DETACH PARTITION</code> 分离</td><td>冷数据,减少父表子分区数量,加速分区裁剪</td></tr>
|
||
<tr><td>需要分析冷数据</td><td>直接查子表 或 <code>ATTACH</code> 临时挂回</td><td>按需分析,分析完再 DETACH</td></tr>
|
||
<tr><td>确定不再需要</td><td><code>DROP TABLE</code></td><td>释放磁盘空间(需确认)</td></tr>
|
||
</tbody>
|
||
</table></div>
|
||
</section>
|
||
|
||
<footer>
|
||
<p>鑫潼智电系统 PostgreSQL 数据库设计文档 · 基于《需求分析报告 V1.0》 · 37 张表 · 3 个分区管理函数 · 1 个物化视图 · pg_cron 自动调度 · 2026-08</p>
|
||
</footer>
|
||
|
||
</div>
|
||
<script src="https://cdn.jsdelivr.net/npm/mermaid@10.9.1/dist/mermaid.min.js"></script>
|
||
<script>
|
||
mermaid.initialize({
|
||
startOnLoad: true, theme: 'default', securityLevel: 'loose',
|
||
themeVariables: {
|
||
primaryColor: '#e8f1ff', primaryTextColor: '#0f1e2e', primaryBorderColor: '#1d6fff',
|
||
lineColor: '#94a3b8', fontSize: '13px',
|
||
fontFamily: 'PingFang SC, Microsoft YaHei, sans-serif'
|
||
},
|
||
er: { useMaxWidth: true }
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|