78 lines
8.0 KiB
Plaintext
78 lines
8.0 KiB
Plaintext
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|||
|
|
<mxfile host="app.diagrams.net" modified="2026-04-14T10:41:00.000Z" agent="Oz" version="24.7.17">
|
|||
|
|
<diagram id="ctx-er" name="ER图">
|
|||
|
|
<mxGraphModel dx="1800" dy="1200" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1800" pageHeight="1200" math="0" shadow="0">
|
|||
|
|
<root>
|
|||
|
|
<mxCell id="0"/>
|
|||
|
|
<mxCell id="1" parent="0"/>
|
|||
|
|
<mxCell id="2" value="00 组织与权限上下文 - ER图" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=22;fontStyle=1;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="20" y="20" width="450" height="30" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="3" value="统一隔离键:adcode / tenant_id / tenant_path / dept_id / dept_path" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#666666;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="20" y="52" width="720" height="24" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="10" value="tb_sys_tenant<br>PK tenant_id<br>FK parent_tenant_id -> tb_sys_tenant.tenant_id<br>tenant_name, tenant_type, status<br>adcode, tenant_path, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="40" y="120" width="280" height="140" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="11" value="tb_sys_dept<br>PK dept_id<br>FK parent_dept_id -> tb_sys_dept.dept_id<br>FK tenant_id -> tb_sys_tenant.tenant_id<br>dept_name, dept_type<br>adcode, tenant_path, dept_path, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="360" y="120" width="300" height="150" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="12" value="tb_sys_user<br>PK user_id, UK username<br>FK tenant_id -> tb_sys_tenant.tenant_id<br>FK dept_id -> tb_sys_dept.dept_id<br>display_name, password_hash, status<br>adcode, tenant_path, dept_path, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="700" y="120" width="320" height="150" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="13" value="tb_sys_role<br>PK role_id, UK role_code<br>FK tenant_id -> tb_sys_tenant.tenant_id<br>role_name<br>dept_id, dept_path, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="700" y="320" width="290" height="130" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="14" value="tb_sys_permission<br>PK permission_id, UK permission_code<br>FK tenant_id -> tb_sys_tenant.tenant_id<br>permission_name<br>dept_id, dept_path, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="1030" y="320" width="320" height="130" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="15" value="rel_user_role<br>PK (user_id, role_id)<br>FK user_id -> tb_sys_user.user_id<br>FK role_id -> tb_sys_role.role_id<br>tenant_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="1030" y="120" width="290" height="130" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="16" value="rel_role_permission<br>PK (role_id, permission_id)<br>FK role_id -> tb_sys_role.role_id<br>FK permission_id -> tb_sys_permission.permission_id<br>tenant_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="1360" y="120" width="320" height="130" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="17" value="tb_auth_refresh_token<br>PK token_id<br>FK user_id -> tb_sys_user.user_id<br>refresh_token, expire_at, revoked<br>tenant_id, dept_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="40" y="330" width="300" height="130" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="18" value="tb_auth_login_audit<br>PK audit_id<br>FK user_id -> tb_sys_user.user_id<br>username, login_ip, login_status<br>tenant_id, dept_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="360" y="330" width="300" height="130" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="19" value="设计方法与原因<br>1) DDD上下文先行:权限域作为业务域前置依赖<br>2) RBAC最小闭环:用户-角色-权限拆分降低耦合<br>3) 多租户统一隔离键:保证后续业务表可水平扩展<br>4) 认证审计分离:令牌高频写与审计查询分流" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontSize=12;" parent="1" vertex="1">
|
|||
|
|
<mxGeometry x="1360" y="320" width="320" height="170" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="100" value="N:1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" parent="1" source="11" target="10" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="101" value="N:1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" parent="1" source="12" target="10" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="102" value="N:1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" parent="1" source="12" target="11" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="103" value="N:1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#9673a6;" parent="1" source="13" target="10" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="104" value="M:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#d6b656;" parent="1" source="15" target="12" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="105" value="M:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#d6b656;" parent="1" source="15" target="13" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="106" value="M:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#d6b656;" parent="1" source="16" target="13" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="107" value="M:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#d6b656;" parent="1" source="16" target="14" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="108" value="N:1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#b85450;" parent="1" source="17" target="12" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
<mxCell id="109" value="N:1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#b85450;" parent="1" source="18" target="12" edge="1">
|
|||
|
|
<mxGeometry relative="1" as="geometry"/>
|
|||
|
|
</mxCell>
|
|||
|
|
</root>
|
|||
|
|
</mxGraphModel>
|
|||
|
|
</diagram>
|
|||
|
|
</mxfile>
|