Complete core functions #9
@@ -10,15 +10,15 @@ java -Djarmode=layertools -jar target/*.jar extract --destination target/extract
|
||||
|
||||
if [[ "${JAR_VERSION}" =~ ^.*SNAPSHOT$ ]]
|
||||
then
|
||||
docker build -t hub.fatweb.top/fatweb-api:snapshot-latest -t hub.fatweb.top/fatweb-api:$JAR_VERSION -t hub.fatweb.top/fatweb-api:$JAR_VERSION-${BUILD_TIME} .
|
||||
docker build -t hub.fatweb.top/oxygen-api:snapshot-latest -t hub.fatweb.top/oxygen-api:$JAR_VERSION -t hub.fatweb.top/oxygen-api:$JAR_VERSION-${BUILD_TIME} .
|
||||
cat "${KEYS_PATH}/docker.password" | docker login hub.fatweb.top -u jenkins --password-stdin
|
||||
docker push hub.fatweb.top/fatweb-api:snapshot-latest
|
||||
docker push hub.fatweb.top/fatweb-api:$JAR_VERSION
|
||||
docker push hub.fatweb.top/fatweb-api:$JAR_VERSION-${BUILD_TIME}
|
||||
docker push hub.fatweb.top/oxygen-api:snapshot-latest
|
||||
docker push hub.fatweb.top/oxygen-api:$JAR_VERSION
|
||||
docker push hub.fatweb.top/oxygen-api:$JAR_VERSION-${BUILD_TIME}
|
||||
else
|
||||
docker build -t hub.fatweb.top/fatweb-api:latest -t hub.fatweb.top/fatweb-api:$JAR_VERSION -t hub.fatweb.top/fatweb-api:$JAR_VERSION-${BUILD_TIME} .
|
||||
docker build -t hub.fatweb.top/oxygen-api:latest -t hub.fatweb.top/oxygen-api:$JAR_VERSION -t hub.fatweb.top/oxygen-api:$JAR_VERSION-${BUILD_TIME} .
|
||||
cat "${KEYS_PATH}/docker.password" | docker login hub.fatweb.top -u jenkins --password-stdin
|
||||
docker push hub.fatweb.top/fatweb-api:latest
|
||||
docker push hub.fatweb.top/fatweb-api:$JAR_VERSION
|
||||
docker push hub.fatweb.top/fatweb-api:$JAR_VERSION-${BUILD_TIME}
|
||||
docker push hub.fatweb.top/oxygen-api:latest
|
||||
docker push hub.fatweb.top/oxygen-api:$JAR_VERSION
|
||||
docker push hub.fatweb.top/oxygen-api:$JAR_VERSION-${BUILD_TIME}
|
||||
fi
|
||||
@@ -1,12 +0,0 @@
|
||||
drop table if exists t_user;
|
||||
|
||||
create table if not exists t_user
|
||||
(
|
||||
id bigint not null primary key,
|
||||
username varchar(20) not null comment '用户名',
|
||||
password char(70) not null comment '密码',
|
||||
enable int not null comment '启用',
|
||||
deleted bigint not null default 0,
|
||||
version int not null default 0,
|
||||
constraint t_user_unique unique (username, deleted)
|
||||
) comment '用户';
|
||||
982
doc/database.drawio
Normal file
982
doc/database.drawio
Normal file
@@ -0,0 +1,982 @@
|
||||
<mxfile host="Electron" modified="2024-01-16T02:51:10.691Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.1.18 Chrome/120.0.6099.199 Electron/28.1.2 Safari/537.36" etag="flxtUq0V3qvy_peuJ5a6" version="22.1.18" type="device">
|
||||
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
|
||||
<mxGraphModel dx="2074" dy="2415" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
|
||||
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-0" value="t_s_user 系统-用户表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1210" y="-350" width="320" height="480" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-1" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="30" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-2" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-1" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-3" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-1" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-4" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="60" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-5" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-4" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-6" value="username 用户名 - unique" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-4" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-7" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="90" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-8" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-7" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-9" value="password 密码" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-7" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-10" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="120" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-11" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-10" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-12" value="verify 验证邮箱&nbsp;- unique" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-10" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-13" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="150" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-14" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-13" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-15" value="forget 忘记密码 - unique" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-13" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-16" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="180" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-17" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-16" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-18" value="locking 锁定" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-16" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-19" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="210" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-20" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-19" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-21" value="expiration 过期时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-19" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-22" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="240" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-23" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-22" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-24" value="credentials_expiration 认证过期时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-22" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-25" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="270" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-26" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-25" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-27" value="enable 启用" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-25" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-28" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="300" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-29" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-28" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-30" value="current_login_time 当前登录时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-28" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-31" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="330" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-32" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-31" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-33" value="current_login_ip 当前登录 IP" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-31" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-34" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="360" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-35" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-34" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-36" value="last_login_time 上次登录时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-34" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-37" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="390" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-38" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-37" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-39" value="last_login_ip 上次登录 IP" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-37" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-40" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="420" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-41" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-40" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-42" value="create_time 创建时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-40" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-43" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-0" vertex="1">
|
||||
<mxGeometry y="450" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-44" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-43" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-45" value="update_time 修改时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-43" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-49" value="t_s_power_type 系统-权限类型表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1232.51" y="580" width="275" height="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-50" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-49" vertex="1">
|
||||
<mxGeometry y="30" width="275" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-51" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-50" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-52" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-50" vertex="1">
|
||||
<mxGeometry x="30" width="245" height="30" as="geometry">
|
||||
<mxRectangle width="245" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-53" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-49" vertex="1">
|
||||
<mxGeometry y="60" width="275" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-54" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-53" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-55" value="name 权限类型名" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-53" vertex="1">
|
||||
<mxGeometry x="30" width="245" height="30" as="geometry">
|
||||
<mxRectangle width="245" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-63" value="t_s_power 系统-权限表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1270" y="430" width="200" height="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-64" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-63" vertex="1">
|
||||
<mxGeometry y="30" width="200" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-65" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-64" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-66" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-64" vertex="1">
|
||||
<mxGeometry x="30" width="170" height="30" as="geometry">
|
||||
<mxRectangle width="170" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-67" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-63" vertex="1">
|
||||
<mxGeometry y="60" width="200" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-68" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-67" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-69" value="type_id 权限类型" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-67" vertex="1">
|
||||
<mxGeometry x="30" width="170" height="30" as="geometry">
|
||||
<mxRectangle width="170" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-80" value="t_s_menu 系统-菜单表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1350" y="760" width="230" height="180" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-81" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-80" vertex="1">
|
||||
<mxGeometry y="30" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-82" value="PK,FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-81" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-83" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-81" vertex="1">
|
||||
<mxGeometry x="70" width="160" height="30" as="geometry">
|
||||
<mxRectangle width="160" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-84" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-80" vertex="1">
|
||||
<mxGeometry y="60" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-85" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-84" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-86" value="name 菜单名" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-84" vertex="1">
|
||||
<mxGeometry x="70" width="160" height="30" as="geometry">
|
||||
<mxRectangle width="160" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-87" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-80" vertex="1">
|
||||
<mxGeometry y="90" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-88" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-87" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-89" value="url URL" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-87" vertex="1">
|
||||
<mxGeometry x="70" width="160" height="30" as="geometry">
|
||||
<mxRectangle width="160" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-90" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-80" vertex="1">
|
||||
<mxGeometry y="120" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-91" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-90" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-92" value="parent_id 父ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-90" vertex="1">
|
||||
<mxGeometry x="70" width="160" height="30" as="geometry">
|
||||
<mxRectangle width="160" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-106" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-80" vertex="1">
|
||||
<mxGeometry y="150" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-107" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=0;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-106" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-108" value="module_id 模块ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=0;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-106" vertex="1">
|
||||
<mxGeometry x="70" width="160" height="30" as="geometry">
|
||||
<mxRectangle width="160" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-93" value="t_s_func 系统-功能表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1120" y="760" width="210" height="150" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-94" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-93" vertex="1">
|
||||
<mxGeometry y="30" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-95" value="PK, FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-94" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-96" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-94" vertex="1">
|
||||
<mxGeometry x="70" width="140" height="30" as="geometry">
|
||||
<mxRectangle width="140" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-97" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-93" vertex="1">
|
||||
<mxGeometry y="60" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-98" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-97" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-99" value="name 功能名" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-97" vertex="1">
|
||||
<mxGeometry x="70" width="140" height="30" as="geometry">
|
||||
<mxRectangle width="140" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-100" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-93" vertex="1">
|
||||
<mxGeometry y="90" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-101" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-100" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-102" value="parent_id 父ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-100" vertex="1">
|
||||
<mxGeometry x="70" width="140" height="30" as="geometry">
|
||||
<mxRectangle width="140" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-103" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-93" vertex="1">
|
||||
<mxGeometry y="120" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-104" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-103" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-105" value="menu_id 菜单ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-103" vertex="1">
|
||||
<mxGeometry x="70" width="140" height="30" as="geometry">
|
||||
<mxRectangle width="140" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-109" value="t_s_module 系统-模块表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1650" y="760" width="210" height="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-110" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-109" vertex="1">
|
||||
<mxGeometry y="30" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-111" value="PK,FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-110" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-112" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-110" vertex="1">
|
||||
<mxGeometry x="70" width="140" height="30" as="geometry">
|
||||
<mxRectangle width="140" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-113" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-109" vertex="1">
|
||||
<mxGeometry y="60" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-114" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-113" vertex="1">
|
||||
<mxGeometry width="70" height="30" as="geometry">
|
||||
<mxRectangle width="70" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-115" value="name 模块名" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-113" vertex="1">
|
||||
<mxGeometry x="70" width="140" height="30" as="geometry">
|
||||
<mxRectangle width="140" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-122" value="t_s_operation 系统-操作表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="820" y="760" width="230" height="150" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-123" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-122" vertex="1">
|
||||
<mxGeometry y="30" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-124" value="PK,FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-123" vertex="1">
|
||||
<mxGeometry width="60" height="30" as="geometry">
|
||||
<mxRectangle width="60" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-125" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-123" vertex="1">
|
||||
<mxGeometry x="60" width="170" height="30" as="geometry">
|
||||
<mxRectangle width="170" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-126" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-122" vertex="1">
|
||||
<mxGeometry y="60" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-127" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-126" vertex="1">
|
||||
<mxGeometry width="60" height="30" as="geometry">
|
||||
<mxRectangle width="60" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-128" value="name 操作名" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-126" vertex="1">
|
||||
<mxGeometry x="60" width="170" height="30" as="geometry">
|
||||
<mxRectangle width="170" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-129" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-122" vertex="1">
|
||||
<mxGeometry y="90" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-130" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-129" vertex="1">
|
||||
<mxGeometry width="60" height="30" as="geometry">
|
||||
<mxRectangle width="60" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-131" value="code 操作编码" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-129" vertex="1">
|
||||
<mxGeometry x="60" width="170" height="30" as="geometry">
|
||||
<mxRectangle width="170" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-132" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-122" vertex="1">
|
||||
<mxGeometry y="120" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-133" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-132" vertex="1">
|
||||
<mxGeometry width="60" height="30" as="geometry">
|
||||
<mxRectangle width="60" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-134" value="func_id 功能ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-132" vertex="1">
|
||||
<mxGeometry x="60" width="170" height="30" as="geometry">
|
||||
<mxRectangle width="170" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-135" value="t_s_group 系统-用户组表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="570" y="160" width="240" height="180" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-136" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-135" vertex="1">
|
||||
<mxGeometry y="30" width="240" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-137" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-136" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-138" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-136" vertex="1">
|
||||
<mxGeometry x="30" width="210" height="30" as="geometry">
|
||||
<mxRectangle width="210" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-139" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-135" vertex="1">
|
||||
<mxGeometry y="60" width="240" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-140" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-139" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-141" value="name 用户组名&nbsp;- unique" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-139" vertex="1">
|
||||
<mxGeometry x="30" width="210" height="30" as="geometry">
|
||||
<mxRectangle width="210" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-142" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-135" vertex="1">
|
||||
<mxGeometry y="90" width="240" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-143" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-142" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-144" value="enable 启用" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-142" vertex="1">
|
||||
<mxGeometry x="30" width="210" height="30" as="geometry">
|
||||
<mxRectangle width="210" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-145" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-135" vertex="1">
|
||||
<mxGeometry y="120" width="240" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-146" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-145" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-147" value="create_time 创建时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-145" vertex="1">
|
||||
<mxGeometry x="30" width="210" height="30" as="geometry">
|
||||
<mxRectangle width="210" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-148" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-135" vertex="1">
|
||||
<mxGeometry y="150" width="240" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-149" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-148" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-150" value="update_time 修改时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-148" vertex="1">
|
||||
<mxGeometry x="30" width="210" height="30" as="geometry">
|
||||
<mxRectangle width="210" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-154" value="t_r_user_group 中间表-系统-用户-用户组" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="780" y="-290" width="340" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-155" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-154" vertex="1">
|
||||
<mxGeometry y="30" width="340" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-156" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-155" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-157" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-155" vertex="1">
|
||||
<mxGeometry x="30" width="310" height="30" as="geometry">
|
||||
<mxRectangle width="310" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-158" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-154" vertex="1">
|
||||
<mxGeometry y="60" width="340" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-159" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-158" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-160" value="user_id 用户ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-158" vertex="1">
|
||||
<mxGeometry x="30" width="310" height="30" as="geometry">
|
||||
<mxRectangle width="310" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-161" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-154" vertex="1">
|
||||
<mxGeometry y="90" width="340" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-162" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-161" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-163" value="group_id 用户组ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-161" vertex="1">
|
||||
<mxGeometry x="30" width="310" height="30" as="geometry">
|
||||
<mxRectangle width="310" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-167" value="t_s_role 系统-角色表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1940" y="160" width="210" height="180" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-168" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-167" vertex="1">
|
||||
<mxGeometry y="30" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-169" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-168" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-170" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-168" vertex="1">
|
||||
<mxGeometry x="30" width="180" height="30" as="geometry">
|
||||
<mxRectangle width="180" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-171" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-167" vertex="1">
|
||||
<mxGeometry y="60" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-172" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-171" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-173" value="name 角色名&nbsp;- unique" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-171" vertex="1">
|
||||
<mxGeometry x="30" width="180" height="30" as="geometry">
|
||||
<mxRectangle width="180" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-174" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-167" vertex="1">
|
||||
<mxGeometry y="90" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-175" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-174" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-176" value="enable 启用" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-174" vertex="1">
|
||||
<mxGeometry x="30" width="180" height="30" as="geometry">
|
||||
<mxRectangle width="180" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-177" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-167" vertex="1">
|
||||
<mxGeometry y="120" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-178" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-177" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-179" value="create_time 创建时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-177" vertex="1">
|
||||
<mxGeometry x="30" width="180" height="30" as="geometry">
|
||||
<mxRectangle width="180" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-180" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-167" vertex="1">
|
||||
<mxGeometry y="150" width="210" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-181" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-180" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-182" value="update_time 修改时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-180" vertex="1">
|
||||
<mxGeometry x="30" width="180" height="30" as="geometry">
|
||||
<mxRectangle width="180" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-183" value="t_r_role_group 中间表-系统-角色-用户组" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1530" y="190" width="330" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-184" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-183" vertex="1">
|
||||
<mxGeometry y="30" width="330" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-185" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-184" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-186" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-184" vertex="1">
|
||||
<mxGeometry x="30" width="300" height="30" as="geometry">
|
||||
<mxRectangle width="300" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-187" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-183" vertex="1">
|
||||
<mxGeometry y="60" width="330" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-188" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-187" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-189" value="role_id 角色ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-187" vertex="1">
|
||||
<mxGeometry x="30" width="300" height="30" as="geometry">
|
||||
<mxRectangle width="300" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-190" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-183" vertex="1">
|
||||
<mxGeometry y="90" width="330" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-191" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-190" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-192" value="group_id 用户组ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-190" vertex="1">
|
||||
<mxGeometry x="30" width="300" height="30" as="geometry">
|
||||
<mxRectangle width="300" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-196" value="t_r_user_role 中间表-系统-用户-角色" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1610" y="-290" width="300" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-197" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-196" vertex="1">
|
||||
<mxGeometry y="30" width="300" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-198" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-197" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-199" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-197" vertex="1">
|
||||
<mxGeometry x="30" width="270" height="30" as="geometry">
|
||||
<mxRectangle width="270" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-200" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-196" vertex="1">
|
||||
<mxGeometry y="60" width="300" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-201" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-200" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-202" value="user_id 用户ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-200" vertex="1">
|
||||
<mxGeometry x="30" width="270" height="30" as="geometry">
|
||||
<mxRectangle width="270" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-203" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-196" vertex="1">
|
||||
<mxGeometry y="90" width="300" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-204" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-203" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-205" value="role_id 角色ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-203" vertex="1">
|
||||
<mxGeometry x="30" width="270" height="30" as="geometry">
|
||||
<mxRectangle width="270" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-209" value="t_r_power_role 中间表-系统-权限-角色" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="880" y="190" width="320" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-210" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-209" vertex="1">
|
||||
<mxGeometry y="30" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-211" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-210" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-212" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-210" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-213" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-209" vertex="1">
|
||||
<mxGeometry y="60" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-214" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-213" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-215" value="power_id 权限ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-213" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-216" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-209" vertex="1">
|
||||
<mxGeometry y="90" width="320" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-217" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-216" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-218" value="role_id 角色ID" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-216" vertex="1">
|
||||
<mxGeometry x="30" width="290" height="30" as="geometry">
|
||||
<mxRectangle width="290" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-222" value="t_s_user_info 系统-用户资料表" style="shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;align=center;resizeLast=1;html=1;fontSize=16;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
|
||||
<mxGeometry x="1238.13" y="-650" width="263.75" height="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-223" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-222" vertex="1">
|
||||
<mxGeometry y="30" width="263.75" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-224" value="PK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;fontStyle=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-223" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-225" value="id" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;fontStyle=5;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-223" vertex="1">
|
||||
<mxGeometry x="30" width="233.75" height="30" as="geometry">
|
||||
<mxRectangle width="233.75" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-226" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-222" vertex="1">
|
||||
<mxGeometry y="60" width="263.75" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-227" value="FK" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-226" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-228" value="user_id 用户ID&nbsp;- unique" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-226" vertex="1">
|
||||
<mxGeometry x="30" width="233.75" height="30" as="geometry">
|
||||
<mxRectangle width="233.75" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-229" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-222" vertex="1">
|
||||
<mxGeometry y="90" width="263.75" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-230" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-229" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-231" value="nickname 昵称" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-229" vertex="1">
|
||||
<mxGeometry x="30" width="233.75" height="30" as="geometry">
|
||||
<mxRectangle width="233.75" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-232" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-222" vertex="1">
|
||||
<mxGeometry y="120" width="263.75" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-233" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-232" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-234" value="avatar 头像" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;whiteSpace=wrap;html=1;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-232" vertex="1">
|
||||
<mxGeometry x="30" width="233.75" height="30" as="geometry">
|
||||
<mxRectangle width="233.75" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-235" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-222" vertex="1">
|
||||
<mxGeometry y="150" width="263.75" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-236" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-235" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-237" value="email 邮箱 - unique" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-235" vertex="1">
|
||||
<mxGeometry x="30" width="233.75" height="30" as="geometry">
|
||||
<mxRectangle width="233.75" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-238" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-222" vertex="1">
|
||||
<mxGeometry y="180" width="263.75" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-239" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-238" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-240" value="create_time 创建时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-238" vertex="1">
|
||||
<mxGeometry x="30" width="233.75" height="30" as="geometry">
|
||||
<mxRectangle width="233.75" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-241" value="" style="shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-222" vertex="1">
|
||||
<mxGeometry y="210" width="263.75" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-242" value="" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;editable=1;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-241" vertex="1">
|
||||
<mxGeometry width="30" height="30" as="geometry">
|
||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-243" value="update_time 修改时间" style="shape=partialRectangle;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;overflow=hidden;fontSize=16;" parent="SgG1xhS9EfBviSQqJXSq-241" vertex="1">
|
||||
<mxGeometry x="30" width="233.75" height="30" as="geometry">
|
||||
<mxRectangle width="233.75" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-263" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-64" target="SgG1xhS9EfBviSQqJXSq-123" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1030" y="470" as="sourcePoint" />
|
||||
<mxPoint x="1080" y="420" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="1080" y="630" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-265" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-64" target="SgG1xhS9EfBviSQqJXSq-94" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="960" y="490" as="sourcePoint" />
|
||||
<mxPoint x="1010" y="440" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="1090" y="640" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-266" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-64" target="SgG1xhS9EfBviSQqJXSq-81" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1520" y="490" as="sourcePoint" />
|
||||
<mxPoint x="1570" y="440" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="1610" y="630" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-267" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-64" target="SgG1xhS9EfBviSQqJXSq-110" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1700" y="520" as="sourcePoint" />
|
||||
<mxPoint x="1750" y="470" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="1620" y="640" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-268" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-67" target="SgG1xhS9EfBviSQqJXSq-50" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1200" y="590" as="sourcePoint" />
|
||||
<mxPoint x="1250" y="540" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="1210" y="560" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-269" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-213" target="SgG1xhS9EfBviSQqJXSq-64" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1430" y="180" as="sourcePoint" />
|
||||
<mxPoint x="1480" y="130" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-271" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-187" target="SgG1xhS9EfBviSQqJXSq-64" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1350" y="320" as="sourcePoint" />
|
||||
<mxPoint x="1400" y="270" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-273" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-210" target="SgG1xhS9EfBviSQqJXSq-136" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="940" y="470" as="sourcePoint" />
|
||||
<mxPoint x="990" y="420" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-274" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-190" target="SgG1xhS9EfBviSQqJXSq-168" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1890" y="460" as="sourcePoint" />
|
||||
<mxPoint x="1940" y="410" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-275" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-161" target="SgG1xhS9EfBviSQqJXSq-136" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1100" y="-560" as="sourcePoint" />
|
||||
<mxPoint x="920" y="-500" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="520" y="30" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-276" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-203" target="SgG1xhS9EfBviSQqJXSq-168" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2270" y="80" as="sourcePoint" />
|
||||
<mxPoint x="2320" y="30" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="2200" y="20" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-277" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-158" target="SgG1xhS9EfBviSQqJXSq-1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="830" y="-540" as="sourcePoint" />
|
||||
<mxPoint x="880" y="-590" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="1160" y="-260" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-278" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-200" target="SgG1xhS9EfBviSQqJXSq-1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1770" y="-410" as="sourcePoint" />
|
||||
<mxPoint x="1820" y="-460" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="SgG1xhS9EfBviSQqJXSq-279" value="" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;curved=0;rounded=0;endSize=8;startSize=8;fontSize=12;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="SgG1xhS9EfBviSQqJXSq-226" target="SgG1xhS9EfBviSQqJXSq-1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="940" y="-450" as="sourcePoint" />
|
||||
<mxPoint x="990" y="-500" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="1160" y="-430" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
343
doc/permission.drawio
Normal file
343
doc/permission.drawio
Normal file
@@ -0,0 +1,343 @@
|
||||
<mxfile host="Electron" modified="2023-12-06T03:01:42.983Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.1.2 Chrome/114.0.5735.289 Electron/25.9.4 Safari/537.36" etag="y2TYcAf6vo8TrTOF2c2W" version="22.1.2" type="device">
|
||||
<diagram name="第 1 页" id="R2cIEvIs15c5_Cru6pMt">
|
||||
<mxGraphModel dx="17124" dy="11311" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-4" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-1" target="SDpw32q9kxCI3RyRmRBe-3">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-6" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-1" target="SDpw32q9kxCI3RyRmRBe-3">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-9" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-7">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-11" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-10">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-14" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-13">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-16" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-15">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-18" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-17">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-1" value="系统<br style="font-size: 12px;">1000000" style="rounded=1;whiteSpace=wrap;html=1;fontSize=12;flipH=0;flipV=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="-15571" y="-8884" width="114" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-23" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-3" target="SDpw32q9kxCI3RyRmRBe-22">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-3" value="系统管理<br style="font-size: 12px;">1990000<br>/system" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="-15344" y="-8884" width="114" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-25" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-24">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-30" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-29">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-33" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-32">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-34" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-32">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-35" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-32">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-37" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-7" target="SDpw32q9kxCI3RyRmRBe-36">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-7" value="用户管理<br style="font-size: 12px;">1010000<br>/system/user" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14329" y="-9774" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-46" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-10" target="SDpw32q9kxCI3RyRmRBe-38">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-47" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-10" target="SDpw32q9kxCI3RyRmRBe-39">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-48" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-10" target="SDpw32q9kxCI3RyRmRBe-40">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-49" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-10" target="SDpw32q9kxCI3RyRmRBe-41">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-10" value="角色管理<br style="font-size: 12px;">1020000<br>/system/role" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14329" y="-9149.5" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-50" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-13" target="SDpw32q9kxCI3RyRmRBe-42">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-51" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-13" target="SDpw32q9kxCI3RyRmRBe-43">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-52" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-13" target="SDpw32q9kxCI3RyRmRBe-44">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-53" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-13" target="SDpw32q9kxCI3RyRmRBe-45">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-13" value="用户组管理<br style="font-size: 12px;">1030000<br>/system/group" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14329" y="-8384" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-57" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-15" target="SDpw32q9kxCI3RyRmRBe-56">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-15" value="日志管理<br style="font-size: 12px;">1510000<br>/system/log" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14329" y="-7984" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-59" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-17" target="SDpw32q9kxCI3RyRmRBe-58">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-61" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-17" target="SDpw32q9kxCI3RyRmRBe-60">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-17" value="系统设置<br style="font-size: 12px;">1520000<br>/system/settings" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;flipV=1;container=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14329" y="-7755.5" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-55" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-22" target="SDpw32q9kxCI3RyRmRBe-54">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-22" value="权限管理<br style="font-size: 12px;">1040000<br>/system/power" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;flipH=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14329" y="-8073" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-63" value="" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-24" target="SDpw32q9kxCI3RyRmRBe-62">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-78" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-24" target="SDpw32q9kxCI3RyRmRBe-69">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-79" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-24" target="SDpw32q9kxCI3RyRmRBe-71">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-24" value="查询<br style="font-size: 12px;">1010100" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-9979" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-80" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-29" target="SDpw32q9kxCI3RyRmRBe-72">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-29" value="增加<br style="font-size: 12px;">1010200" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-9818" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-81" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-32" target="SDpw32q9kxCI3RyRmRBe-73">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-82" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-32" target="SDpw32q9kxCI3RyRmRBe-74">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-32" value="修改<br>1010300" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-9706" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-83" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-36" target="SDpw32q9kxCI3RyRmRBe-75">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-84" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-36" target="SDpw32q9kxCI3RyRmRBe-77">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-36" value="删除<br>1010400" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-9557" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-94" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-38" target="SDpw32q9kxCI3RyRmRBe-86">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-95" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-38" target="SDpw32q9kxCI3RyRmRBe-87">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-96" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-38" target="SDpw32q9kxCI3RyRmRBe-88">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-38" value="查询<br style="font-size: 12px;">1020100" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-9366" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-97" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-39" target="SDpw32q9kxCI3RyRmRBe-89">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-39" value="增加<br style="font-size: 12px;">1020200" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-9184" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-98" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-40" target="SDpw32q9kxCI3RyRmRBe-90">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-99" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-40" target="SDpw32q9kxCI3RyRmRBe-91">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-40" value="修改<br>1020300" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-9052.5" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-100" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-41" target="SDpw32q9kxCI3RyRmRBe-92">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-102" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-41" target="SDpw32q9kxCI3RyRmRBe-93">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-41" value="删除<br>1020400" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-8893.5" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-111" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-42" target="SDpw32q9kxCI3RyRmRBe-103">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-112" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-42" target="SDpw32q9kxCI3RyRmRBe-104">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-113" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-42" target="SDpw32q9kxCI3RyRmRBe-105">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-42" value="查询<br style="font-size: 12px;">1030100" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-8663" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-114" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-43" target="SDpw32q9kxCI3RyRmRBe-106">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-43" value="增加<br style="font-size: 12px;">1030200" style="whiteSpace=wrap;html=1;fontSize=12;rounded=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-8487" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-115" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-44" target="SDpw32q9kxCI3RyRmRBe-107">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-116" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-44" target="SDpw32q9kxCI3RyRmRBe-108">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-44" value="修改<br>1030300" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-8354" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-117" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-45" target="SDpw32q9kxCI3RyRmRBe-109">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-118" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-45" target="SDpw32q9kxCI3RyRmRBe-110">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-45" value="删除<br>1030400" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-8201" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-120" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-54" target="SDpw32q9kxCI3RyRmRBe-119">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-54" value="查询<br>1040100" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-8073" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-123" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-56" target="SDpw32q9kxCI3RyRmRBe-122">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-56" value="查询<br>10510100" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-7984" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-132" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-58" target="SDpw32q9kxCI3RyRmRBe-124">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-133" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-58" target="SDpw32q9kxCI3RyRmRBe-127">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-58" value="查询<br>1520100" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-7840.5" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-134" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-60" target="SDpw32q9kxCI3RyRmRBe-130">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-136" style="edgeStyle=none;curved=1;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startSize=8;endSize=8;" edge="1" parent="1" source="SDpw32q9kxCI3RyRmRBe-60" target="SDpw32q9kxCI3RyRmRBe-131">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-60" value="修改<br>1520300" style="whiteSpace=wrap;html=1;rounded=1;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="-14020" y="-7670.5" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-62" value="单个<br style="font-size: 12px;">1010101<br style="font-size: 12px;">system:user:query:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-10055" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-69" value="全部<br>1010102<br>system:user:query:all" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9979" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-70" value="" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13056" y="-8941" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-71" value="列表<br>1010103<br>system:user:query:list" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9903" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-72" value="单个<br>1010201<br>system:user:add:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9818" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-73" value="单个<br>1010301<br>system:user:modify:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9743" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-74" value="密码<br>1010302<br>system:user:modify:password" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9669" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-75" value="单个<br>1010401<br>system:user:delete:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9592" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-77" value="多个<br>1010402<br>system:user:delete:multiple" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9522" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-86" value="单个<br style="font-size: 12px;">1020101<br style="font-size: 12px;">system:role:query:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9442" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-87" value="全部<br>1020102<br>system:role:query:all" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9366" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-88" value="列表<br>1020103<br>system:role:query:list" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9290" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-89" value="单个<br>1020201<br>system:role:add:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9184" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-90" value="单个<br>1020301<br>system:role:modify:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9090" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-91" value="状态<br>1020302<br>system:role:modify:status" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-9015" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-92" value="单个<br>1020401<br>system:role:delete:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8930" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-93" value="多个<br>1020402<br>system:role:delete:multiple" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8857" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-103" value="单个<br style="font-size: 12px;">1030101<br style="font-size: 12px;">system:group:query:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8739" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-104" value="全部<br>1030102<br>system:group:query:all" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8663" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-105" value="列表<br>1030103<br>system:group:query:list" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8587" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-106" value="单个<br>1030201<br>system:group:add:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8487" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-107" value="单个<br>1030301<br>system:group:modify:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8391.5" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-108" value="状态<br>1030302<br>system:group:modify:status" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8316.5" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-109" value="单个<br>1030401<br>system:group:delete:one" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8233" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-110" value="多个<br>1030402<br>system:group:delete:multiple" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8160" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-119" value="列表<br>1040103<br>system:power:query:list" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-8073" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-122" value="全部<br>1510101<br>system:log:query:all" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-7984" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-124" value="基础<br>1520101<br>system:settings:query:base" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-7879" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-127" value="邮件<br>1520102<br>system:settings:query:mail" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-7802" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-130" value="基础<br>1520301<br>system:settings:modify:base" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-7709" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="SDpw32q9kxCI3RyRmRBe-131" value="邮件<br>1520302<br>system:settings:modify:mail" style="whiteSpace=wrap;html=1;rounded=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-13754" y="-7632" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
142
pom.xml
142
pom.xml
@@ -5,14 +5,28 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.1.4</version>
|
||||
<version>3.2.1</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>top.fatweb</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>fatweb-api</name>
|
||||
<description>fatweb-api</description>
|
||||
<name>oxygen-api</name>
|
||||
<description>oxygen-api</description>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sonatype-oss-snapshots</id>
|
||||
<name>sonatype-oss-snapshots</name>
|
||||
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
@@ -28,7 +42,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||
<version>4.3.0</version>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
@@ -61,15 +75,12 @@
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<kotlin.version>1.8.22</kotlin.version>
|
||||
<kotlin.version>1.9.21</kotlin.version>
|
||||
<build.timestamp>${maven.build.timestamp}</build.timestamp>
|
||||
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss</maven.build.timestamp.format>
|
||||
<flyway.version>9.22.3</flyway.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
@@ -79,29 +90,27 @@
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
@@ -112,51 +121,91 @@
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.lianjiatech</groupId>
|
||||
<artifactId>retrofit-spring-boot-starter</artifactId>
|
||||
<version>3.0.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.5.3.2</version>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter-test</artifactId>
|
||||
<version>3.5.3.2</version>
|
||||
<scope>test</scope>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.2.19</version>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
</dependency>
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
<version>3.5.3.2</version>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
<version>2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||
<version>3.5.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.44.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
||||
<version>4.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-mysql</artifactId>
|
||||
<version>${flyway.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter-test</artifactId>
|
||||
<version>3.5.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
<version>3.5.5</version>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<groupId>top.fatweb</groupId>
|
||||
<artifactId>avatar-generator</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<groupId>com.github.oshi</groupId>
|
||||
<artifactId>oshi-core</artifactId>
|
||||
<version>6.4.9</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -202,6 +251,19 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.dokka</groupId>
|
||||
<artifactId>dokka-maven-plugin</artifactId>
|
||||
<version>1.9.10</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>pre-site</phase>
|
||||
<goals>
|
||||
<goal>dokka</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package top.fatweb.api
|
||||
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableTransactionManagement
|
||||
class FatWebApiApplication
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val logger = LoggerFactory.getLogger("main")
|
||||
|
||||
if (!File("data").isDirectory) {
|
||||
if (!File("data").mkdir()) {
|
||||
logger.error("Can not create directory 'data', please try again later.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (File("application-config.yml").exists() || File("data/application-config.yml").exists()) {
|
||||
runApplication<FatWebApiApplication>(*args)
|
||||
} else {
|
||||
logger.warn("File ‘application.yml’ cannot be found in the running path. The configuration file template 'application.example.yml' has been created in directory 'data'. Please change the configuration file content, rename it to 'application.yml', and then restart the server.")
|
||||
FatWebApiApplication::class.java.getResource("/application-config-template.yml")?.readText()?.let {
|
||||
File("data/application-config.example.yml").writeText(
|
||||
it.replace(
|
||||
"\$uuid\$", UUID.randomUUID().toString().replace("-", "")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package top.fatweb.api.annotation
|
||||
|
||||
import org.springframework.core.annotation.AliasFor
|
||||
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class ApiVersion(
|
||||
@get:AliasFor("version") val value: Int = 1,
|
||||
|
||||
@get:AliasFor("value") val version: Int = 1
|
||||
)
|
||||
@@ -1,25 +0,0 @@
|
||||
package top.fatweb.api.constant
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||
import org.springframework.stereotype.Component
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties("app.security")
|
||||
object SecurityConstants {
|
||||
var headerString = "Authorization"
|
||||
|
||||
var tokenPrefix = "Bearer "
|
||||
|
||||
var jwtTtl = 2L
|
||||
|
||||
var jwtTtlUnit = TimeUnit.HOURS
|
||||
|
||||
var jwtKey = "FatWeb"
|
||||
|
||||
var jwtIssuer = "FatWeb"
|
||||
|
||||
var redisTtl = 20L
|
||||
|
||||
var redisTtlUnit = TimeUnit.MINUTES
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package top.fatweb.api.constant
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||
import org.springframework.stereotype.Component
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties("app")
|
||||
object ServerConstants {
|
||||
lateinit var version: String
|
||||
|
||||
lateinit var buildTime: String
|
||||
|
||||
fun buildZoneDateTime(zoneId: ZoneId = ZoneId.systemDefault()): ZonedDateTime =
|
||||
LocalDateTime.parse(buildTime).atZone(ZoneId.of("UTC")).withZoneSameInstant(zoneId)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package top.fatweb.api.controller
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author FatttSnake
|
||||
* @since 2023-10-04
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/user")
|
||||
class UserController
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package top.fatweb.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import io.swagger.v3.oas.annotations.tags.Tag
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.api.annotation.ApiVersion
|
||||
import top.fatweb.api.converter.UserConverter
|
||||
import top.fatweb.api.entity.common.ResponseCode
|
||||
import top.fatweb.api.entity.common.ResponseResult
|
||||
import top.fatweb.api.param.LoginParam
|
||||
import top.fatweb.api.service.permission.IAuthenticationService
|
||||
import top.fatweb.api.util.WebUtil
|
||||
|
||||
@Tag(name = "身份认证", description = "身份认证相关接口")
|
||||
@ApiVersion(2)
|
||||
@RestController
|
||||
class AuthenticationController(val authenticationService: IAuthenticationService, val userConverter: UserConverter) {
|
||||
@Operation(summary = "登录")
|
||||
@PostMapping("/login")
|
||||
fun login(@Valid @RequestBody loginParam: LoginParam) =
|
||||
ResponseResult.success(
|
||||
ResponseCode.SYSTEM_LOGIN_SUCCESS,
|
||||
"Login success",
|
||||
authenticationService.login(userConverter.loginParamToUser(loginParam))
|
||||
)
|
||||
|
||||
@Operation(summary = "登出")
|
||||
@PostMapping("/logout")
|
||||
fun logout(request: HttpServletRequest) =
|
||||
when (authenticationService.logout(WebUtil.getToken(request))) {
|
||||
true -> ResponseResult.success(ResponseCode.SYSTEM_LOGOUT_SUCCESS, "Logout success", null)
|
||||
false -> ResponseResult.fail(ResponseCode.SYSTEM_LOGOUT_FAILED, "Logout failed", null)
|
||||
}
|
||||
|
||||
@Operation(summary = "更新 Token")
|
||||
@GetMapping("/token")
|
||||
fun renewToken(request: HttpServletRequest) =
|
||||
ResponseResult.success(
|
||||
ResponseCode.SYSTEM_TOKEN_RENEW_SUCCESS,
|
||||
"Token renew success",
|
||||
authenticationService.renewToken(WebUtil.getToken(request))
|
||||
)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package top.fatweb.api.converter
|
||||
|
||||
import org.springframework.stereotype.Component
|
||||
import top.fatweb.api.entity.permission.User
|
||||
import top.fatweb.api.param.LoginParam
|
||||
|
||||
@Component
|
||||
object UserConverter {
|
||||
fun loginParamToUser(loginParam: LoginParam): User {
|
||||
val user = User().apply {
|
||||
username = loginParam.username
|
||||
password = loginParam.password
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package top.fatweb.api.entity.common
|
||||
|
||||
enum class BusinessCode(val code: Int) {
|
||||
SYSTEM(100),
|
||||
DATABASE(200)
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package top.fatweb.api.entity.common
|
||||
|
||||
enum class ResponseCode(val code: Int) {
|
||||
SYSTEM_OK(BusinessCode.SYSTEM, 0),
|
||||
SYSTEM_LOGIN_SUCCESS(BusinessCode.SYSTEM, 20),
|
||||
SYSTEM_PASSWORD_CHANGE_SUCCESS(BusinessCode.SYSTEM, 21),
|
||||
SYSTEM_LOGOUT_SUCCESS(BusinessCode.SYSTEM, 22),
|
||||
SYSTEM_TOKEN_RENEW_SUCCESS(BusinessCode.SYSTEM, 23),
|
||||
SYSTEM_UNAUTHORIZED(BusinessCode.SYSTEM, 30),
|
||||
SYSTEM_USERNAME_NOT_FOUND(BusinessCode.SYSTEM, 31),
|
||||
SYSTEM_ACCESS_DENIED(BusinessCode.SYSTEM, 32),
|
||||
SYSTEM_USER_DISABLE(BusinessCode.SYSTEM, 33),
|
||||
SYSTEM_LOGIN_USERNAME_PASSWORD_ERROR(BusinessCode.SYSTEM, 34),
|
||||
SYSTEM_OLD_PASSWORD_NOT_MATCH(BusinessCode.SYSTEM, 35),
|
||||
SYSTEM_LOGOUT_FAILED(BusinessCode.SYSTEM, 36),
|
||||
SYSTEM_TOKEN_ILLEGAL(BusinessCode.SYSTEM, 37),
|
||||
SYSTEM_TOKEN_HAS_EXPIRED(BusinessCode.SYSTEM, 38),
|
||||
SYSTEM_REQUEST_ILLEGAL(BusinessCode.SYSTEM, 40),
|
||||
SYSTEM_ARGUMENT_NOT_VALID(BusinessCode.SYSTEM, 41),
|
||||
SYSTEM_ERROR(BusinessCode.SYSTEM, 50),
|
||||
SYSTEM_TIMEOUT(BusinessCode.SYSTEM, 51);
|
||||
|
||||
constructor(businessCode: BusinessCode, code: Int) : this(businessCode.code * 100 + code)
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package top.fatweb.api.entity.common
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import java.io.Serializable
|
||||
|
||||
class ResponseResult<T> private constructor(
|
||||
@Schema(description = "响应码", defaultValue = "200")
|
||||
val code: Int,
|
||||
|
||||
@Schema(description = "是否调用成功")
|
||||
val success: Boolean,
|
||||
|
||||
@Schema(description = "信息")
|
||||
val msg: String,
|
||||
|
||||
@Schema(description = "数据")
|
||||
val data: T?
|
||||
) : Serializable {
|
||||
companion object {
|
||||
fun <T> build(code: ResponseCode, success: Boolean, msg: String, data: T?) =
|
||||
ResponseResult(code.code, success, msg, data)
|
||||
|
||||
fun <T> success(code: ResponseCode = ResponseCode.SYSTEM_OK, msg: String = "success", data: T? = null) =
|
||||
build(code, true, msg, data)
|
||||
|
||||
fun <T> fail(code: ResponseCode = ResponseCode.SYSTEM_ERROR, msg: String = "fail", data: T? = null) =
|
||||
build(code, false, msg, data)
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package top.fatweb.api.entity.permission
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo
|
||||
import org.springframework.security.core.GrantedAuthority
|
||||
import org.springframework.security.core.userdetails.UserDetails
|
||||
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
|
||||
class LoginUser() : UserDetails {
|
||||
lateinit var user: User
|
||||
|
||||
@JsonIgnore
|
||||
private var authorities: List<GrantedAuthority>? = null
|
||||
|
||||
constructor(user: User) : this() {
|
||||
this.user = user
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
override fun getAuthorities(): List<GrantedAuthority> {
|
||||
authorities?.let { return it }
|
||||
authorities = emptyList()
|
||||
|
||||
return authorities as List<GrantedAuthority>
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
override fun getPassword(): String? = user.password
|
||||
|
||||
@JsonIgnore
|
||||
override fun getUsername(): String? = user.username
|
||||
|
||||
@JsonIgnore
|
||||
override fun isAccountNonExpired(): Boolean = true
|
||||
|
||||
@JsonIgnore
|
||||
override fun isAccountNonLocked(): Boolean = true
|
||||
|
||||
@JsonIgnore
|
||||
override fun isCredentialsNonExpired(): Boolean = true
|
||||
|
||||
@JsonIgnore
|
||||
override fun isEnabled(): Boolean = user.enable == 1
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package top.fatweb.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户
|
||||
* </p>
|
||||
*
|
||||
* @author FatttSnake
|
||||
* @since 2023-10-04
|
||||
*/
|
||||
@TableName("t_user")
|
||||
class User() : Serializable {
|
||||
constructor(username: String, password: String, enable: Boolean = true) : this() {
|
||||
this.username = username
|
||||
this.password = password
|
||||
this.enable = if (enable) 1 else 0
|
||||
}
|
||||
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@TableField("username")
|
||||
var username: String? = null
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@TableField("password")
|
||||
var password: String? = null
|
||||
|
||||
/**
|
||||
* 启用
|
||||
*/
|
||||
@TableField("enable")
|
||||
var enable: Int? = null
|
||||
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "User{id=$id, username=$username, password=$password, enable=$enable, deleted=$deleted, version=$version}"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
package top.fatweb.api.exception
|
||||
|
||||
class TokenHasExpiredException : RuntimeException("Token has expired")
|
||||
@@ -1,46 +0,0 @@
|
||||
package top.fatweb.api.filter
|
||||
|
||||
import jakarta.servlet.FilterChain
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||
import org.springframework.security.core.context.SecurityContextHolder
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.util.StringUtils
|
||||
import org.springframework.web.filter.OncePerRequestFilter
|
||||
import top.fatweb.api.constant.SecurityConstants
|
||||
import top.fatweb.api.entity.permission.LoginUser
|
||||
import top.fatweb.api.exception.TokenHasExpiredException
|
||||
import top.fatweb.api.util.JwtUtil
|
||||
import top.fatweb.api.util.RedisUtil
|
||||
import top.fatweb.api.util.WebUtil
|
||||
|
||||
@Component
|
||||
class JwtAuthenticationTokenFilter(private val redisUtil: RedisUtil) : OncePerRequestFilter() {
|
||||
override fun doFilterInternal(
|
||||
request: HttpServletRequest,
|
||||
response: HttpServletResponse,
|
||||
filterChain: FilterChain
|
||||
) {
|
||||
val tokenWithPrefix = request.getHeader(SecurityConstants.headerString)
|
||||
|
||||
if (!StringUtils.hasText(tokenWithPrefix) || "/error/thrown" == request.servletPath) {
|
||||
filterChain.doFilter(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
val token = WebUtil.getToken(tokenWithPrefix)
|
||||
JwtUtil.parseJwt(token)
|
||||
|
||||
val redisKey = "${SecurityConstants.jwtIssuer}_login:" + token
|
||||
val loginUser = redisUtil.getObject<LoginUser>(redisKey)
|
||||
loginUser ?: let { throw TokenHasExpiredException() }
|
||||
|
||||
redisUtil.setExpire(redisKey, SecurityConstants.redisTtl, SecurityConstants.redisTtlUnit)
|
||||
|
||||
val authenticationToken = UsernamePasswordAuthenticationToken(loginUser, null, loginUser.authorities)
|
||||
SecurityContextHolder.getContext().authentication = authenticationToken
|
||||
|
||||
filterChain.doFilter(request, response)
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package top.fatweb.api.handler
|
||||
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException
|
||||
import com.auth0.jwt.exceptions.SignatureVerificationException
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException
|
||||
import org.springframework.security.authentication.BadCredentialsException
|
||||
import org.springframework.security.authentication.InsufficientAuthenticationException
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice
|
||||
import top.fatweb.api.entity.common.ResponseCode
|
||||
import top.fatweb.api.entity.common.ResponseResult
|
||||
import top.fatweb.api.exception.TokenHasExpiredException
|
||||
|
||||
@RestControllerAdvice
|
||||
class ExceptionHandler {
|
||||
private val log: Logger = LoggerFactory.getLogger(this::class.java)
|
||||
|
||||
@ExceptionHandler(value = [Exception::class])
|
||||
fun exceptionHandler(e: Exception): ResponseResult<*> {
|
||||
return when (e) {
|
||||
is InsufficientAuthenticationException -> {
|
||||
log.debug(e.localizedMessage, e)
|
||||
ResponseResult.fail(ResponseCode.SYSTEM_UNAUTHORIZED, e.localizedMessage, null)
|
||||
}
|
||||
|
||||
is HttpMessageNotReadableException -> {
|
||||
log.debug(e.localizedMessage, e)
|
||||
ResponseResult.fail(ResponseCode.SYSTEM_REQUEST_ILLEGAL, e.localizedMessage.split(":")[0], null)
|
||||
}
|
||||
|
||||
is MethodArgumentNotValidException -> {
|
||||
log.debug(e.localizedMessage, e)
|
||||
val errorMessage = e.allErrors.map { error -> error.defaultMessage }.joinToString(". ")
|
||||
ResponseResult.fail(ResponseCode.SYSTEM_ARGUMENT_NOT_VALID, errorMessage, null)
|
||||
}
|
||||
|
||||
is InternalAuthenticationServiceException -> {
|
||||
log.debug(e.localizedMessage, e)
|
||||
ResponseResult.fail(ResponseCode.SYSTEM_USERNAME_NOT_FOUND, "Username not found", null)
|
||||
}
|
||||
|
||||
is BadCredentialsException -> {
|
||||
log.debug(e.localizedMessage, e)
|
||||
ResponseResult.fail(ResponseCode.SYSTEM_LOGIN_USERNAME_PASSWORD_ERROR, e.localizedMessage, null)
|
||||
}
|
||||
|
||||
is SignatureVerificationException, is JWTDecodeException -> {
|
||||
log.debug(e.localizedMessage, e)
|
||||
ResponseResult.fail(ResponseCode.SYSTEM_TOKEN_ILLEGAL, "Token illegal", null)
|
||||
}
|
||||
|
||||
is TokenHasExpiredException -> {
|
||||
log.debug(e.localizedMessage, e)
|
||||
ResponseResult.fail(ResponseCode.SYSTEM_TOKEN_HAS_EXPIRED, e.localizedMessage, null)
|
||||
}
|
||||
|
||||
else -> {
|
||||
log.error(e.localizedMessage, e)
|
||||
ResponseResult.fail(ResponseCode.SYSTEM_ERROR, data = null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package top.fatweb.api.mapper
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper
|
||||
import org.apache.ibatis.annotations.Mapper
|
||||
import top.fatweb.api.entity.permission.User
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author FatttSnake
|
||||
* @since 2023-10-04
|
||||
*/
|
||||
@Mapper
|
||||
interface UserMapper : BaseMapper<User>
|
||||
@@ -1,17 +0,0 @@
|
||||
package top.fatweb.api.param
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import jakarta.validation.constraints.NotBlank
|
||||
import java.io.Serializable
|
||||
|
||||
@Schema(description = "登录请求参数")
|
||||
class LoginParam : Serializable {
|
||||
|
||||
@Schema(description = "用户名", example = "test", required = true)
|
||||
@NotBlank(message = "Username can not be blank")
|
||||
val username: String? = null
|
||||
|
||||
@Schema(description = "密码", example = "test123456", required = true)
|
||||
@NotBlank(message = "Password can not be blank")
|
||||
val password: String? = null
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package top.fatweb.api.service
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService
|
||||
import top.fatweb.api.entity.permission.User
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author FatttSnake
|
||||
* @since 2023-10-04
|
||||
*/
|
||||
interface IUserService : IService<User>
|
||||
@@ -1,18 +0,0 @@
|
||||
package top.fatweb.api.service.impl
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
|
||||
import org.springframework.stereotype.Service
|
||||
import top.fatweb.api.entity.permission.User
|
||||
import top.fatweb.api.mapper.UserMapper
|
||||
import top.fatweb.api.service.IUserService
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author FatttSnake
|
||||
* @since 2023-10-04
|
||||
*/
|
||||
@Service
|
||||
class UserServiceImpl : ServiceImpl<UserMapper, User>(), IUserService
|
||||
@@ -1,13 +0,0 @@
|
||||
package top.fatweb.api.service.permission
|
||||
|
||||
import top.fatweb.api.entity.permission.User
|
||||
import top.fatweb.api.vo.LoginVo
|
||||
import top.fatweb.api.vo.TokenVo
|
||||
|
||||
interface IAuthenticationService {
|
||||
fun login(user: User): LoginVo
|
||||
|
||||
fun logout(token: String): Boolean
|
||||
|
||||
fun renewToken(token: String): TokenVo
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package top.fatweb.api.service.permission.impl
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationManager
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||
import org.springframework.stereotype.Service
|
||||
import top.fatweb.api.constant.SecurityConstants
|
||||
import top.fatweb.api.entity.permission.LoginUser
|
||||
import top.fatweb.api.entity.permission.User
|
||||
import top.fatweb.api.service.permission.IAuthenticationService
|
||||
import top.fatweb.api.util.JwtUtil
|
||||
import top.fatweb.api.util.RedisUtil
|
||||
import top.fatweb.api.util.WebUtil
|
||||
import top.fatweb.api.vo.LoginVo
|
||||
import top.fatweb.api.vo.TokenVo
|
||||
|
||||
@Service
|
||||
class AuthenticationServiceImpl(
|
||||
private val authenticationManager: AuthenticationManager,
|
||||
private val redisUtil: RedisUtil
|
||||
) : IAuthenticationService {
|
||||
override fun login(user: User): LoginVo {
|
||||
val usernamePasswordAuthenticationToken = UsernamePasswordAuthenticationToken(user.username, user.password)
|
||||
val authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken)
|
||||
authentication ?: let {
|
||||
throw RuntimeException("Login failed")
|
||||
}
|
||||
|
||||
val loginUser = authentication.principal as LoginUser
|
||||
loginUser.user.password = ""
|
||||
val userId = loginUser.user.id.toString()
|
||||
val jwt = JwtUtil.createJwt(userId)
|
||||
|
||||
jwt ?: let {
|
||||
throw RuntimeException("Login failed")
|
||||
}
|
||||
|
||||
val redisKey = "${SecurityConstants.jwtIssuer}_login:" + jwt
|
||||
redisUtil.setObject(redisKey, loginUser, SecurityConstants.redisTtl, SecurityConstants.redisTtlUnit)
|
||||
|
||||
return LoginVo(jwt)
|
||||
}
|
||||
|
||||
override fun logout(token: String): Boolean =
|
||||
redisUtil.delObject("${SecurityConstants.jwtIssuer}_login:" + token)
|
||||
|
||||
override fun renewToken(token: String): TokenVo {
|
||||
val oldRedisKey = "${SecurityConstants.jwtIssuer}_login:" + token
|
||||
redisUtil.delObject(oldRedisKey)
|
||||
val jwt = JwtUtil.createJwt(WebUtil.getLoginUserId().toString())
|
||||
|
||||
jwt ?: let {
|
||||
throw RuntimeException("Login failed")
|
||||
}
|
||||
|
||||
val redisKey = "${SecurityConstants.jwtIssuer}_login:" + jwt
|
||||
redisUtil.setObject(
|
||||
redisKey,
|
||||
WebUtil.getLoginUser(),
|
||||
SecurityConstants.redisTtl,
|
||||
SecurityConstants.redisTtlUnit
|
||||
)
|
||||
|
||||
return TokenVo(jwt)
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package top.fatweb.api.service.permission.impl
|
||||
|
||||
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
|
||||
import org.springframework.security.core.userdetails.UserDetails
|
||||
import org.springframework.security.core.userdetails.UserDetailsService
|
||||
import org.springframework.stereotype.Service
|
||||
import top.fatweb.api.entity.permission.LoginUser
|
||||
import top.fatweb.api.entity.permission.User
|
||||
import top.fatweb.api.service.IUserService
|
||||
|
||||
@Service
|
||||
class UserDetailsServiceImpl(val userService: IUserService) : UserDetailsService {
|
||||
override fun loadUserByUsername(username: String?): UserDetails {
|
||||
val user = userService.getOne(KtQueryWrapper(User()).eq(User::username, username))
|
||||
user ?: let { throw Exception("Username not found") }
|
||||
|
||||
return LoginUser(user)
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package top.fatweb.api.util
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.servlet.mvc.condition.RequestCondition
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
|
||||
import top.fatweb.api.annotation.ApiVersion
|
||||
import java.lang.reflect.Method
|
||||
|
||||
class ApiResponseMappingHandlerMapping : RequestMappingHandlerMapping() {
|
||||
private val versionFlag = "{apiVersion}"
|
||||
|
||||
private fun createCondition(clazz: Class<*>): RequestCondition<ApiVersionCondition>? {
|
||||
val classRequestMapping = clazz.getAnnotation(RequestMapping::class.java)
|
||||
classRequestMapping ?: let { return null }
|
||||
val mappingUrlBuilder = StringBuilder()
|
||||
if (classRequestMapping.value.isNotEmpty()) {
|
||||
mappingUrlBuilder.append(classRequestMapping.value[0])
|
||||
}
|
||||
val mappingUrl = mappingUrlBuilder.toString()
|
||||
if (!mappingUrl.contains(versionFlag)) {
|
||||
return null
|
||||
}
|
||||
val apiVersion = clazz.getAnnotation(ApiVersion::class.java)
|
||||
|
||||
return if (apiVersion == null) ApiVersionCondition(1) else ApiVersionCondition(apiVersion.version)
|
||||
}
|
||||
|
||||
override fun getCustomMethodCondition(method: Method): RequestCondition<*>? = createCondition(method.javaClass)
|
||||
|
||||
override fun getCustomTypeCondition(handlerType: Class<*>): RequestCondition<*>? = createCondition(handlerType)
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
package top.fatweb.api.util
|
||||
|
||||
import org.springframework.data.redis.core.BoundSetOperations
|
||||
import org.springframework.data.redis.core.RedisTemplate
|
||||
import org.springframework.stereotype.Component
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@Component
|
||||
class RedisUtil(private val redisTemplate: RedisTemplate<String, Any>) {
|
||||
/**
|
||||
* 设置有效时间
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @param timeout 超时时间
|
||||
* @param timeUnit 时间颗粒度
|
||||
* @return true=设置成功;false=设置失败
|
||||
*/
|
||||
fun setExpire(key: String, timeout: Long, timeUnit: TimeUnit = TimeUnit.SECONDS) =
|
||||
redisTemplate.expire(key, timeout, timeUnit)
|
||||
|
||||
/**
|
||||
* 获取有效时间
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @return 有效时间
|
||||
*/
|
||||
fun getExpire(key: String, timeUnit: TimeUnit = TimeUnit.SECONDS) = redisTemplate.getExpire(key, timeUnit)
|
||||
|
||||
/**
|
||||
* 判断 key 是否存在
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @return true=存在; false=不存在
|
||||
*/
|
||||
fun hasKey(key: String) = redisTemplate.hasKey(key)
|
||||
|
||||
/**
|
||||
* 获得缓存的基本对象列表
|
||||
*
|
||||
* @param pattern 字符串前缀
|
||||
* @return 对象列表
|
||||
*/
|
||||
fun keys(pattern: String): Set<String> = redisTemplate.keys(pattern)
|
||||
|
||||
/**
|
||||
* 缓存基本的对象,Integer、String、实体类等
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @param value 缓存的值
|
||||
*/
|
||||
fun setObject(key: String, value: Any) = redisTemplate.opsForValue().set(key, value)
|
||||
|
||||
/**
|
||||
* 缓存基本的对象,Integer、String、实体类等
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @param value 缓存的值
|
||||
* @param timeout 超时时间
|
||||
* @param timeUnit 时间颗粒度
|
||||
*/
|
||||
fun setObject(key: String, value: Any, timeout: Long, timeUnit: TimeUnit = TimeUnit.SECONDS) =
|
||||
redisTemplate.opsForValue().set(key, value, timeout, timeUnit)
|
||||
|
||||
|
||||
/**
|
||||
* 获得缓存的基本对象
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @return 缓存的值
|
||||
*/
|
||||
fun <T> getObject(key: String) = redisTemplate.opsForValue().get(key) as? T
|
||||
|
||||
/**
|
||||
* 删除单个对象
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @return true=删除成功;false=删除失败
|
||||
*/
|
||||
fun delObject(key: String) = redisTemplate.delete(key)
|
||||
|
||||
/**
|
||||
* 删除对象集合
|
||||
*
|
||||
* @param collection 键集合
|
||||
* @return 删除个数
|
||||
*/
|
||||
fun delObject(collection: Collection<String>) = redisTemplate.delete(collection)
|
||||
|
||||
/**
|
||||
* 缓存 List 数据
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @param dataList 缓存的 List 数据
|
||||
* @return 缓存的个数
|
||||
*/
|
||||
fun setList(key: String, dataList: List<Any>) = redisTemplate.opsForList().rightPushAll(key, dataList)
|
||||
|
||||
/**
|
||||
* 获得缓存的 List 数据
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @return 缓存的键对应的 List 数据
|
||||
*/
|
||||
fun <T> getList(key: String): List<T>? = redisTemplate.opsForList().range(key, 0, -1) as? List<T>
|
||||
|
||||
/**
|
||||
* 缓存 Set 数据
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @param dataSet 缓存的 Set 数据
|
||||
* @return 缓存数据的对象
|
||||
*/
|
||||
fun setSet(key: String, dataSet: Set<Any>): BoundSetOperations<String, Any> {
|
||||
val boundSetOps: BoundSetOperations<String, Any> = redisTemplate.boundSetOps(key)
|
||||
for (data in dataSet) {
|
||||
boundSetOps.add(data)
|
||||
}
|
||||
return boundSetOps
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的 Set 数据
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @return 缓存的键对应的 Set 数据
|
||||
*/
|
||||
fun <T> getSet(key: String): Set<T>? = redisTemplate.opsForSet().members(key) as? Set<T>
|
||||
|
||||
/**
|
||||
* 缓存 Map 数据
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @param dataMap 缓存的 Map 数据
|
||||
*/
|
||||
fun setMap(key: String, dataMap: Map<String, Any>) = redisTemplate.opsForHash<String, Any>().putAll(key, dataMap)
|
||||
|
||||
/**
|
||||
* 获得缓存的 Map 数据
|
||||
*
|
||||
* @param key 缓存的键
|
||||
* @return 缓存的键对应的 Map 数据
|
||||
*/
|
||||
fun <T> getMap(key: String): Map<String, T>? =
|
||||
redisTemplate.opsForHash<String, Any>().entries(key) as? Map<String, T>
|
||||
|
||||
/**
|
||||
* 往 Hash 中存入数据
|
||||
*
|
||||
* @param key Redis 键
|
||||
* @param hKey Hash 键
|
||||
* @param value 值
|
||||
*/
|
||||
fun setMapValue(key: String, hKey: String, value: Any) =
|
||||
redisTemplate.opsForHash<String, Any>().put(key, hKey, value)
|
||||
|
||||
/**
|
||||
* 获取 Hash 中的数据
|
||||
*
|
||||
* @param key Redis 键
|
||||
* @param hKey Hash 键
|
||||
* @return Hash 中的对象
|
||||
*/
|
||||
fun <T> getMapValue(key: String, hKey: String) = redisTemplate.opsForHash<String, T>().get(key, hKey)
|
||||
|
||||
/**
|
||||
* 删除 Hash 中的数据
|
||||
*
|
||||
* @param key Redis 键
|
||||
* @param hKey Hash 键
|
||||
*/
|
||||
fun delMapValue(key: String, hKey: String) = redisTemplate.opsForHash<String, Any>().delete(key, hKey)
|
||||
|
||||
/**
|
||||
* 获取多个 Hash 中的数据
|
||||
*
|
||||
* @param key Redis 键
|
||||
* @param hKeys Hash 键集合
|
||||
* @return Hash 对象集合
|
||||
*/
|
||||
fun <T> getMultiMapValue(key: String, hKeys: Collection<String>): List<T> =
|
||||
redisTemplate.opsForHash<String, T>().multiGet(key, hKeys)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package top.fatweb.api.util
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.springframework.security.core.context.SecurityContextHolder
|
||||
import top.fatweb.api.constant.SecurityConstants
|
||||
import top.fatweb.api.entity.permission.LoginUser
|
||||
|
||||
object WebUtil {
|
||||
fun getLoginUser() = SecurityContextHolder.getContext().authentication.principal as LoginUser
|
||||
|
||||
fun getLoginUserId() = getLoginUser().user.id
|
||||
|
||||
fun getToken(tokenWithPrefix: String) = tokenWithPrefix.removePrefix(SecurityConstants.tokenPrefix)
|
||||
|
||||
fun getToken(request: HttpServletRequest) = getToken(request.getHeader(SecurityConstants.headerString))
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package top.fatweb.api.vo
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
|
||||
@Schema(description = "登录返回参数")
|
||||
data class LoginVo(
|
||||
@Schema(
|
||||
description = "Token",
|
||||
example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYTllYjFkYmVmZDQ0OWRkOThlOGNjNzZlNzZkMDgyNSIsInN1YiI6IjE3MDk5ODYwNTg2Nzk5NzU5MzgiLCJpc3MiOiJGYXRXZWIiLCJpYXQiOjE2OTY1MjgxMTcsImV4cCI6MTY5NjUzNTMxN30.U2ZsyrGk7NbsP-DJfdz9xgWSfect5r2iKQnlEsscAA8"
|
||||
) val token: String
|
||||
)
|
||||
@@ -0,0 +1,67 @@
|
||||
package top.fatweb.oxygen.api
|
||||
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
import org.springframework.scheduling.annotation.EnableScheduling
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Application main class
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableTransactionManagement
|
||||
@EnableScheduling
|
||||
class OxygenApiApplication
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*
|
||||
* @param args
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
val logger = LoggerFactory.getLogger("main")
|
||||
|
||||
if (!File("data").isDirectory) {
|
||||
if (!File("data").mkdir()) {
|
||||
logger.error("Can not create directory 'data', please try again later.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!File("data/db").isDirectory) {
|
||||
if (!File("data/db").mkdir()) {
|
||||
logger.error("Can not create directory 'data/db', please try again later.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!File("data/db/sqlite.db").isFile || File("data/db/sqlite.db").inputStream()
|
||||
.use { it.readNBytes(15).toString(Charsets.UTF_8) != "SQLite format 3" }
|
||||
) {
|
||||
logger.warn("The 'data/db/sqlite.db' database is lost or damaged, recreating...")
|
||||
if (File("data/db/sqlite.db").exists() && !File("data/db/sqlite.db").delete()) {
|
||||
logger.error("Can not recreate database 'data/db/sqlite.db', please try again later.")
|
||||
}
|
||||
}
|
||||
|
||||
if (File("application-config.yml").exists() || File("data/application-config.yml").exists()) {
|
||||
runApplication<OxygenApiApplication>(*args)
|
||||
} else {
|
||||
logger.warn("File 'application-config.yml' cannot be found in the running path or the data path. The configuration file template 'application-config.example.yml' has been created in directory 'data'. Please change the configuration file content, move it to the running path, rename it to 'application-config.yml', and then restart the server.")
|
||||
OxygenApiApplication::class.java.getResource("/application-config-template.yml")?.readText()?.let {
|
||||
File("data/application-config.example.yml").writeText(
|
||||
it.replace(
|
||||
"\$uuid\$", UUID.randomUUID().toString().replace("-", "")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package top.fatweb.oxygen.api.annotation
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag
|
||||
import org.springframework.core.annotation.AliasFor
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
/**
|
||||
* API controller annotation
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Tag
|
||||
* @see RequestMapping
|
||||
* @see RestController
|
||||
*/
|
||||
@Tag(name = "")
|
||||
@RequestMapping
|
||||
@RestController
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class ApiController(
|
||||
val version: Int = 1,
|
||||
|
||||
@get:AliasFor(annotation = RestController::class, attribute = "value") val value: String = "",
|
||||
|
||||
@get:AliasFor(annotation = RequestMapping::class, attribute = "path") val path: Array<String> = [""],
|
||||
|
||||
@get:AliasFor(annotation = Tag::class, attribute = "name") val name: String,
|
||||
|
||||
@get:AliasFor(annotation = Tag::class, attribute = "description") val description: String
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
package top.fatweb.oxygen.api.annotation
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag
|
||||
import org.springframework.core.annotation.AliasFor
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
/**
|
||||
* Base controller annotation
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RequestMapping
|
||||
* @see RestController
|
||||
*/
|
||||
@Tag(name = "")
|
||||
@RequestMapping
|
||||
@RestController
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class BaseController(
|
||||
@get:AliasFor(annotation = RequestMapping::class, attribute = "path") val path: Array<String> = [""],
|
||||
|
||||
@get:AliasFor(annotation = Tag::class, attribute = "name") val name: String,
|
||||
|
||||
@get:AliasFor(annotation = Tag::class, attribute = "description") val description: String
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package top.fatweb.oxygen.api.annotation
|
||||
|
||||
import top.fatweb.oxygen.api.entity.system.EventLog
|
||||
|
||||
/**
|
||||
* Event log record annotation
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class EventLogRecord(
|
||||
val event: EventLog.Event
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
package top.fatweb.oxygen.api.annotation
|
||||
|
||||
import io.swagger.v3.oas.annotations.Hidden
|
||||
import org.springframework.core.annotation.AliasFor
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
/**
|
||||
* Hidden controller annotation
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Hidden
|
||||
* @see RequestMapping
|
||||
* @see RestController
|
||||
*/
|
||||
@Hidden
|
||||
@RequestMapping
|
||||
@RestController
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class HiddenController(
|
||||
@get:AliasFor(annotation = RequestMapping::class, attribute = "path") val path: Array<String> = [""]
|
||||
)
|
||||
58
src/main/kotlin/top/fatweb/oxygen/api/aop/EventLogAspect.kt
Normal file
58
src/main/kotlin/top/fatweb/oxygen/api/aop/EventLogAspect.kt
Normal file
@@ -0,0 +1,58 @@
|
||||
package top.fatweb.oxygen.api.aop
|
||||
|
||||
import org.aspectj.lang.JoinPoint
|
||||
import org.aspectj.lang.annotation.AfterReturning
|
||||
import org.aspectj.lang.annotation.Aspect
|
||||
import org.aspectj.lang.annotation.Pointcut
|
||||
import org.aspectj.lang.reflect.MethodSignature
|
||||
import org.springframework.stereotype.Component
|
||||
import top.fatweb.oxygen.api.annotation.EventLogRecord
|
||||
import top.fatweb.oxygen.api.service.system.IEventLogService
|
||||
import top.fatweb.oxygen.api.util.WebUtil
|
||||
import top.fatweb.oxygen.api.vo.permission.LoginVo
|
||||
import top.fatweb.oxygen.api.vo.permission.RegisterVo
|
||||
|
||||
/**
|
||||
* Event log record aspect
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IEventLogService
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
class EventLogAspect(
|
||||
private val eventLogService: IEventLogService
|
||||
) {
|
||||
/**
|
||||
* Event log record pointcut
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Pointcut("@annotation(top.fatweb.oxygen.api.annotation.EventLogRecord)")
|
||||
fun eventLogPointcut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Do after event log record pointcut
|
||||
*
|
||||
* @param joinPoint Join point
|
||||
* @param retValue Return value
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see JoinPoint
|
||||
*/
|
||||
@AfterReturning(value = "eventLogPointcut()", returning = "retValue")
|
||||
fun doAfter(joinPoint: JoinPoint, retValue: Any?) {
|
||||
val annotation = (joinPoint.signature as MethodSignature).method.getAnnotation(EventLogRecord::class.java)
|
||||
|
||||
val userId = WebUtil.getLoginUserId() ?: when (retValue) {
|
||||
is LoginVo -> retValue.userId!!
|
||||
is RegisterVo -> retValue.userId!!
|
||||
else -> -1
|
||||
}
|
||||
|
||||
eventLogService.saveEvent(annotation, userId)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.fasterxml.jackson.databind.SerializationFeature
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer
|
||||
import org.springframework.boot.jackson.JsonComponent
|
||||
import org.springframework.context.annotation.Bean
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Date format configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@JsonComponent
|
||||
class DateFormatConfig {
|
||||
/**
|
||||
* The format of the time in response when request APIs
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@set:Value("\${spring.jackson.date-format}")
|
||||
lateinit var dateFormat: String
|
||||
|
||||
/**
|
||||
* The timezone of the time in response when request APIs
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see TimeZone
|
||||
*/
|
||||
@set:Value("\${spring.jackson.time-zone}}")
|
||||
lateinit var timeZone: TimeZone
|
||||
|
||||
@Bean
|
||||
fun jackson2ObjectMapperBuilder() = Jackson2ObjectMapperBuilderCustomizer {
|
||||
val tz = timeZone
|
||||
val df: DateFormat = SimpleDateFormat(dateFormat)
|
||||
df.timeZone = tz
|
||||
it.failOnEmptyBeans(false).failOnUnknownProperties(false)
|
||||
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).dateFormat(df)
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun jackson2ObjectMapperBuilderCustomizer() =
|
||||
Jackson2ObjectMapperBuilderCustomizer {
|
||||
it.serializerByType(
|
||||
LocalDateTime::class.java, LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateFormat))
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,16 @@
|
||||
package top.fatweb.api.config
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import top.fatweb.api.filter.ExceptionFilter
|
||||
import top.fatweb.oxygen.api.filter.ExceptionFilter
|
||||
|
||||
/**
|
||||
* Filter configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class FilterConfig {
|
||||
@Bean
|
||||
43
src/main/kotlin/top/fatweb/oxygen/api/config/FlywayConfig.kt
Normal file
43
src/main/kotlin/top/fatweb/oxygen/api/config/FlywayConfig.kt
Normal file
@@ -0,0 +1,43 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource
|
||||
import jakarta.annotation.PostConstruct
|
||||
import org.flywaydb.core.Flyway
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.DependsOn
|
||||
import top.fatweb.oxygen.api.properties.FlywayProperties
|
||||
import javax.sql.DataSource
|
||||
|
||||
/**
|
||||
* Flyway configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@DependsOn("flywayProperties")
|
||||
@Configuration
|
||||
class FlywayConfig(
|
||||
private val dataSource: DataSource
|
||||
) {
|
||||
@PostConstruct
|
||||
fun migrateOrder() {
|
||||
val ds = dataSource as DynamicRoutingDataSource
|
||||
ds.dataSources.forEach { (k: String, v: DataSource?) ->
|
||||
val flyway = Flyway.configure()
|
||||
.dataSource(v)
|
||||
.locations(*FlywayProperties.locations.map { "$it/$k" }.toTypedArray())
|
||||
.baselineOnMigrate(FlywayProperties.baselineOnMigrate)
|
||||
.table(FlywayProperties.table)
|
||||
.outOfOrder(FlywayProperties.outOfOrder)
|
||||
.validateOnMigrate(FlywayProperties.validateOnMigrate)
|
||||
.encoding(FlywayProperties.encoding)
|
||||
.sqlMigrationPrefix(FlywayProperties.sqlMigrationPrefix)
|
||||
.sqlMigrationSeparator(FlywayProperties.sqlMigrationSeparator)
|
||||
.sqlMigrationSuffixes(*FlywayProperties.sqlMigrationSuffixes.toTypedArray())
|
||||
.baselineVersion(FlywayProperties.baselineVersion)
|
||||
.load()
|
||||
flyway.migrate()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
69
src/main/kotlin/top/fatweb/oxygen/api/config/InitConfig.kt
Normal file
69
src/main/kotlin/top/fatweb/oxygen/api/config/InitConfig.kt
Normal file
@@ -0,0 +1,69 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
|
||||
import jakarta.annotation.PostConstruct
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.context.annotation.DependsOn
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.stereotype.Component
|
||||
import top.fatweb.avatargenerator.GitHubAvatar
|
||||
import top.fatweb.oxygen.api.entity.permission.User
|
||||
import top.fatweb.oxygen.api.entity.permission.UserInfo
|
||||
import top.fatweb.oxygen.api.properties.AdminProperties
|
||||
import top.fatweb.oxygen.api.service.permission.IUserInfoService
|
||||
import top.fatweb.oxygen.api.service.permission.IUserService
|
||||
import top.fatweb.oxygen.api.util.StrUtil
|
||||
|
||||
/**
|
||||
* Application initialization configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IUserService
|
||||
* @see IUserInfoService
|
||||
* @see PasswordEncoder
|
||||
*/
|
||||
@DependsOn("adminProperties")
|
||||
@Component
|
||||
class InitConfig(
|
||||
private val userService: IUserService,
|
||||
private val userInfoService: IUserInfoService,
|
||||
private val passwordEncoder: PasswordEncoder
|
||||
) {
|
||||
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
||||
|
||||
@PostConstruct
|
||||
fun init() {
|
||||
if (!userService.exists(KtQueryWrapper(User()).eq(User::id, 0))) {
|
||||
userInfoService.remove(KtQueryWrapper(UserInfo()).eq(UserInfo::userId, 0))
|
||||
|
||||
val rawPassword = AdminProperties.password ?: let {
|
||||
logger.warn("No default administrator password is set, a randomly generated password will be used")
|
||||
StrUtil.getRandomPassword(10)
|
||||
}
|
||||
val encodedPassword = passwordEncoder.encode(rawPassword)
|
||||
|
||||
val user = User().apply {
|
||||
id = 0
|
||||
username = AdminProperties.username
|
||||
password = encodedPassword
|
||||
locking = 0
|
||||
enable = 1
|
||||
}
|
||||
val userInfo = UserInfo().apply {
|
||||
userId = 0
|
||||
nickname = AdminProperties.nickname
|
||||
avatar =
|
||||
GitHubAvatar.newAvatarBuilder().build().createAsBase64((Long.MIN_VALUE..Long.MAX_VALUE).random())
|
||||
email = AdminProperties.email
|
||||
}
|
||||
|
||||
if (userService.save(user) && userInfoService.save(userInfo)) {
|
||||
logger.warn("First startup, create administrator - username: admin, password: $rawPassword")
|
||||
logger.warn("This information will only be shown once. Please change your password promptly after logging in.")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import retrofit2.converter.jackson.JacksonConverterFactory
|
||||
|
||||
/**
|
||||
* Jackson configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class JacksonConfig {
|
||||
@Bean
|
||||
fun jacksonConverterFactory(): JacksonConverterFactory {
|
||||
val mapper = JsonMapper.builder()
|
||||
.findAndAddModules()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.serializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.build()
|
||||
|
||||
return JacksonConverterFactory.create(mapper)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package top.fatweb.api.config
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor
|
||||
@@ -6,6 +6,12 @@ import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerIntercept
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
/**
|
||||
* Mybatis-plus configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class MybatisPlusConfig {
|
||||
@Bean
|
||||
@@ -16,5 +22,4 @@ class MybatisPlusConfig {
|
||||
|
||||
return mybatisPlusInterceptor
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package top.fatweb.api.config
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo
|
||||
@@ -12,6 +12,12 @@ import org.springframework.data.redis.core.RedisTemplate
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer
|
||||
|
||||
/**
|
||||
* Redis configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class RedisConfig {
|
||||
@Bean
|
||||
@@ -1,4 +1,4 @@
|
||||
package top.fatweb.api.config
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
@@ -6,23 +6,31 @@ import org.springframework.security.authentication.AuthenticationManager
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||
import org.springframework.security.config.annotation.web.configurers.*
|
||||
import org.springframework.security.config.http.SessionCreationPolicy
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||
import org.springframework.security.web.SecurityFilterChain
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
|
||||
import org.springframework.web.cors.CorsConfiguration
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
|
||||
import top.fatweb.api.filter.JwtAuthenticationTokenFilter
|
||||
import top.fatweb.api.handler.JwtAccessDeniedHandler
|
||||
import top.fatweb.api.handler.JwtAuthenticationEntryPointHandler
|
||||
import top.fatweb.oxygen.api.filter.JwtAuthenticationTokenFilter
|
||||
import top.fatweb.oxygen.api.handler.JwtAccessDeniedHandler
|
||||
import top.fatweb.oxygen.api.handler.JwtAuthenticationEntryPointHandler
|
||||
|
||||
/**
|
||||
* Spring Security configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see JwtAuthenticationTokenFilter
|
||||
* @see JwtAuthenticationEntryPointHandler
|
||||
* @see JwtAccessDeniedHandler
|
||||
*/
|
||||
@Configuration
|
||||
@EnableMethodSecurity
|
||||
class SecurityConfig(
|
||||
val jwtAuthenticationTokenFilter: JwtAuthenticationTokenFilter,
|
||||
val authenticationEntryPointHandler: JwtAuthenticationEntryPointHandler,
|
||||
val accessDeniedHandler: JwtAccessDeniedHandler
|
||||
private val jwtAuthenticationTokenFilter: JwtAuthenticationTokenFilter,
|
||||
private val authenticationEntryPointHandler: JwtAuthenticationEntryPointHandler,
|
||||
private val accessDeniedHandler: JwtAccessDeniedHandler
|
||||
) {
|
||||
@Bean
|
||||
fun passwordEncoder() = BCryptPasswordEncoder()
|
||||
@@ -47,43 +55,51 @@ class SecurityConfig(
|
||||
@Bean
|
||||
fun securityFilterChain(httpSecurity: HttpSecurity): SecurityFilterChain = httpSecurity
|
||||
// Disable CSRF
|
||||
.csrf { csrfConfigurer: CsrfConfigurer<HttpSecurity> -> csrfConfigurer.disable() }
|
||||
.csrf {
|
||||
it.disable()
|
||||
}
|
||||
// Do not get SecurityContent by Session
|
||||
.sessionManagement { sessionManagementConfigurer: SessionManagementConfigurer<HttpSecurity?> ->
|
||||
sessionManagementConfigurer.sessionCreationPolicy(
|
||||
.sessionManagement {
|
||||
it.sessionCreationPolicy(
|
||||
SessionCreationPolicy.STATELESS
|
||||
)
|
||||
}
|
||||
.authorizeHttpRequests { authorizeHttpRequests: AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry ->
|
||||
authorizeHttpRequests
|
||||
.authorizeHttpRequests {
|
||||
it
|
||||
// Allow anonymous access
|
||||
.requestMatchers(
|
||||
"/login",
|
||||
"/error/thrown",
|
||||
"/doc.html",
|
||||
"/swagger-ui/**",
|
||||
"/webjars/**",
|
||||
"/v3/**",
|
||||
"/swagger-ui.html",
|
||||
"/favicon.ico"
|
||||
"/favicon.ico",
|
||||
"/login",
|
||||
"/register",
|
||||
"/forget",
|
||||
"/retrieve"
|
||||
).anonymous()
|
||||
.requestMatchers("/tool/detail/**", "/tool/store", "/tool/store/*", "/system/user/info/*").permitAll()
|
||||
// Authentication required
|
||||
.anyRequest().authenticated()
|
||||
}
|
||||
|
||||
.logout { logoutConfigurer: LogoutConfigurer<HttpSecurity> -> logoutConfigurer.disable() }
|
||||
.logout {
|
||||
it.disable()
|
||||
}
|
||||
|
||||
.exceptionHandling { exceptionHandlingConfigurer: ExceptionHandlingConfigurer<HttpSecurity?> ->
|
||||
exceptionHandlingConfigurer.authenticationEntryPoint(
|
||||
.exceptionHandling {
|
||||
it.authenticationEntryPoint(
|
||||
authenticationEntryPointHandler
|
||||
)
|
||||
exceptionHandlingConfigurer.accessDeniedHandler(
|
||||
it.accessDeniedHandler(
|
||||
accessDeniedHandler
|
||||
)
|
||||
}
|
||||
|
||||
.cors { cors: CorsConfigurer<HttpSecurity?> ->
|
||||
cors.configurationSource(
|
||||
.cors {
|
||||
it.configurationSource(
|
||||
corsConfigurationSource()
|
||||
)
|
||||
}
|
||||
@@ -1,22 +1,27 @@
|
||||
package top.fatweb.api.config
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI
|
||||
import io.swagger.v3.oas.models.info.Contact
|
||||
import io.swagger.v3.oas.models.info.Info
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import top.fatweb.api.constant.ServerConstants
|
||||
import top.fatweb.oxygen.api.properties.ServerProperties
|
||||
|
||||
/**
|
||||
* Swagger API doc configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class SwaggerConfig {
|
||||
|
||||
@Bean
|
||||
fun customOpenAPI(): OpenAPI? {
|
||||
val contact = Contact().name("FatttSnake").url("https://fatweb.top").email("fatttsnake@fatweb.top")
|
||||
val contact = Contact().name("FatttSnake").url("https://fatweb.top").email("fatttsnake@gmail.com")
|
||||
return OpenAPI().info(
|
||||
Info().title("FatWeb API 文档").description("FatWeb 后端 API 文档,包含各个 Controller 调用信息")
|
||||
Info().title("Oxygen API 文档").description("Oxygen 后端 API 文档,包含各个 Controller 调用信息")
|
||||
.contact(contact).version(
|
||||
ServerConstants.version
|
||||
ServerProperties.version
|
||||
)
|
||||
)
|
||||
}
|
||||
24
src/main/kotlin/top/fatweb/oxygen/api/config/SysLogConfig.kt
Normal file
24
src/main/kotlin/top/fatweb/oxygen/api/config/SysLogConfig.kt
Normal file
@@ -0,0 +1,24 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||
import top.fatweb.oxygen.api.interceptor.SysLogInterceptor
|
||||
|
||||
/**
|
||||
* System log configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SysLogInterceptor
|
||||
* @see WebMvcConfigurer
|
||||
*/
|
||||
@Configuration
|
||||
class SysLogConfig(
|
||||
private val sysLogInterceptor: SysLogInterceptor
|
||||
) : WebMvcConfigurer {
|
||||
override fun addInterceptors(registry: InterceptorRegistry) {
|
||||
registry.addInterceptor(sysLogInterceptor).addPathPatterns("/**")
|
||||
.excludePathPatterns("/error/thrown", "/webjars/**")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.apache.velocity.app.VelocityEngine
|
||||
import org.apache.velocity.runtime.RuntimeConstants
|
||||
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
/**
|
||||
* Velocity engine configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
class VelocityEngineConfig {
|
||||
@Bean
|
||||
fun velocityEngine() = VelocityEngine().apply {
|
||||
setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath")
|
||||
setProperty("classpath.resource.loader.class", ClasspathResourceLoader::class.java.name)
|
||||
init()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||
import top.fatweb.oxygen.api.annotation.ApiController
|
||||
|
||||
/**
|
||||
* Web MVC configurer configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see WebMvcRegistrations
|
||||
*/
|
||||
@Configuration
|
||||
class WebMvcConfigurerConfig : WebMvcConfigurer {
|
||||
override fun configurePathMatch(configurer: PathMatchConfigurer) {
|
||||
configurer.addPathPrefix("/api/{API_VERSION}") { it.isAnnotationPresent(ApiController::class.java) }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
package top.fatweb.api.config
|
||||
package top.fatweb.oxygen.api.config
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
|
||||
import top.fatweb.api.util.ApiResponseMappingHandlerMapping
|
||||
import top.fatweb.oxygen.api.util.ApiResponseMappingHandlerMapping
|
||||
|
||||
/**
|
||||
* Web MVC registrations configuration
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see WebMvcRegistrations
|
||||
*/
|
||||
@Configuration
|
||||
class WebMvcRegistrationsConfig : WebMvcRegistrations {
|
||||
override fun getRequestMappingHandlerMapping(): RequestMappingHandlerMapping = ApiResponseMappingHandlerMapping()
|
||||
@@ -1,13 +1,16 @@
|
||||
package top.fatweb.api.controller
|
||||
package top.fatweb.oxygen.api.controller
|
||||
|
||||
import io.swagger.v3.oas.annotations.Hidden
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import top.fatweb.oxygen.api.annotation.HiddenController
|
||||
|
||||
@Hidden
|
||||
@RestController
|
||||
@RequestMapping("/error")
|
||||
/**
|
||||
* Exception controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@HiddenController(["/error"])
|
||||
class ExceptionController {
|
||||
@RequestMapping("/thrown")
|
||||
fun thrown(request: HttpServletRequest) {
|
||||
@@ -0,0 +1,204 @@
|
||||
package top.fatweb.oxygen.api.controller.api.v1
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import top.fatweb.oxygen.api.annotation.ApiController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.api.v1.avatar.AvatarBaseParam
|
||||
import top.fatweb.oxygen.api.param.api.v1.avatar.AvatarGitHubParam
|
||||
import top.fatweb.oxygen.api.service.api.v1.IAvatarService
|
||||
import top.fatweb.oxygen.api.vo.api.v1.avatar.AvatarBase64Vo
|
||||
|
||||
/**
|
||||
* Avatar controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IAvatarService
|
||||
*/
|
||||
@ApiController(value = "avatarControllerV1", path = ["/avatar"], name = "随机头像 V1", description = "随机头像相关接口")
|
||||
class AvatarController(
|
||||
private val avatarService: IAvatarService
|
||||
) {
|
||||
/**
|
||||
* Get random avatar
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "获取随机头像")
|
||||
@GetMapping(produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun getRandom(@Valid avatarBaseParam: AvatarBaseParam?): ByteArray =
|
||||
avatarService.random(avatarBaseParam)
|
||||
|
||||
/**
|
||||
* Get random avatar as base64
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "获取随机头像 Base64")
|
||||
@GetMapping("base64")
|
||||
fun getRandomBase64(
|
||||
@Valid avatarBaseParam: AvatarBaseParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS, data = avatarService.randomBase64(avatarBaseParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get triangle avatar
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "三角形头像")
|
||||
@GetMapping("/triangle", produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun triangle(@Valid avatarBaseParam: AvatarBaseParam?): ByteArray =
|
||||
avatarService.triangle(avatarBaseParam)
|
||||
|
||||
/**
|
||||
* Get triangle avatar as base64
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "三角形头像 Base64")
|
||||
@GetMapping("/triangle/base64")
|
||||
fun triangleBase64(
|
||||
@Valid avatarBaseParam: AvatarBaseParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS,
|
||||
data = avatarService.triangleBase64(avatarBaseParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get square avatar
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "正方形头像")
|
||||
@GetMapping("/square", produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun square(@Valid avatarBaseParam: AvatarBaseParam?): ByteArray =
|
||||
avatarService.square(avatarBaseParam)
|
||||
|
||||
/**
|
||||
* Get square avatar as base64
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "正方形头像 Base64")
|
||||
@GetMapping("/square/base64")
|
||||
fun squareBase64(
|
||||
@Valid avatarBaseParam: AvatarBaseParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS,
|
||||
data = avatarService.squareBase64(avatarBaseParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get identicon avatar
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "Identicon 头像")
|
||||
@GetMapping("/identicon", produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun identicon(@Valid avatarBaseParam: AvatarBaseParam?): ByteArray =
|
||||
avatarService.identicon(avatarBaseParam)
|
||||
|
||||
/**
|
||||
* Get identicon avatar as base64
|
||||
*
|
||||
* @param avatarBaseParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarBaseParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "Identicon 头像 Base64")
|
||||
@GetMapping("/identicon/base64")
|
||||
fun identiconBase64(
|
||||
@Valid avatarBaseParam: AvatarBaseParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS,
|
||||
data = avatarService.identiconBase64(avatarBaseParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get GitHub avatar
|
||||
*
|
||||
* @param avatarGitHubParam Avatar base parameters
|
||||
* @return Avatar byte array
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarGitHubParam
|
||||
* @see ByteArray
|
||||
*/
|
||||
@Operation(summary = "GitHub 头像")
|
||||
@GetMapping("/github", produces = [MediaType.IMAGE_PNG_VALUE])
|
||||
fun github(@Valid avatarGitHubParam: AvatarGitHubParam?): ByteArray =
|
||||
avatarService.github(avatarGitHubParam)
|
||||
|
||||
/**
|
||||
* Get GitHub avatar as base64
|
||||
*
|
||||
* @param avatarGitHubParam Avatar base parameters
|
||||
* @return Response object includes avatar base64 string
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see AvatarGitHubParam
|
||||
* @see ResponseResult
|
||||
* @see AvatarBase64Vo
|
||||
*/
|
||||
@Operation(summary = "GitHub 头像 Base64")
|
||||
@GetMapping("/github/base64")
|
||||
fun githubBase64(
|
||||
@Valid avatarGitHubParam: AvatarGitHubParam?
|
||||
): ResponseResult<AvatarBase64Vo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS,
|
||||
data = avatarService.githubBase64(avatarGitHubParam)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.permission.*
|
||||
import top.fatweb.oxygen.api.service.permission.IAuthenticationService
|
||||
import top.fatweb.oxygen.api.util.WebUtil
|
||||
import top.fatweb.oxygen.api.vo.permission.LoginVo
|
||||
import top.fatweb.oxygen.api.vo.permission.RegisterVo
|
||||
import top.fatweb.oxygen.api.vo.permission.TokenVo
|
||||
|
||||
/**
|
||||
* Authentication controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IAuthenticationService
|
||||
*/
|
||||
@BaseController(name = "身份认证", description = "身份认证相关接口")
|
||||
class AuthenticationController(
|
||||
private val authenticationService: IAuthenticationService
|
||||
) {
|
||||
/**
|
||||
* Register
|
||||
*
|
||||
* @param registerParam Register parameters
|
||||
* @return Response object includes user ID
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RegisterParam
|
||||
* @see ResponseResult
|
||||
* @see RegisterVo
|
||||
*/
|
||||
@Operation(summary = "注册")
|
||||
@PostMapping("/register")
|
||||
fun register(
|
||||
request: HttpServletRequest,
|
||||
@Valid @RequestBody registerParam: RegisterParam
|
||||
): ResponseResult<RegisterVo> = ResponseResult.success(
|
||||
ResponseCode.PERMISSION_REGISTER_SUCCESS,
|
||||
data = authenticationService.register(request, registerParam)
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* Send verify email
|
||||
*
|
||||
* @return Response object includes resend result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "发送验证邮件")
|
||||
@PostMapping("/resend")
|
||||
fun resend(): ResponseResult<Nothing> {
|
||||
authenticationService.resend()
|
||||
|
||||
return ResponseResult.success(ResponseCode.PERMISSION_RESEND_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify email
|
||||
*
|
||||
* @param verifyParam Verify parameters
|
||||
* @return Response object includes verify result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see VerifyParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "验证邮箱")
|
||||
@PostMapping("/verify")
|
||||
fun verify(@Valid @RequestBody verifyParam: VerifyParam): ResponseResult<Nothing> {
|
||||
authenticationService.verify(verifyParam)
|
||||
|
||||
return ResponseResult.success(ResponseCode.PERMISSION_VERIFY_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget password
|
||||
*
|
||||
* @param request
|
||||
* @param forgetParam Forget parameters
|
||||
* @return Response object includes forget result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see ForgetParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "忘记密码")
|
||||
@PostMapping("/forget")
|
||||
fun forget(request: HttpServletRequest, @Valid @RequestBody forgetParam: ForgetParam): ResponseResult<Nothing> {
|
||||
authenticationService.forget(request, forgetParam)
|
||||
|
||||
return ResponseResult.success(ResponseCode.PERMISSION_FORGET_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve password
|
||||
*
|
||||
* @param request
|
||||
* @param retrieveParam Retrieve parameters
|
||||
* @return Response object includes retrieve result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see RetrieveParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "找回密码")
|
||||
@PostMapping("/retrieve")
|
||||
fun retrieve(
|
||||
request: HttpServletRequest,
|
||||
@Valid @RequestBody retrieveParam: RetrieveParam
|
||||
): ResponseResult<Nothing> {
|
||||
authenticationService.retrieve(request, retrieveParam)
|
||||
|
||||
return ResponseResult.success(ResponseCode.PERMISSION_RETRIEVE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Login
|
||||
*
|
||||
* @param request
|
||||
* @param loginParam Login parameters
|
||||
* @return Response object includes login result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see LoginParam
|
||||
* @see ResponseResult
|
||||
* @see LoginVo
|
||||
*/
|
||||
@Operation(summary = "登录")
|
||||
@PostMapping("/login")
|
||||
fun login(request: HttpServletRequest, @Valid @RequestBody loginParam: LoginParam): ResponseResult<LoginVo> =
|
||||
ResponseResult.success(
|
||||
ResponseCode.PERMISSION_LOGIN_SUCCESS,
|
||||
"Login success",
|
||||
authenticationService.login(request, loginParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Logout
|
||||
*
|
||||
* @param request
|
||||
* @return Response object includes logout result
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "登出")
|
||||
@PostMapping("/logout")
|
||||
fun logout(request: HttpServletRequest): ResponseResult<Nothing> =
|
||||
when (authenticationService.logout(WebUtil.getToken(request))) {
|
||||
true -> ResponseResult.success(ResponseCode.PERMISSION_LOGOUT_SUCCESS, "Logout success", null)
|
||||
false -> ResponseResult.fail(ResponseCode.PERMISSION_LOGOUT_FAILED, "Logout failed", null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Renew token
|
||||
*
|
||||
* @param request
|
||||
* @return Response object includes new token
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see HttpServletRequest
|
||||
* @see ResponseResult
|
||||
* @see TokenVo
|
||||
*/
|
||||
@Operation(summary = "更新 Token")
|
||||
@GetMapping("/token")
|
||||
fun renewToken(request: HttpServletRequest): ResponseResult<TokenVo> = ResponseResult.success(
|
||||
ResponseCode.PERMISSION_TOKEN_RENEW_SUCCESS,
|
||||
"Token renew success",
|
||||
authenticationService.renewToken(WebUtil.getToken(request))
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.permission.group.*
|
||||
import top.fatweb.oxygen.api.service.permission.IGroupService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.GroupWithRoleVo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.GroupVo
|
||||
|
||||
/**
|
||||
* Group management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IGroupService
|
||||
*/
|
||||
@BaseController(path = ["/system/group"], name = "用户组管理", description = "用户组管理相关接口")
|
||||
class GroupController(
|
||||
val groupService: IGroupService
|
||||
) {
|
||||
/**
|
||||
* Get group by ID
|
||||
*
|
||||
* @param id Group ID
|
||||
* @return Response object includes group information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see GroupWithRoleVo
|
||||
*/
|
||||
@Operation(summary = "获取单个用户组")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:group:query:one')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<GroupWithRoleVo> =
|
||||
ResponseResult.databaseSuccess(data = groupService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get group paging information
|
||||
*
|
||||
* @param groupGetParam Get group parameters
|
||||
* @return Response object includes group paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupGetParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see GroupWithRoleVo
|
||||
*/
|
||||
@Operation(summary = "获取用户组")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:query:all')")
|
||||
fun get(@Valid groupGetParam: GroupGetParam?): ResponseResult<PageVo<GroupWithRoleVo>> =
|
||||
ResponseResult.databaseSuccess(
|
||||
data = groupService.getPage(groupGetParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get group list
|
||||
*
|
||||
* @return Response object includes group list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see GroupVo
|
||||
*/
|
||||
@Operation(summary = "获取用户组列表")
|
||||
@GetMapping("/list")
|
||||
@PreAuthorize("hasAnyAuthority('system:group:query:list', 'system:user:add:one', 'system:user:modify:one')")
|
||||
fun list(): ResponseResult<List<GroupVo>> =
|
||||
ResponseResult.databaseSuccess(
|
||||
data = groupService.getList()
|
||||
)
|
||||
|
||||
/**
|
||||
* Add group
|
||||
*
|
||||
* @param groupAddParam Add group parameters
|
||||
* @return Response object includes group information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupAddParam
|
||||
* @see ResponseResult
|
||||
* @see GroupVo
|
||||
*/
|
||||
@Operation(summary = "添加用户组")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:add:one')")
|
||||
fun add(@Valid @RequestBody groupAddParam: GroupAddParam): ResponseResult<GroupVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS, data = groupService.add(groupAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update group
|
||||
*
|
||||
* @param groupUpdateParam Update group parameters
|
||||
* @return Response object includes group information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see GroupVo
|
||||
*/
|
||||
@Operation(summary = "修改用户组")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:modify:one')")
|
||||
fun update(@Valid @RequestBody groupUpdateParam: GroupUpdateParam): ResponseResult<GroupVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS, data = groupService.update(groupUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update status of group
|
||||
*
|
||||
* @param groupUpdateStatusParam Update status of group parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupUpdateStatusParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "修改用户组状态")
|
||||
@PatchMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:modify:status')")
|
||||
fun updateStatus(@Valid @RequestBody groupUpdateStatusParam: GroupUpdateStatusParam): ResponseResult<Nothing> {
|
||||
groupService.status(groupUpdateStatusParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete group by ID
|
||||
*
|
||||
* @param id Group ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除用户组")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:group:delete:one')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> {
|
||||
groupService.deleteOne(id)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete group by list
|
||||
*
|
||||
* @param groupDeleteParam Delete group parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupDeleteParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "批量删除用户组")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:group:delete:multiple')")
|
||||
fun deleteList(@Valid @RequestBody groupDeleteParam: GroupDeleteParam): ResponseResult<Nothing> {
|
||||
groupService.delete(groupDeleteParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.service.permission.IPowerService
|
||||
import top.fatweb.oxygen.api.vo.permission.PowerSetVo
|
||||
|
||||
/**
|
||||
* Power management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPowerService
|
||||
*/
|
||||
@BaseController(path = ["/system/power"], name = "权限管理", description = "权限管理相关接口")
|
||||
class PowerController(
|
||||
private val powerService: IPowerService
|
||||
) {
|
||||
/**
|
||||
* Get power list
|
||||
*
|
||||
* @return Response object includes power list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see PowerSetVo
|
||||
*/
|
||||
@Operation(summary = "获取权限列表")
|
||||
@GetMapping("/list")
|
||||
@PreAuthorize("hasAnyAuthority('system:power:query:list', 'system:role:add:one', 'system:role:modify:one')")
|
||||
fun getList(): ResponseResult<PowerSetVo> = ResponseResult.databaseSuccess(data = powerService.getList())
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.permission.role.*
|
||||
import top.fatweb.oxygen.api.service.permission.IRoleService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.RoleWithPowerVo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.RoleVo
|
||||
|
||||
/**
|
||||
* Role management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IRoleService
|
||||
*/
|
||||
@BaseController(path = ["/system/role"], name = "角色管理", description = "角色管理相关接口")
|
||||
class RoleController(
|
||||
private val roleService: IRoleService
|
||||
) {
|
||||
/**
|
||||
* Get role by ID
|
||||
*
|
||||
* @param id Role ID
|
||||
* @return Response object includes role information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see RoleWithPowerVo
|
||||
*/
|
||||
@Operation(summary = "获取单个角色")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:role:query:one')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<RoleWithPowerVo> =
|
||||
ResponseResult.databaseSuccess(data = roleService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get role paging information
|
||||
*
|
||||
* @param roleGetParam Get role parameters
|
||||
* @return Response object includes role paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleGetParam
|
||||
* @see ResponseResult
|
||||
* @see RoleWithPowerVo
|
||||
*/
|
||||
@Operation(summary = "获取角色")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:query:all')")
|
||||
fun get(roleGetParam: RoleGetParam?): ResponseResult<PageVo<RoleWithPowerVo>> =
|
||||
ResponseResult.databaseSuccess(
|
||||
data = roleService.getPage(roleGetParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get role list
|
||||
*
|
||||
* @return Response object includes role list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see RoleVo
|
||||
*/
|
||||
@Operation(summary = "获取角色列表")
|
||||
@GetMapping("/list")
|
||||
@PreAuthorize("hasAnyAuthority('system:role:query:list', 'system:group:add:one', 'system:group:modify:one', 'system:user:add:one', 'system:user:modify:one')")
|
||||
fun list(): ResponseResult<List<RoleVo>> {
|
||||
return ResponseResult.databaseSuccess(
|
||||
data = roleService.getList()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add role
|
||||
*
|
||||
* @param roleAddParam Add role parameters
|
||||
* @return Response object includes role information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleAddParam
|
||||
* @see ResponseResult
|
||||
* @see RoleVo
|
||||
*/
|
||||
@Operation(summary = "添加角色")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:add:one')")
|
||||
fun add(@Valid @RequestBody roleAddParam: RoleAddParam): ResponseResult<RoleVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS, data = roleService.add(roleAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update role
|
||||
*
|
||||
* @param roleUpdateParam Update role parameters
|
||||
* @return Response object includes role information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see RoleVo
|
||||
*/
|
||||
@Operation(summary = "修改角色")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:modify:one')")
|
||||
fun update(@Valid @RequestBody roleUpdateParam: RoleUpdateParam): ResponseResult<RoleVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS, data = roleService.update(roleUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update status of role
|
||||
*
|
||||
* @param roleUpdateStatusParam Update status of role parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleUpdateStatusParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "修改角色状态")
|
||||
@PatchMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:modify:status')")
|
||||
fun status(@Valid @RequestBody roleUpdateStatusParam: RoleUpdateStatusParam): ResponseResult<Nothing> {
|
||||
roleService.status(roleUpdateStatusParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete role by ID
|
||||
*
|
||||
* @param id
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除角色")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:role:delete:one')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> {
|
||||
roleService.deleteOne(id)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete role by list
|
||||
*
|
||||
* @param roleDeleteParam Delete role parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleDeleteParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "批量删除角色")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:role:delete:multiple')")
|
||||
fun deleteList(@Valid @RequestBody roleDeleteParam: RoleDeleteParam): ResponseResult<Nothing> {
|
||||
roleService.delete(roleDeleteParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
package top.fatweb.oxygen.api.controller.permission
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.permission.user.*
|
||||
import top.fatweb.oxygen.api.service.permission.IUserService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithPasswordRoleInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithPowerInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithRoleInfoVo
|
||||
|
||||
/**
|
||||
* User management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IUserService
|
||||
*/
|
||||
@BaseController(path = ["/system/user"], name = "用户管理", description = "用户管理相关接口")
|
||||
class UserController(
|
||||
private val userService: IUserService
|
||||
) {
|
||||
/**
|
||||
* Get current user information
|
||||
*
|
||||
* @return Response object includes user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see UserWithPowerInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取当前用户信息")
|
||||
@GetMapping("/info")
|
||||
fun getInfo(): ResponseResult<UserWithPowerInfoVo> =
|
||||
ResponseResult.databaseSuccess(data = userService.getInfo())
|
||||
|
||||
/**
|
||||
* Get basic user information
|
||||
*
|
||||
* @param username Username
|
||||
* @return Response object includes user basic information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see UserWithPowerInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取指定用户基本信息")
|
||||
@GetMapping("/info/{username}")
|
||||
fun getBasicInfo(@PathVariable username: String): ResponseResult<UserWithInfoVo> =
|
||||
ResponseResult.databaseSuccess(data = userService.getBasicInfo(username))
|
||||
|
||||
/**
|
||||
* Update current user information
|
||||
*
|
||||
* @param userInfoUpdateParam Update user information parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserInfoUpdateParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "更新当前用户信息")
|
||||
@PatchMapping("info")
|
||||
fun updateInfo(@RequestBody @Valid userInfoUpdateParam: UserInfoUpdateParam): ResponseResult<Nothing> =
|
||||
if (userService.updateInfo(userInfoUpdateParam)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
else ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_FAILED)
|
||||
|
||||
/**
|
||||
* Change password
|
||||
*
|
||||
* @param userChangePasswordParam User change password parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserChangePasswordParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "更改密码")
|
||||
@PostMapping("info")
|
||||
fun password(@RequestBody @Valid userChangePasswordParam: UserChangePasswordParam): ResponseResult<Nothing> {
|
||||
userService.password(userChangePasswordParam)
|
||||
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user by ID
|
||||
*
|
||||
* @param id User ID
|
||||
* @return Response object includes user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取单个用户")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:user:query:one')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<UserWithRoleInfoVo> =
|
||||
ResponseResult.databaseSuccess(data = userService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get user paging information
|
||||
*
|
||||
* @param userGetParam Get user parameters
|
||||
* @return Response object includes user paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserGetParam
|
||||
* @see ResponseResult
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取用户")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:query:all')")
|
||||
fun get(@Valid userGetParam: UserGetParam?): ResponseResult<PageVo<UserWithRoleInfoVo>> =
|
||||
ResponseResult.databaseSuccess(
|
||||
data = userService.getPage(userGetParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Add user
|
||||
*
|
||||
* @param userAddParam Add user parameters
|
||||
* @return Response object includes user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserAddParam
|
||||
* @see ResponseResult
|
||||
* @see UserWithPasswordRoleInfoVo
|
||||
*/
|
||||
@Operation(summary = "添加用户")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:add:one')")
|
||||
fun add(@Valid @RequestBody userAddParam: UserAddParam): ResponseResult<UserWithPasswordRoleInfoVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS, data = userService.add(userAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update user
|
||||
*
|
||||
* @param userUpdateParam Update user parameters
|
||||
* @return Response object includes user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
@Operation(summary = "修改用户")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:modify:one')")
|
||||
fun update(@Valid @RequestBody userUpdateParam: UserUpdateParam): ResponseResult<UserWithRoleInfoVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS, data = userService.update(userUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update user password
|
||||
*
|
||||
* @param userUpdatePasswordParam Update user password parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserUpdatePasswordParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "修改密码")
|
||||
@PatchMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:modify:password')")
|
||||
fun password(@Valid @RequestBody userUpdatePasswordParam: UserUpdatePasswordParam): ResponseResult<Nothing> {
|
||||
userService.password(userUpdatePasswordParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete user by ID
|
||||
*
|
||||
* @param id User ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除用户")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:user:delete:one')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> {
|
||||
userService.deleteOne(id)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete user by list
|
||||
*
|
||||
* @param userDeleteParam Delete user parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserDeleteParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "批量删除用户")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:user:delete:multiple')")
|
||||
fun deleteList(@Valid @RequestBody userDeleteParam: UserDeleteParam): ResponseResult<Nothing> {
|
||||
userService.delete(userDeleteParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package top.fatweb.oxygen.api.controller.system
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.DeleteMapping
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.PutMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.system.*
|
||||
import top.fatweb.oxygen.api.service.system.ISensitiveWordService
|
||||
import top.fatweb.oxygen.api.service.system.ISettingsService
|
||||
import top.fatweb.oxygen.api.vo.system.BaseSettingsVo
|
||||
import top.fatweb.oxygen.api.vo.system.MailSettingsVo
|
||||
import top.fatweb.oxygen.api.vo.system.SensitiveWordVo
|
||||
|
||||
/**
|
||||
* System settings management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ISettingsService
|
||||
* @see ISensitiveWordService
|
||||
*/
|
||||
@BaseController(path = ["/system/settings"], name = "系统设置", description = "系统设置相关接口")
|
||||
class SettingsController(
|
||||
private val settingsService: ISettingsService,
|
||||
private val sensitiveWordService: ISensitiveWordService
|
||||
) {
|
||||
/**
|
||||
* Get base settings
|
||||
*
|
||||
* @return Response object includes base settings information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see BaseSettingsVo
|
||||
*/
|
||||
@Operation(summary = "获取基础设置")
|
||||
@GetMapping("/base")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:query:base')")
|
||||
fun getApp(): ResponseResult<BaseSettingsVo> = ResponseResult.success(data = settingsService.getBase())
|
||||
|
||||
/**
|
||||
* Update base settings
|
||||
*
|
||||
* @param baseSettingsParam Base settings parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see BaseSettingsParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "更新基础设置")
|
||||
@PutMapping("/base")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:base')")
|
||||
fun updateApp(@RequestBody baseSettingsParam: BaseSettingsParam): ResponseResult<Nothing> {
|
||||
settingsService.updateBase(baseSettingsParam)
|
||||
return ResponseResult.success()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mail settings
|
||||
*
|
||||
* @return Response object includes mail settings
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see MailSettingsVo
|
||||
*/
|
||||
@Operation(summary = "获取邮件设置")
|
||||
@GetMapping("/mail")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:query:mail')")
|
||||
fun getMail(): ResponseResult<MailSettingsVo> = ResponseResult.success(data = settingsService.getMail())
|
||||
|
||||
/**
|
||||
* Update mail settings
|
||||
*
|
||||
* @param mailSettingsParam Mail settings parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see MailSettingsParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "更新邮件设置")
|
||||
@PutMapping("/mail")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:mail')")
|
||||
fun updateMail(@RequestBody mailSettingsParam: MailSettingsParam): ResponseResult<Nothing> {
|
||||
settingsService.updateMail(mailSettingsParam)
|
||||
return ResponseResult.success()
|
||||
}
|
||||
|
||||
/**
|
||||
* Send mail test
|
||||
*
|
||||
* @param mailSendParam Mail send parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see MailSendParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "邮件发送测试")
|
||||
@PostMapping("/mail")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:mail')")
|
||||
fun sendMail(@RequestBody @Valid mailSendParam: MailSendParam): ResponseResult<Nothing> {
|
||||
settingsService.sendMail(mailSendParam)
|
||||
return ResponseResult.success()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sensitive word settings
|
||||
*
|
||||
* @return Response object includes sensitive word settings information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see SensitiveWordVo
|
||||
*/
|
||||
@Operation(summary = "获取敏感词配置")
|
||||
@GetMapping("/sensitive")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:query:sensitive')")
|
||||
fun getSensitive(): ResponseResult<List<SensitiveWordVo>> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_SELECT_SUCCESS, data = sensitiveWordService.get())
|
||||
|
||||
/**
|
||||
* Add sensitive word
|
||||
*
|
||||
* @param sensitiveWordAddParam Add sensitive word settings parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SensitiveWordAddParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "添加敏感词")
|
||||
@PostMapping("/sensitive")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:sensitive')")
|
||||
fun addSensitive(@RequestBody @Valid sensitiveWordAddParam: SensitiveWordAddParam): ResponseResult<Nothing> {
|
||||
sensitiveWordService.add(sensitiveWordAddParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_INSERT_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update sensitive word
|
||||
*
|
||||
* @param sensitiveWordUpdateParam Update sensitive word settings parameters
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SensitiveWordUpdateParam
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "修改敏感词")
|
||||
@PutMapping("/sensitive")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:sensitive')")
|
||||
fun updateSensitive(@RequestBody sensitiveWordUpdateParam: SensitiveWordUpdateParam): ResponseResult<Nothing> {
|
||||
sensitiveWordService.update(sensitiveWordUpdateParam)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete sensitive word
|
||||
*
|
||||
* @see id Sensitive word ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除敏感词")
|
||||
@DeleteMapping("/sensitive/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:settings:modify:sensitive')")
|
||||
fun deleteSensitive(@PathVariable id: Long): ResponseResult<Nothing> {
|
||||
sensitiveWordService.delete(id)
|
||||
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package top.fatweb.oxygen.api.controller.system
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.system.ActiveInfoGetParam
|
||||
import top.fatweb.oxygen.api.param.system.OnlineInfoGetParam
|
||||
import top.fatweb.oxygen.api.service.system.IStatisticsService
|
||||
import top.fatweb.oxygen.api.vo.system.*
|
||||
|
||||
/**
|
||||
* Statistics management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IStatisticsService
|
||||
*/
|
||||
@BaseController(path = ["/system/statistics"], name = "统计接口", description = "系统信息统计相关接口")
|
||||
class StatisticsController(
|
||||
private val statisticService: IStatisticsService
|
||||
) {
|
||||
/**
|
||||
* Get software information
|
||||
*
|
||||
* @return Response object includes software information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see SoftwareInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取软件信息")
|
||||
@GetMapping("/software")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:base')")
|
||||
fun software(): ResponseResult<SoftwareInfoVo> = ResponseResult.success(data = statisticService.software())
|
||||
|
||||
/**
|
||||
* Get hardware information
|
||||
*
|
||||
* @return Response object includes hardware information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see HardwareInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取硬件信息")
|
||||
@GetMapping("/hardware")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:base')")
|
||||
fun hardware(): ResponseResult<HardwareInfoVo> = ResponseResult.success(data = statisticService.hardware())
|
||||
|
||||
/**
|
||||
* Get CPU information
|
||||
*
|
||||
* @return Response object includes CPU information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see CpuInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取 CPU 信息")
|
||||
@GetMapping("/cpu")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:real')")
|
||||
fun cpu(): ResponseResult<CpuInfoVo> = ResponseResult.success(data = statisticService.cpu())
|
||||
|
||||
/**
|
||||
* Get storage information
|
||||
*
|
||||
* @return Response object includes storage information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see StorageInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取存储信息")
|
||||
@GetMapping("/storage")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:real')")
|
||||
fun storage(): ResponseResult<StorageInfoVo> = ResponseResult.success(data = statisticService.storage())
|
||||
|
||||
/**
|
||||
* Get the history of online users information
|
||||
*
|
||||
* @param onlineInfoGetParam Get online information parameters
|
||||
* @return Response object includes online user information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see OnlineInfoGetParam
|
||||
* @see ResponseResult
|
||||
* @see OnlineInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取在线用户数量信息")
|
||||
@GetMapping("/online")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:usage')")
|
||||
fun online(onlineInfoGetParam: OnlineInfoGetParam?): ResponseResult<OnlineInfoVo> =
|
||||
ResponseResult.success(data = statisticService.online(onlineInfoGetParam))
|
||||
|
||||
/**
|
||||
* Get the history of active information
|
||||
*
|
||||
* @param activeInfoGetParam Get active information parameters
|
||||
* @return Response object includes history of active information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ActiveInfoGetParam
|
||||
* @see ResponseResult
|
||||
* @see ActiveInfoVo
|
||||
*/
|
||||
@Operation(summary = "获取用户活跃信息")
|
||||
@GetMapping("/active")
|
||||
@PreAuthorize("hasAnyAuthority('system:statistics:query:usage')")
|
||||
fun active(activeInfoGetParam: ActiveInfoGetParam): ResponseResult<ActiveInfoVo> =
|
||||
ResponseResult.success(data = statisticService.active(activeInfoGetParam))
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package top.fatweb.oxygen.api.controller.system
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.system.SysLogGetParam
|
||||
import top.fatweb.oxygen.api.service.system.ISysLogService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.system.SysLogVo
|
||||
|
||||
/**
|
||||
* System log viewer controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ISysLogService
|
||||
*/
|
||||
@BaseController(path = ["/system/log"], name = "系统日志", description = "系统日志相关接口")
|
||||
class SysLogController(
|
||||
private val sysLogService: ISysLogService
|
||||
) {
|
||||
/**
|
||||
* Get system log in page
|
||||
*
|
||||
* @param sysLogGetParam Get system log parameters
|
||||
* @return Response object includes system log in page
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SysLogGetParam
|
||||
* @see ResponseResult
|
||||
* @see SysLogVo
|
||||
*/
|
||||
@Operation(summary = "获取")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:log:query:all')")
|
||||
fun get(@Valid sysLogGetParam: SysLogGetParam?): ResponseResult<PageVo<SysLogVo>> {
|
||||
return ResponseResult.success(
|
||||
ResponseCode.DATABASE_SELECT_SUCCESS, data = sysLogService.getPage(sysLogGetParam)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.tool.ToolBaseAddParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolBaseUpdateParam
|
||||
import top.fatweb.oxygen.api.service.tool.IToolBaseService
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolBaseVo
|
||||
|
||||
/**
|
||||
* Tool base management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IToolBaseService
|
||||
*/
|
||||
@BaseController(path = ["/system/tool/base"], name = "工具基板管理", description = "工具基板管理相关接口")
|
||||
class BaseController(
|
||||
private val toolBaseService: IToolBaseService
|
||||
) {
|
||||
/**
|
||||
* Get tool base by ID
|
||||
*
|
||||
* @param id Tool base ID
|
||||
* @return Response object includes tool base information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
@Operation(summary = "获取单个基板")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:base')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<ToolBaseVo> =
|
||||
ResponseResult.databaseSuccess(data = toolBaseService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get tool base list
|
||||
*
|
||||
* @return Response object includes tool base list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
@Operation(summary = "获取基板")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:base', 'system:tool:add:template', 'system:tool:modify:template')")
|
||||
fun get(): ResponseResult<List<ToolBaseVo>> =
|
||||
ResponseResult.databaseSuccess(data = toolBaseService.get())
|
||||
|
||||
/**
|
||||
* Add tool base
|
||||
*
|
||||
* @param toolBaseAddParam Add tool base parameters
|
||||
* @return Response object includes tool base information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolBaseAddParam
|
||||
* @see ResponseResult
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
@Operation(summary = "新增基板")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:add:base')")
|
||||
fun add(@RequestBody @Valid toolBaseAddParam: ToolBaseAddParam): ResponseResult<ToolBaseVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS,
|
||||
data = toolBaseService.add(toolBaseAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update tool base
|
||||
*
|
||||
* @param toolBaseUpdateParam Update tool base parameters
|
||||
* @return Response object includes tool base information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolBaseUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
@Operation(summary = "更新基板")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:base')")
|
||||
fun update(@RequestBody @Valid toolBaseUpdateParam: ToolBaseUpdateParam): ResponseResult<ToolBaseVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = toolBaseService.update(toolBaseUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Delete tool base by ID
|
||||
*
|
||||
* @param id Tool base ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除基板")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:delete:base')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (toolBaseService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCategoryAddParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCategoryUpdateParam
|
||||
import top.fatweb.oxygen.api.service.tool.IToolCategoryService
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolCategoryVo
|
||||
|
||||
/**
|
||||
* Tool category management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IToolCategoryService
|
||||
*/
|
||||
@BaseController(path = ["/system/tool/category"], name = "工具类别管理", description = "工具列别管理相关接口")
|
||||
class CategoryController(
|
||||
private val toolCategoryService: IToolCategoryService
|
||||
) {
|
||||
/**
|
||||
* Get tool category by ID
|
||||
*
|
||||
* @param id Tool category ID
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Operation(summary = "获取单个类别")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:category')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<ToolCategoryVo> =
|
||||
ResponseResult.databaseSuccess(data = toolCategoryService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get tool category list
|
||||
*
|
||||
* @return Response object includes tool template list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Operation(summary = "获取类别")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:category')")
|
||||
fun get(): ResponseResult<List<ToolCategoryVo>> =
|
||||
ResponseResult.databaseSuccess(data = toolCategoryService.get())
|
||||
|
||||
/**
|
||||
* Add tool category
|
||||
*
|
||||
* @param toolCategoryAddParam Add tool category parameters
|
||||
* @return Response object includes tool category information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategoryAddParam
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Operation(summary = "新增类别")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:add:category')")
|
||||
fun add(@RequestBody @Valid toolCategoryAddParam: ToolCategoryAddParam): ResponseResult<ToolCategoryVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS,
|
||||
data = toolCategoryService.add(toolCategoryAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update tool category
|
||||
*
|
||||
* @param toolCategoryUpdateParam Update tool category parameters
|
||||
* @return Response object includes tool category information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategoryUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Operation(summary = "更新类别")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:category')")
|
||||
fun update(@RequestBody @Valid toolCategoryUpdateParam: ToolCategoryUpdateParam): ResponseResult<ToolCategoryVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = toolCategoryService.update(toolCategoryUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Delete tool category
|
||||
*
|
||||
* @param id Tool category ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除类别")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:delete:category')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (toolCategoryService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCreateParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolUpdateParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolUpgradeParam
|
||||
import top.fatweb.oxygen.api.service.tool.IEditService
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolCategoryVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolTemplateVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolVo
|
||||
|
||||
/**
|
||||
* Tool edit controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IEditService
|
||||
*/
|
||||
@BaseController(path = ["/tool"], name = "工具编辑", description = "工具编辑相关接口")
|
||||
class EditController(
|
||||
private val editService: IEditService
|
||||
) {
|
||||
/**
|
||||
* Get tool template list
|
||||
*
|
||||
* @return Response object includes tool template list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "获取模板")
|
||||
@GetMapping("/template")
|
||||
fun getTemplate(): ResponseResult<List<ToolTemplateVo>> =
|
||||
ResponseResult.databaseSuccess(data = editService.getTemplate())
|
||||
|
||||
/**
|
||||
* Get tool template by ID
|
||||
*
|
||||
* @param id ID
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "获取单个模板")
|
||||
@GetMapping("/template/{id}")
|
||||
fun getTemplate(@PathVariable id: Long): ResponseResult<ToolTemplateVo> =
|
||||
ResponseResult.databaseSuccess(data = editService.getTemplate(id))
|
||||
|
||||
/**
|
||||
* Get tool category list
|
||||
*
|
||||
* @return Response object includes tool category list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
@Operation(summary = "获取类别")
|
||||
@GetMapping("/category")
|
||||
fun getCategory(): ResponseResult<List<ToolCategoryVo>> =
|
||||
ResponseResult.databaseSuccess(data = editService.getCategory())
|
||||
|
||||
/**
|
||||
* Create tool
|
||||
*
|
||||
* @param toolCreateParam Create tool parameters
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCreateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "创建工具")
|
||||
@PostMapping
|
||||
fun create(@RequestBody @Valid toolCreateParam: ToolCreateParam): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_INSERT_SUCCESS, data = editService.create(toolCreateParam))
|
||||
|
||||
/**
|
||||
* Upgrade tool
|
||||
*
|
||||
* @param toolUpgradeParam Upgrade tool parameters
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolUpgradeParam
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "升级工具")
|
||||
@PatchMapping
|
||||
fun upgrade(@RequestBody @Valid toolUpgradeParam: ToolUpgradeParam): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = editService.upgrade(toolUpgradeParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Get personal tool
|
||||
*
|
||||
* @return Response object includes tool list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "获取个人工具")
|
||||
@GetMapping
|
||||
fun get(): ResponseResult<List<ToolVo>> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_SELECT_SUCCESS, data = editService.get())
|
||||
|
||||
/**
|
||||
* Get tool detail
|
||||
*
|
||||
* @param username Username
|
||||
* @param toolId Tool ID
|
||||
* @param ver Version
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "获取工具内容")
|
||||
@GetMapping("/detail/{username}/{toolId}/{ver}")
|
||||
fun detail(
|
||||
@PathVariable username: String,
|
||||
@PathVariable toolId: String,
|
||||
@PathVariable ver: String
|
||||
): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_SELECT_SUCCESS,
|
||||
data = editService.detail(username, toolId, ver)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update tool
|
||||
*
|
||||
* @param toolUpdateParam Update tool parameters
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "更新工具")
|
||||
@PutMapping
|
||||
fun update(@RequestBody @Valid toolUpdateParam: ToolUpdateParam): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS, data = editService.update(toolUpdateParam))
|
||||
|
||||
/**
|
||||
* Submit tool review
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "提交工具审核")
|
||||
@PostMapping("/{id}")
|
||||
fun submit(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (editService.submit(id)) ResponseResult.success(ResponseCode.TOOL_SUBMIT_SUCCESS)
|
||||
else ResponseResult.fail(ResponseCode.TOOL_SUBMIT_ERROR)
|
||||
|
||||
/**
|
||||
* Cancel tool review
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "取消工具审核")
|
||||
@PutMapping("/{id}")
|
||||
fun cancel(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (editService.cancel(id)) ResponseResult.success(ResponseCode.TOOL_CANCEL_SUCCESS)
|
||||
else ResponseResult.fail(ResponseCode.TOOL_CANCEL_ERROR)
|
||||
|
||||
/**
|
||||
* Delete tool
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除工具")
|
||||
@DeleteMapping("/{id}")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (editService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.tool.ToolManagementGetParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolManagementPassParam
|
||||
import top.fatweb.oxygen.api.service.tool.IManagementService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolVo
|
||||
|
||||
/**
|
||||
* Tool management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IManagementService
|
||||
*/
|
||||
@BaseController(path = ["/system/tool"], name = "工具管理", description = "工具管理相关接口")
|
||||
class ManagementController(
|
||||
private val managementService: IManagementService
|
||||
) {
|
||||
/**
|
||||
* Get tool by ID
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "获取单个工具")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:tool')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(data = managementService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get tool paging information
|
||||
*
|
||||
* @param toolManagementGetParam Get tool parameters in tool management
|
||||
* @return Response object includes tool paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolManagementGetParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "获取工具")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:tool')")
|
||||
fun get(toolManagementGetParam: ToolManagementGetParam): ResponseResult<PageVo<ToolVo>> =
|
||||
ResponseResult.databaseSuccess(data = managementService.getPage(toolManagementGetParam))
|
||||
|
||||
/**
|
||||
* Pass tool review
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @param toolManagementPassParam Pass tool parameters in tool management
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolManagementPassParam
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "通过审核")
|
||||
@PostMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:tool')")
|
||||
fun pass(
|
||||
@PathVariable id: Long,
|
||||
@RequestBody @Valid toolManagementPassParam: ToolManagementPassParam
|
||||
): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = managementService.pass(id, toolManagementPassParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Reject tool review
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "驳回审核")
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:tool')")
|
||||
fun reject(@PathVariable id: Long): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS, data = managementService.reject(id))
|
||||
|
||||
/**
|
||||
* Put off shelve
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object includes tool information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolVo
|
||||
*/
|
||||
@Operation(summary = "下架")
|
||||
@PatchMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:tool')")
|
||||
fun offShelve(@PathVariable id: Long): ResponseResult<ToolVo> =
|
||||
ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS, data = managementService.offShelve(id))
|
||||
|
||||
/**
|
||||
* Delete tool
|
||||
*
|
||||
* @param id Tool ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除工具")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:delete:tool')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (managementService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.PageSortParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolStoreGetParam
|
||||
import top.fatweb.oxygen.api.service.tool.IStoreService
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolVo
|
||||
|
||||
/**
|
||||
* Tool store controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IStoreService
|
||||
*/
|
||||
@BaseController(path = ["/tool/store"], name = "工具商店", description = "工具商店相关接口")
|
||||
class StoreController(
|
||||
private val storeService: IStoreService
|
||||
) {
|
||||
/**
|
||||
* Get store tool paging information
|
||||
*
|
||||
* @param toolStoreGetParam Get tool parameters in tool store
|
||||
* @return Response object includes store tool paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolStoreGetParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
@GetMapping
|
||||
fun get(@Valid toolStoreGetParam: ToolStoreGetParam): ResponseResult<PageVo<ToolVo>> =
|
||||
ResponseResult.databaseSuccess(data = storeService.getPage(toolStoreGetParam))
|
||||
|
||||
/**
|
||||
* Get store tool paging information by username
|
||||
*
|
||||
* @param username Username
|
||||
* @param pageSortParam Page sort parameters
|
||||
* @return Response object includes store tool paging information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see PageSortParam
|
||||
* @see ResponseResult
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
@GetMapping("/{username}")
|
||||
fun get(@PathVariable username: String, @Valid pageSortParam: PageSortParam): ResponseResult<PageVo<ToolVo>> =
|
||||
ResponseResult.databaseSuccess(data = storeService.getPage(pageSortParam, username))
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package top.fatweb.oxygen.api.controller.tool
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import top.fatweb.oxygen.api.annotation.BaseController
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseCode
|
||||
import top.fatweb.oxygen.api.entity.common.ResponseResult
|
||||
import top.fatweb.oxygen.api.param.tool.ToolTemplateAddParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolTemplateUpdateParam
|
||||
import top.fatweb.oxygen.api.service.tool.IToolTemplateService
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolTemplateVo
|
||||
|
||||
/**
|
||||
* Tool template management controller
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IToolTemplateService
|
||||
*/
|
||||
@BaseController(path = ["/system/tool/template"], name = "工具模板管理", description = "工具模板管理相关接口")
|
||||
class TemplateController(
|
||||
private val toolTemplateService: IToolTemplateService
|
||||
) {
|
||||
/**
|
||||
* Get tool template by ID
|
||||
*
|
||||
* @param id Tool template ID
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "获取单个模板")
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:template')")
|
||||
fun getOne(@PathVariable id: Long): ResponseResult<ToolTemplateVo> =
|
||||
ResponseResult.databaseSuccess(data = toolTemplateService.getOne(id))
|
||||
|
||||
/**
|
||||
* Get tool template list
|
||||
*
|
||||
* @return Response object includes tool template list
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "获取模板")
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:query:template')")
|
||||
fun get(): ResponseResult<List<ToolTemplateVo>> =
|
||||
ResponseResult.databaseSuccess(data = toolTemplateService.get())
|
||||
|
||||
/**
|
||||
* Add tool template
|
||||
*
|
||||
* @param toolTemplateAddParam Add tool template parameters
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolTemplateAddParam
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "添加模板")
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:add:template')")
|
||||
fun add(@RequestBody @Valid toolTemplateAddParam: ToolTemplateAddParam): ResponseResult<ToolTemplateVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_INSERT_SUCCESS,
|
||||
data = toolTemplateService.add(toolTemplateAddParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Update tool template
|
||||
*
|
||||
* @param toolTemplateUpdateParam Update tool template parameters
|
||||
* @return Response object includes tool template information
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolTemplateUpdateParam
|
||||
* @see ResponseResult
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
@Operation(summary = "更新模板")
|
||||
@PutMapping
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:modify:template')")
|
||||
fun update(@RequestBody @Valid toolTemplateUpdateParam: ToolTemplateUpdateParam): ResponseResult<ToolTemplateVo> =
|
||||
ResponseResult.databaseSuccess(
|
||||
ResponseCode.DATABASE_UPDATE_SUCCESS,
|
||||
data = toolTemplateService.update(toolTemplateUpdateParam)
|
||||
)
|
||||
|
||||
/**
|
||||
* Delete tool template
|
||||
*
|
||||
* @param id Tool template ID
|
||||
* @return Response object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseResult
|
||||
*/
|
||||
@Operation(summary = "删除模板")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('system:tool:delete:template')")
|
||||
fun delete(@PathVariable id: Long): ResponseResult<Nothing> =
|
||||
if (toolTemplateService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS)
|
||||
else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.Func
|
||||
import top.fatweb.oxygen.api.vo.permission.base.FuncVo
|
||||
|
||||
/**
|
||||
* Function converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object FuncConverter {
|
||||
/**
|
||||
* Convert Func object into FuncVo object
|
||||
*
|
||||
* @param func Func object
|
||||
* @return FuncVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Func
|
||||
* @see FuncVo
|
||||
*/
|
||||
fun funcToFuncVo(func: Func) = FuncVo(
|
||||
id = func.id,
|
||||
name = func.name,
|
||||
parentId = func.parentId,
|
||||
menuId = func.menuId
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.oxygen.api.entity.permission.Group
|
||||
import top.fatweb.oxygen.api.entity.permission.Role
|
||||
import top.fatweb.oxygen.api.param.permission.group.GroupAddParam
|
||||
import top.fatweb.oxygen.api.param.permission.group.GroupUpdateParam
|
||||
import top.fatweb.oxygen.api.param.permission.group.GroupUpdateStatusParam
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.GroupWithRoleVo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.GroupVo
|
||||
|
||||
/**
|
||||
* Group converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object GroupConverter {
|
||||
/**
|
||||
* Convert Group object into GroupVo object
|
||||
*
|
||||
* @param group Group object
|
||||
* @return GroupVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Group
|
||||
* @see GroupVo
|
||||
*/
|
||||
fun groupToGroupVo(group: Group) = GroupVo(
|
||||
id = group.id,
|
||||
name = group.name,
|
||||
enable = group.enable == 1,
|
||||
createTime = group.createTime,
|
||||
updateTime = group.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert Group object into GroupWithRoleVo object
|
||||
*
|
||||
* @param group Group object
|
||||
* @return GroupWithRoleVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Group
|
||||
* @see GroupWithRoleVo
|
||||
*/
|
||||
fun groupToGroupWithRoleVo(group: Group) = GroupWithRoleVo(
|
||||
id = group.id,
|
||||
name = group.name,
|
||||
enable = group.enable == 1,
|
||||
createTime = group.createTime,
|
||||
updateTime = group.updateTime,
|
||||
roles = group.roles?.map(RoleConverter::roleToRoleVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert IPage<Group> object into PageVo<GroupWithRoleVo> object
|
||||
*
|
||||
* @param groupPage IPage<Group> object
|
||||
* @return PageVo<GroupWithRoleVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPage
|
||||
* @see Group
|
||||
* @see PageVo
|
||||
* @see GroupWithRoleVo
|
||||
*/
|
||||
fun groupPageToGroupWithRolePageVo(groupPage: IPage<Group>) = PageVo(
|
||||
total = groupPage.total,
|
||||
pages = groupPage.pages,
|
||||
size = groupPage.size,
|
||||
current = groupPage.current,
|
||||
records = groupPage.records.map(::groupToGroupWithRoleVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert GroupAddParam object into Group object
|
||||
*
|
||||
* @param groupAddParam GroupAddParam object
|
||||
* @return Group object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupAddParam
|
||||
* @see Group
|
||||
*/
|
||||
fun groupAddParamToGroup(groupAddParam: GroupAddParam) = Group().apply {
|
||||
name = groupAddParam.name
|
||||
enable = if (groupAddParam.enable) 1 else 0
|
||||
roles = groupAddParam.roleIds?.map { Role().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GroupUpdateParam object into Group object
|
||||
*
|
||||
* @param groupUpdateParam GroupUpdateParam object
|
||||
* @return Group object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupUpdateParam
|
||||
* @see Group
|
||||
*/
|
||||
fun groupUpdateParamToGroup(groupUpdateParam: GroupUpdateParam) = Group().apply {
|
||||
id = groupUpdateParam.id
|
||||
name = groupUpdateParam.name
|
||||
enable = if (groupUpdateParam.enable) 1 else 0
|
||||
roles = groupUpdateParam.roleIds?.map { Role().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GroupUpdateStatusParam object into Group object
|
||||
*
|
||||
* @param groupUpdateStatusParam GroupUpdateStatusParam object
|
||||
* @return Group object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see GroupUpdateStatusParam
|
||||
* @see Group
|
||||
*/
|
||||
fun groupUpdateStatusParamToGroup(groupUpdateStatusParam: GroupUpdateStatusParam) = Group().apply {
|
||||
id = groupUpdateStatusParam.id
|
||||
enable = if (groupUpdateStatusParam.enable) 1 else 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.Menu
|
||||
import top.fatweb.oxygen.api.vo.permission.base.MenuVo
|
||||
|
||||
/**
|
||||
* Menu converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object MenuConverter {
|
||||
/**
|
||||
* Convert Menu object into MenuVo object
|
||||
*
|
||||
* @param menu Menu object
|
||||
* @return MenuVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Menu
|
||||
* @see MenuVo
|
||||
*/
|
||||
fun menuToMenuVo(menu: Menu) = MenuVo(
|
||||
id = menu.id,
|
||||
name = menu.name,
|
||||
url = menu.url,
|
||||
parentId = menu.parentId,
|
||||
moduleId = menu.moduleId
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.Module
|
||||
import top.fatweb.oxygen.api.vo.permission.base.ModuleVo
|
||||
|
||||
/**
|
||||
* Module converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ModuleConverter {
|
||||
/**
|
||||
* Convert Module object into ModuleVo object
|
||||
*
|
||||
* @param module Module object
|
||||
* @return ModuleVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Module
|
||||
* @see ModuleVo
|
||||
*/
|
||||
fun moduleToModuleVo(module: Module) = ModuleVo(
|
||||
id = module.id,
|
||||
name = module.name
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.Operation
|
||||
import top.fatweb.oxygen.api.vo.permission.base.OperationVo
|
||||
|
||||
/**
|
||||
* Operation converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object OperationConverter {
|
||||
/**
|
||||
* Convert Operation object into OperationVo object
|
||||
*
|
||||
* @param operation Operation object
|
||||
* @return OperationVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Operation
|
||||
* @see OperationVo
|
||||
*/
|
||||
fun operationToOperationVo(operation: Operation) = OperationVo(
|
||||
id = operation.id,
|
||||
name = operation.name,
|
||||
code = operation.code,
|
||||
funcId = operation.funcId
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.PowerSet
|
||||
import top.fatweb.oxygen.api.vo.permission.PowerSetVo
|
||||
|
||||
/**
|
||||
* Power converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object PowerConverter {
|
||||
/**
|
||||
* Convert PowerSet object into PowerSetVo object
|
||||
*
|
||||
* @param powerSet PowerSet object
|
||||
* @return PowerSetVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see PowerSet
|
||||
* @see PowerSetVo
|
||||
*/
|
||||
fun powerSetToPowerSetVo(powerSet: PowerSet) = PowerSetVo(
|
||||
moduleList = powerSet.moduleList?.map(ModuleConverter::moduleToModuleVo),
|
||||
menuList = powerSet.menuList?.map(MenuConverter::menuToMenuVo),
|
||||
funcList = powerSet.funcList?.map(FuncConverter::funcToFuncVo),
|
||||
operationList = powerSet.operationList?.map(OperationConverter::operationToOperationVo)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.oxygen.api.entity.permission.Power
|
||||
import top.fatweb.oxygen.api.entity.permission.Role
|
||||
import top.fatweb.oxygen.api.param.permission.role.RoleAddParam
|
||||
import top.fatweb.oxygen.api.param.permission.role.RoleUpdateParam
|
||||
import top.fatweb.oxygen.api.param.permission.role.RoleUpdateStatusParam
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.RoleWithPowerVo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.RoleVo
|
||||
|
||||
/**
|
||||
* Role converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object RoleConverter {
|
||||
/**
|
||||
* Convert Role object into RoleVo object
|
||||
*
|
||||
* @param role Role object
|
||||
* @return RoleVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Role
|
||||
* @see RoleVo
|
||||
*/
|
||||
fun roleToRoleVo(role: Role) = RoleVo(
|
||||
id = role.id,
|
||||
name = role.name,
|
||||
enable = role.enable == 1,
|
||||
createTime = role.createTime,
|
||||
updateTime = role.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert Role object into RoleWithPowerVo object
|
||||
*
|
||||
* @param role Role object
|
||||
* @return RoleWithPowerVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Role
|
||||
* @see RoleWithPowerVo
|
||||
*/
|
||||
fun roleToRoleWithPowerVo(role: Role) = RoleWithPowerVo(
|
||||
id = role.id,
|
||||
name = role.name,
|
||||
enable = role.enable == 1,
|
||||
createTime = role.createTime,
|
||||
updateTime = role.updateTime,
|
||||
modules = role.modules?.map(ModuleConverter::moduleToModuleVo),
|
||||
menus = role.menus?.map(MenuConverter::menuToMenuVo),
|
||||
funcs = role.funcs?.map(FuncConverter::funcToFuncVo),
|
||||
operations = role.operations?.map(OperationConverter::operationToOperationVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert IPage<Role> object into PageVo object
|
||||
*
|
||||
* @param rolePage IPage<Role> object
|
||||
* @return PageVo<RoleWithPowerVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPage
|
||||
* @see Role
|
||||
* @see PageVo
|
||||
* @see RoleWithPowerVo
|
||||
*/
|
||||
fun rolePageToRoleWithPowerPageVo(rolePage: IPage<Role>) = PageVo(
|
||||
total = rolePage.total,
|
||||
pages = rolePage.pages,
|
||||
size = rolePage.size,
|
||||
current = rolePage.current,
|
||||
records = rolePage.records.map(::roleToRoleWithPowerVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert RoleAddParam object into Role object
|
||||
*
|
||||
* @param roleAddParam RoleAddParam object
|
||||
* @return Role object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleAddParam
|
||||
* @see Role
|
||||
*/
|
||||
fun roleAddParamToRole(roleAddParam: RoleAddParam) = Role().apply {
|
||||
name = roleAddParam.name
|
||||
enable = if (roleAddParam.enable) 1 else 0
|
||||
powers = roleAddParam.powerIds?.map { Power().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert RoleUpdateParam into Role object
|
||||
*
|
||||
* @param roleUpdateParam RoleUpdateParam object
|
||||
* @return Role object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleUpdateParam
|
||||
* @see Role
|
||||
*/
|
||||
fun roleUpdateParamToRole(roleUpdateParam: RoleUpdateParam) = Role().apply {
|
||||
id = roleUpdateParam.id
|
||||
name = roleUpdateParam.name
|
||||
enable = if (roleUpdateParam.enable) 1 else 0
|
||||
powers = roleUpdateParam.powerIds?.map { Power().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert RoleUpdateStatusParam object into Role object
|
||||
*
|
||||
* @param roleUpdateStatusParam RoleUpdateStatusParam object
|
||||
* @return Role object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see RoleUpdateStatusParam
|
||||
* @see Role
|
||||
*/
|
||||
fun roleUpdateStatusParamToRole(roleUpdateStatusParam: RoleUpdateStatusParam) = Role().apply {
|
||||
id = roleUpdateStatusParam.id
|
||||
enable = if (roleUpdateStatusParam.enable) 1 else 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.avatargenerator.GitHubAvatar
|
||||
import top.fatweb.oxygen.api.entity.permission.Group
|
||||
import top.fatweb.oxygen.api.entity.permission.Role
|
||||
import top.fatweb.oxygen.api.entity.permission.User
|
||||
import top.fatweb.oxygen.api.entity.permission.UserInfo
|
||||
import top.fatweb.oxygen.api.param.permission.user.UserAddParam
|
||||
import top.fatweb.oxygen.api.param.permission.user.UserUpdateParam
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithPasswordRoleInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithPowerInfoVo
|
||||
import top.fatweb.oxygen.api.vo.permission.UserWithRoleInfoVo
|
||||
|
||||
/**
|
||||
* User converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object UserConverter {
|
||||
/**
|
||||
* Convert User object into UserWithPowerInfoVo object
|
||||
*
|
||||
* @param user User object
|
||||
* @return UserWithPowerInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
* @see UserWithPowerInfoVo
|
||||
*/
|
||||
fun userToUserWithPowerInfoVo(user: User) = UserWithPowerInfoVo(
|
||||
id = user.id,
|
||||
username = user.username,
|
||||
verified = user.verify.isNullOrBlank(),
|
||||
locking = user.locking?.let { it == 1 },
|
||||
expiration = user.expiration,
|
||||
credentialsExpiration = user.credentialsExpiration,
|
||||
enable = user.enable?.let { it == 1 },
|
||||
currentLoginTime = user.currentLoginTime,
|
||||
currentLoginIp = user.currentLoginIp,
|
||||
lastLoginTime = user.lastLoginTime,
|
||||
lastLoginIp = user.lastLoginIp,
|
||||
createTime = user.createTime,
|
||||
updateTime = user.updateTime,
|
||||
userInfo = user.userInfo?.let(UserInfoConverter::userInfoToUserInfoVo),
|
||||
modules = user.modules?.map(ModuleConverter::moduleToModuleVo),
|
||||
menus = user.menus?.map(MenuConverter::menuToMenuVo),
|
||||
funcs = user.funcs?.map(FuncConverter::funcToFuncVo),
|
||||
operations = user.operations?.map(OperationConverter::operationToOperationVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert User object into UserWithRoleInfoVo object
|
||||
*
|
||||
* @param user User object
|
||||
* @return UserWithRoleInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
fun userToUserWithRoleInfoVo(user: User) = UserWithRoleInfoVo(
|
||||
id = user.id,
|
||||
username = user.username,
|
||||
verify = user.verify,
|
||||
locking = user.locking?.let { it == 1 },
|
||||
expiration = user.expiration,
|
||||
credentialsExpiration = user.credentialsExpiration,
|
||||
enable = user.enable?.let { it == 1 },
|
||||
currentLoginTime = user.currentLoginTime,
|
||||
currentLoginIp = user.currentLoginIp,
|
||||
lastLoginTime = user.lastLoginTime,
|
||||
lastLoginIp = user.lastLoginIp,
|
||||
createTime = user.createTime,
|
||||
updateTime = user.updateTime,
|
||||
userInfo = user.userInfo?.let(UserInfoConverter::userInfoToUserInfoVo),
|
||||
roles = user.roles?.map(RoleConverter::roleToRoleVo),
|
||||
groups = user.groups?.map(GroupConverter::groupToGroupVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert User object into UserWithInfoVo object
|
||||
*
|
||||
* @param user User object
|
||||
* @return UserWithInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
* @see UserWithInfoVo
|
||||
*/
|
||||
fun userToUserWithInfoVo(user: User) = UserWithInfoVo(
|
||||
id = user.id,
|
||||
username = user.username,
|
||||
verified = user.verify.isNullOrBlank(),
|
||||
locking = user.locking?.let { it == 1 },
|
||||
expiration = user.expiration,
|
||||
credentialsExpiration = user.credentialsExpiration,
|
||||
enable = user.enable?.let { it == 1 },
|
||||
currentLoginTime = user.currentLoginTime,
|
||||
currentLoginIp = user.currentLoginIp,
|
||||
lastLoginTime = user.lastLoginTime,
|
||||
lastLoginIp = user.lastLoginIp,
|
||||
createTime = user.createTime,
|
||||
updateTime = user.updateTime,
|
||||
userInfo = user.userInfo?.let(UserInfoConverter::userInfoToUserInfoVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert User object into UserWithPasswordRoleInfoVo object
|
||||
*
|
||||
* @param user User object
|
||||
* @return UserWithPasswordRoleInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
* @see UserWithPasswordRoleInfoVo
|
||||
*/
|
||||
fun userToUserWithPasswordRoleInfoVo(user: User) = UserWithPasswordRoleInfoVo(
|
||||
id = user.id,
|
||||
username = user.username,
|
||||
password = user.password,
|
||||
verify = user.verify,
|
||||
locking = user.locking?.let { it == 1 },
|
||||
expiration = user.expiration,
|
||||
credentialsExpiration = user.credentialsExpiration,
|
||||
enable = user.enable?.let { it == 1 },
|
||||
currentLoginTime = user.currentLoginTime,
|
||||
currentLoginIp = user.currentLoginIp,
|
||||
lastLoginTime = user.lastLoginTime,
|
||||
lastLoginIp = user.lastLoginIp,
|
||||
createTime = user.createTime,
|
||||
updateTime = user.updateTime,
|
||||
userInfo = user.userInfo?.let(UserInfoConverter::userInfoToUserInfoVo),
|
||||
roles = user.roles?.map(RoleConverter::roleToRoleVo),
|
||||
groups = user.groups?.map(GroupConverter::groupToGroupVo)
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert UserAddParam object into User object
|
||||
*
|
||||
* @param userAddParam UserAddParam object
|
||||
* @return User object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserAddParam
|
||||
* @see User
|
||||
*/
|
||||
fun userAddParamToUser(userAddParam: UserAddParam) = User().apply {
|
||||
username = userAddParam.username
|
||||
password = userAddParam.password
|
||||
locking = if (userAddParam.locking) 1 else 0
|
||||
expiration = userAddParam.expiration
|
||||
credentialsExpiration = userAddParam.credentialsExpiration
|
||||
enable = if (userAddParam.enable) 1 else 0
|
||||
userInfo = UserInfo().apply {
|
||||
nickname = userAddParam.nickname ?: userAddParam.username
|
||||
avatar = userAddParam.avatar ?: GitHubAvatar.newAvatarBuilder().build()
|
||||
.createAsBase64((Long.MIN_VALUE..Long.MAX_VALUE).random())
|
||||
email = userAddParam.email
|
||||
}
|
||||
roles = userAddParam.roleIds?.map { Role().apply { id = it } }
|
||||
groups = userAddParam.groupIds?.map { Group().apply { id = it } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert UserUpdateParam object into User object
|
||||
*
|
||||
* @param userUpdateParam UserUpdateParam object
|
||||
* @return User object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserUpdateParam
|
||||
* @see User
|
||||
*/
|
||||
fun userUpdateParamToUser(userUpdateParam: UserUpdateParam) = User().apply {
|
||||
id = userUpdateParam.id
|
||||
username = userUpdateParam.username
|
||||
locking = if (userUpdateParam.locking && userUpdateParam.id != 0L) 1 else 0
|
||||
expiration = if (userUpdateParam.id != 0L) userUpdateParam.expiration else null
|
||||
credentialsExpiration = userUpdateParam.credentialsExpiration
|
||||
enable = if (userUpdateParam.enable || userUpdateParam.id == 0L) 1 else 0
|
||||
userInfo = UserInfo().apply {
|
||||
nickname = userUpdateParam.nickname
|
||||
avatar = userUpdateParam.avatar
|
||||
email = userUpdateParam.email
|
||||
}
|
||||
roles = if (userUpdateParam.id != 0L) userUpdateParam.roleIds?.map { Role().apply { id = it } } else null
|
||||
groups = if (userUpdateParam.id != 0L) userUpdateParam.groupIds?.map { Group().apply { id = it } } else null
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert IPage<User> object into PageVo<UserWithRoleInfoVo> object
|
||||
*
|
||||
* @param userPage IPage<User> object
|
||||
* @return PageVo<UserWithRoleInfoVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPage
|
||||
* @see User
|
||||
* @see PageVo
|
||||
* @see UserWithRoleInfoVo
|
||||
*/
|
||||
fun userPageToUserWithRoleInfoPageVo(userPage: IPage<User>) = PageVo(
|
||||
total = userPage.total,
|
||||
pages = userPage.pages,
|
||||
size = userPage.size,
|
||||
current = userPage.current,
|
||||
records = userPage.records.map(::userToUserWithRoleInfoVo)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package top.fatweb.oxygen.api.converter.permission
|
||||
|
||||
import top.fatweb.oxygen.api.entity.permission.UserInfo
|
||||
import top.fatweb.oxygen.api.vo.permission.base.UserInfoVo
|
||||
|
||||
/**
|
||||
* User information converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object UserInfoConverter {
|
||||
/**
|
||||
* Convert UserInfo object into UserInfoVo object
|
||||
*
|
||||
* @param userInfo UserInfo object
|
||||
* @return UserInfoVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserInfo
|
||||
* @see UserInfoVo
|
||||
*/
|
||||
fun userInfoToUserInfoVo(userInfo: UserInfo) = UserInfoVo(
|
||||
id = userInfo.id,
|
||||
userId = userInfo.userId,
|
||||
nickname = userInfo.nickname,
|
||||
avatar = userInfo.avatar,
|
||||
email = userInfo.email,
|
||||
createTime = userInfo.createTime,
|
||||
updateTime = userInfo.updateTime
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package top.fatweb.oxygen.api.converter.system
|
||||
|
||||
import top.fatweb.oxygen.api.entity.system.SensitiveWord
|
||||
import top.fatweb.oxygen.api.param.system.SensitiveWordAddParam
|
||||
import top.fatweb.oxygen.api.vo.system.SensitiveWordVo
|
||||
|
||||
/**
|
||||
* Settings converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object SettingsConverter {
|
||||
/**
|
||||
* Convert SensitiveWord object into SensitiveWordVo object
|
||||
*
|
||||
* @param sensitiveWord SensitiveWord object
|
||||
* @return SensitiveWordVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SensitiveWord
|
||||
* @see SensitiveWordVo
|
||||
*/
|
||||
fun sensitiveWordToSensitiveWordVo(sensitiveWord: SensitiveWord) = SensitiveWordVo(
|
||||
id = sensitiveWord.id,
|
||||
word = sensitiveWord.word,
|
||||
useFor = sensitiveWord.useFor?.map(SensitiveWord.Use::valueOf)?.toSet(),
|
||||
enable = sensitiveWord.enable == 1
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert SensitiveWordAddParam object into SensitiveWord object
|
||||
*
|
||||
* @param sensitiveWordAddParam SensitiveWordAddParam object
|
||||
* @return SensitiveWord object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see SensitiveWordAddParam
|
||||
* @see SensitiveWord
|
||||
*/
|
||||
fun sensitiveWordAddParamToSensitiveWord(sensitiveWordAddParam: SensitiveWordAddParam) = SensitiveWord().apply {
|
||||
word = sensitiveWordAddParam.word
|
||||
useFor = sensitiveWordAddParam.useFor.map(SensitiveWord.Use::code).toSet()
|
||||
enable = if (sensitiveWordAddParam.enable) 1 else 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package top.fatweb.oxygen.api.converter.system
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||
import top.fatweb.oxygen.api.entity.system.SysLog
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.system.SysLogVo
|
||||
|
||||
/**
|
||||
* System log converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object SysLogConverter {
|
||||
/**
|
||||
* Convert IPage<SysLog> object into PageVo<SysLogVo> object
|
||||
*
|
||||
* @param syslogPage IPage<Syslog> object
|
||||
* @return PageVo<SysLogVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see IPage
|
||||
* @see SysLog
|
||||
* @see PageVo
|
||||
* @see SysLogVo
|
||||
*/
|
||||
fun sysLogPageToSysLogPageVo(syslogPage: IPage<SysLog>) = PageVo(
|
||||
syslogPage.total,
|
||||
syslogPage.pages,
|
||||
syslogPage.size,
|
||||
syslogPage.current,
|
||||
syslogPage.records.map {
|
||||
SysLogVo(
|
||||
id = it.id,
|
||||
logType = it.logType,
|
||||
operateUserId = it.operateUserId,
|
||||
operateTime = it.operateTime,
|
||||
requestUri = it.requestUri,
|
||||
requestMethod = it.requestMethod,
|
||||
requestParams = it.requestParams,
|
||||
requestIp = it.requestIp,
|
||||
requestServerAddress = it.requestServerAddress,
|
||||
exception = it.exception == 1,
|
||||
exceptionInfo = it.exceptionInfo,
|
||||
startTime = it.startTime,
|
||||
endTime = it.endTime,
|
||||
executeTime = it.executeTime,
|
||||
userAgent = it.userAgent,
|
||||
operateUsername = it.operateUsername
|
||||
)
|
||||
})
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import top.fatweb.oxygen.api.entity.tool.ToolBase
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolBaseVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolDataVo
|
||||
|
||||
/**
|
||||
* Tool base converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolBaseConverter {
|
||||
/**
|
||||
* Convert ToolBase object into ToolBaseVo object
|
||||
*
|
||||
* @param toolBase ToolBase object
|
||||
* @return ToolBaseVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolBase
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
fun toolBaseToToolBaseVo(toolBase: ToolBase) = ToolBaseVo(
|
||||
id = toolBase.id,
|
||||
name = toolBase.name,
|
||||
source = toolBase.source?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
dist = toolBase.dist?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
compiled = toolBase.compiled == 1,
|
||||
createTime = toolBase.createTime,
|
||||
updateTime = toolBase.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert ToolBase object into ToolBaseVo object by get list
|
||||
*
|
||||
* @param toolBase ToolBase object
|
||||
* @return ToolBaseVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolBase
|
||||
* @see ToolBaseVo
|
||||
*/
|
||||
fun toolBaseToToolBaseVoByGetList(toolBase: ToolBase) = ToolBaseVo(
|
||||
id = toolBase.id,
|
||||
name = toolBase.name,
|
||||
source = ToolDataVo(id = toolBase.sourceId, data = null, createTime = null, updateTime = null),
|
||||
dist = ToolDataVo(id = toolBase.distId, data = null, createTime = null, updateTime = null),
|
||||
compiled = toolBase.compiled == 1,
|
||||
createTime = toolBase.createTime,
|
||||
updateTime = toolBase.updateTime
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import top.fatweb.oxygen.api.entity.tool.ToolCategory
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCategoryAddParam
|
||||
import top.fatweb.oxygen.api.param.tool.ToolCategoryUpdateParam
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolCategoryVo
|
||||
|
||||
/**
|
||||
* Tool category converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolCategoryConverter {
|
||||
/**
|
||||
* Convert ToolCategory object into ToolCategoryVo object
|
||||
*
|
||||
* @param toolCategory ToolCategory object
|
||||
* @return ToolCategoryVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategory
|
||||
* @see ToolCategoryVo
|
||||
*/
|
||||
fun toolCategoryToToolCategoryVo(toolCategory: ToolCategory) = ToolCategoryVo(
|
||||
id = toolCategory.id,
|
||||
name = toolCategory.name,
|
||||
enable = toolCategory.enable == 1,
|
||||
createTime = toolCategory.createTime,
|
||||
updateTime = toolCategory.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert ToolCategoryAddParam object into ToolCategory object
|
||||
*
|
||||
* @param toolCategoryAddParam ToolCategoryAddParam object
|
||||
* @return ToolCateGory object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategoryAddParam
|
||||
* @see ToolCategory
|
||||
*/
|
||||
fun toolCategoryAddParamToToolCategory(toolCategoryAddParam: ToolCategoryAddParam) = ToolCategory().apply {
|
||||
name = toolCategoryAddParam.name
|
||||
enable = if (toolCategoryAddParam.enable) 1 else 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert ToolCategoryUpdateParam object into ToolCategory object
|
||||
*
|
||||
* @param toolCategoryUpdateParam ToolCategoryUpdateParam object
|
||||
* @return ToolCategory object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolCategoryUpdateParam
|
||||
* @see ToolCategory
|
||||
*/
|
||||
fun toolCategoryUpdateParamToToolCategory(toolCategoryUpdateParam: ToolCategoryUpdateParam) = ToolCategory().apply {
|
||||
id = toolCategoryUpdateParam.id
|
||||
name = toolCategoryUpdateParam.name
|
||||
enable = toolCategoryUpdateParam.enable?. let { if (it) 1 else 0 }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
|
||||
import top.fatweb.oxygen.api.converter.permission.UserConverter
|
||||
import top.fatweb.oxygen.api.entity.tool.Tool
|
||||
import top.fatweb.oxygen.api.vo.PageVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolVo
|
||||
|
||||
/**
|
||||
* Tool converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolConverter {
|
||||
/**
|
||||
* Convert Tool object into ToolVo object
|
||||
*
|
||||
* @param tool Tool object
|
||||
* @return ToolVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Tool
|
||||
* @see ToolVo
|
||||
*/
|
||||
fun toolToToolVo(tool: Tool) = ToolVo(
|
||||
id = tool.id,
|
||||
name = tool.name,
|
||||
toolId = tool.toolId,
|
||||
icon = tool.icon,
|
||||
description = tool.description,
|
||||
base = tool.base?.let(ToolBaseConverter::toolBaseToToolBaseVo),
|
||||
author = tool.author?.let(UserConverter::userToUserWithInfoVo),
|
||||
ver = tool.ver,
|
||||
keywords = tool.keywords,
|
||||
categories = tool.categories?.map(ToolCategoryConverter::toolCategoryToToolCategoryVo),
|
||||
source = tool.source?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
dist = tool.dist?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
entryPoint = tool.entryPoint,
|
||||
publish = tool.publish,
|
||||
review = tool.review,
|
||||
createTime = tool.createTime,
|
||||
updateTime = tool.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert Page<Tool> object into PageVo<ToolVo> object
|
||||
*
|
||||
* @param toolPage Page<Tool> object
|
||||
* @return PageVo<ToolVo> object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Page
|
||||
* @see Tool
|
||||
* @see PageVo
|
||||
* @see ToolVo
|
||||
*/
|
||||
fun toolPageToToolPageVo(toolPage: Page<Tool>): PageVo<ToolVo> = PageVo(
|
||||
total = toolPage.total,
|
||||
pages = toolPage.pages,
|
||||
size = toolPage.size,
|
||||
current = toolPage.current,
|
||||
records = toolPage.records.map(::toolToToolVo)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import top.fatweb.oxygen.api.entity.tool.ToolData
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolDataVo
|
||||
|
||||
/**
|
||||
* Tool data converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolDataConverter {
|
||||
/**
|
||||
* Convert ToolData object into ToolDataVo object
|
||||
*
|
||||
* @param toolData ToolData object
|
||||
* @return ToolDataVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolData
|
||||
* @see ToolDataVo
|
||||
*/
|
||||
fun toolDataToToolDataVo(toolData: ToolData) = ToolDataVo(
|
||||
id = toolData.id,
|
||||
data = toolData.data,
|
||||
createTime = toolData.createTime,
|
||||
updateTime = toolData.updateTime
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package top.fatweb.oxygen.api.converter.tool
|
||||
|
||||
import top.fatweb.oxygen.api.entity.tool.ToolTemplate
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolBaseVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolDataVo
|
||||
import top.fatweb.oxygen.api.vo.tool.ToolTemplateVo
|
||||
|
||||
/**
|
||||
* Tool template converter
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
object ToolTemplateConverter {
|
||||
/**
|
||||
* Convert ToolTemplate object into ToolTemplateVo object
|
||||
*
|
||||
* @param toolTemplate ToolTemplate object
|
||||
* @return ToolTemplateVo object
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ToolTemplate
|
||||
* @see ToolTemplateVo
|
||||
*/
|
||||
fun toolTemplateToToolTemplateVo(toolTemplate: ToolTemplate) = ToolTemplateVo(
|
||||
id = toolTemplate.id,
|
||||
name = toolTemplate.name,
|
||||
base = toolTemplate.base?.let(ToolBaseConverter::toolBaseToToolBaseVo),
|
||||
source = toolTemplate.source?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
entryPoint = toolTemplate.entryPoint,
|
||||
enable = toolTemplate.enable == 1,
|
||||
createTime = toolTemplate.createTime,
|
||||
updateTime = toolTemplate.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert ToolTemplate object into ToolTemplateVo object by list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
fun toolTemplateToToolTemplateVoByList(toolTemplate: ToolTemplate) = ToolTemplateVo(
|
||||
id = toolTemplate.id,
|
||||
name = toolTemplate.name,
|
||||
base = ToolBaseVo(
|
||||
id = toolTemplate.baseId,
|
||||
name = null,
|
||||
source = null,
|
||||
dist = null,
|
||||
compiled = null,
|
||||
createTime = null,
|
||||
updateTime = null
|
||||
),
|
||||
source = ToolDataVo(id = toolTemplate.sourceId, data = null, createTime = null, updateTime = null),
|
||||
entryPoint = toolTemplate.entryPoint,
|
||||
enable = toolTemplate.enable == 1,
|
||||
createTime = toolTemplate.createTime,
|
||||
updateTime = toolTemplate.updateTime
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert ToolTemplate object into ToolTemplateVo object with base dist
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
fun toolTemplateToToolTemplateVoWithBaseDist(toolTemplate: ToolTemplate) = ToolTemplateVo(
|
||||
id = toolTemplate.id,
|
||||
name = toolTemplate.name,
|
||||
base = ToolBaseVo(
|
||||
id = toolTemplate.baseId,
|
||||
name = toolTemplate.base?.name,
|
||||
source = null,
|
||||
dist = ToolDataVo(id = null, data = toolTemplate.base?.distData, createTime = null, updateTime = null),
|
||||
compiled = null,
|
||||
createTime = null,
|
||||
updateTime = null
|
||||
),
|
||||
source = toolTemplate.source?.let(ToolDataConverter::toolDataToToolDataVo),
|
||||
entryPoint = toolTemplate.entryPoint,
|
||||
enable = toolTemplate.enable == 1,
|
||||
createTime = toolTemplate.createTime,
|
||||
updateTime = toolTemplate.updateTime
|
||||
)
|
||||
}
|
||||
35
src/main/kotlin/top/fatweb/oxygen/api/cron/StatisticsCron.kt
Normal file
35
src/main/kotlin/top/fatweb/oxygen/api/cron/StatisticsCron.kt
Normal file
@@ -0,0 +1,35 @@
|
||||
package top.fatweb.oxygen.api.cron
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled
|
||||
import org.springframework.stereotype.Component
|
||||
import top.fatweb.oxygen.api.entity.system.StatisticsLog
|
||||
import top.fatweb.oxygen.api.properties.SecurityProperties
|
||||
import top.fatweb.oxygen.api.service.system.IStatisticsLogService
|
||||
import top.fatweb.oxygen.api.util.RedisUtil
|
||||
|
||||
/**
|
||||
* Statistics scheduled tasks
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Component
|
||||
class StatisticsCron(
|
||||
private val redisUtil: RedisUtil,
|
||||
private val statisticsLogService: IStatisticsLogService
|
||||
) {
|
||||
/**
|
||||
* Auto record number of online users
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Scheduled(cron = "0 * * * * *")
|
||||
fun onlineUserCount() {
|
||||
statisticsLogService.save(StatisticsLog().apply {
|
||||
key = StatisticsLog.KeyItem.ONLINE_USERS_COUNT
|
||||
value = redisUtil.keys("${SecurityProperties.jwtIssuer}_login_*")
|
||||
.distinctBy { Regex("${SecurityProperties.jwtIssuer}_login_(.*):.*").matchEntire(it)?.groupValues?.getOrNull(1) }.size.toString()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package top.fatweb.oxygen.api.entity.common
|
||||
|
||||
/**
|
||||
* Business code entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
enum class BusinessCode(val code: Int) {
|
||||
/**
|
||||
* System
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
SYSTEM(100),
|
||||
|
||||
/**
|
||||
* Permission
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
PERMISSION(200),
|
||||
|
||||
/**
|
||||
* Database
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
DATABASE(300),
|
||||
|
||||
/**
|
||||
* Tool
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
TOOL(400),
|
||||
|
||||
/**
|
||||
* Avatar API
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
API_AVATAR(501)
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package top.fatweb.oxygen.api.entity.common
|
||||
|
||||
/**
|
||||
* Response code entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
enum class ResponseCode(val code: Int) {
|
||||
SYSTEM_OK(BusinessCode.SYSTEM, 0),
|
||||
|
||||
SYSTEM_ERROR(BusinessCode.SYSTEM, 50),
|
||||
SYSTEM_TIMEOUT(BusinessCode.SYSTEM, 51),
|
||||
SYSTEM_REQUEST_ILLEGAL(BusinessCode.SYSTEM, 52),
|
||||
SYSTEM_ARGUMENT_NOT_VALID(BusinessCode.SYSTEM, 53),
|
||||
SYSTEM_INVALID_CAPTCHA_CODE(BusinessCode.SYSTEM, 54),
|
||||
SYSTEM_REQUEST_TOO_FREQUENT(BusinessCode.SYSTEM, 55),
|
||||
SYSTEM_MATCH_SENSITIVE_WORD(BusinessCode.SYSTEM, 56),
|
||||
|
||||
PERMISSION_LOGIN_SUCCESS(BusinessCode.PERMISSION, 0),
|
||||
PERMISSION_PASSWORD_CHANGE_SUCCESS(BusinessCode.PERMISSION, 1),
|
||||
PERMISSION_LOGOUT_SUCCESS(BusinessCode.PERMISSION, 2),
|
||||
PERMISSION_TOKEN_RENEW_SUCCESS(BusinessCode.PERMISSION, 3),
|
||||
PERMISSION_REGISTER_SUCCESS(BusinessCode.PERMISSION, 4),
|
||||
PERMISSION_RESEND_SUCCESS(BusinessCode.PERMISSION, 5),
|
||||
PERMISSION_VERIFY_SUCCESS(BusinessCode.PERMISSION, 6),
|
||||
PERMISSION_FORGET_SUCCESS(BusinessCode.PERMISSION, 7),
|
||||
PERMISSION_RETRIEVE_SUCCESS(BusinessCode.PERMISSION, 8),
|
||||
|
||||
PERMISSION_UNAUTHORIZED(BusinessCode.PERMISSION, 50),
|
||||
PERMISSION_USERNAME_NOT_FOUND(BusinessCode.PERMISSION, 51),
|
||||
PERMISSION_ACCESS_DENIED(BusinessCode.PERMISSION, 52),
|
||||
PERMISSION_USER_LOCKED(BusinessCode.PERMISSION, 53),
|
||||
PERMISSION_USER_EXPIRED(BusinessCode.PERMISSION, 54),
|
||||
PERMISSION_USER_CREDENTIALS_EXPIRED(BusinessCode.PERMISSION, 55),
|
||||
PERMISSION_USER_DISABLE(BusinessCode.PERMISSION, 56),
|
||||
PERMISSION_LOGIN_USERNAME_PASSWORD_ERROR(BusinessCode.PERMISSION, 57),
|
||||
PERMISSION_OLD_PASSWORD_NOT_MATCH(BusinessCode.PERMISSION, 58),
|
||||
PERMISSION_LOGOUT_FAILED(BusinessCode.PERMISSION, 59),
|
||||
PERMISSION_TOKEN_ILLEGAL(BusinessCode.PERMISSION, 60),
|
||||
PERMISSION_TOKEN_HAS_EXPIRED(BusinessCode.PERMISSION, 61),
|
||||
PERMISSION_NO_VERIFICATION_REQUIRED(BusinessCode.PERMISSION, 62),
|
||||
PERMISSION_VERIFY_CODE_ERROR_OR_EXPIRED(BusinessCode.PERMISSION, 63),
|
||||
PERMISSION_ACCOUNT_NEED_INIT(BusinessCode.PERMISSION, 64),
|
||||
PERMISSION_USER_NOT_FOUND(BusinessCode.PERMISSION, 65),
|
||||
PERMISSION_RETRIEVE_CODE_ERROR_OR_EXPIRED(BusinessCode.PERMISSION, 66),
|
||||
PERMISSION_ACCOUNT_NEED_RESET_PASSWORD(BusinessCode.PERMISSION, 67),
|
||||
|
||||
DATABASE_SELECT_SUCCESS(BusinessCode.DATABASE, 0),
|
||||
DATABASE_SELECT_FAILED(BusinessCode.DATABASE, 5),
|
||||
DATABASE_INSERT_SUCCESS(BusinessCode.DATABASE, 10),
|
||||
DATABASE_INSERT_FAILED(BusinessCode.DATABASE, 15),
|
||||
DATABASE_UPDATE_SUCCESS(BusinessCode.DATABASE, 20),
|
||||
DATABASE_UPDATE_FAILED(BusinessCode.DATABASE, 25),
|
||||
DATABASE_DELETE_SUCCESS(BusinessCode.DATABASE, 30),
|
||||
DATABASE_DELETE_FAILED(BusinessCode.DATABASE, 35),
|
||||
DATABASE_EXECUTE_ERROR(BusinessCode.DATABASE, 50),
|
||||
DATABASE_DUPLICATE_KEY(BusinessCode.DATABASE, 51),
|
||||
DATABASE_NO_RECORD_FOUND(BusinessCode.DATABASE, 52),
|
||||
|
||||
TOOL_SUBMIT_SUCCESS(BusinessCode.TOOL, 10),
|
||||
TOOL_CANCEL_SUCCESS(BusinessCode.TOOL, 11),
|
||||
TOOL_ILLEGAL_VERSION(BusinessCode.TOOL, 50),
|
||||
TOOL_UNDER_REVIEW(BusinessCode.TOOL, 51),
|
||||
TOOL_NOT_UNDER_REVIEW(BusinessCode.TOOL, 52),
|
||||
TOOL_HAS_UNPUBLISHED_VERSION(BusinessCode.TOOL, 53),
|
||||
TOOL_HAS_NOT_BEEN_PUBLISHED(BusinessCode.TOOL, 54),
|
||||
TOOL_HAS_BEEN_PUBLISHED(BusinessCode.TOOL, 55),
|
||||
TOOL_SUBMIT_ERROR(BusinessCode.TOOL, 60),
|
||||
TOOL_CANCEL_ERROR(BusinessCode.TOOL, 61),
|
||||
|
||||
API_AVATAR_SUCCESS(BusinessCode.API_AVATAR, 0),
|
||||
API_AVATAR_ERROR(BusinessCode.API_AVATAR, 50);
|
||||
|
||||
constructor(businessCode: BusinessCode, code: Int) : this(businessCode.code * 100 + code)
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package top.fatweb.oxygen.api.entity.common
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Response result entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class ResponseResult<T> private constructor(
|
||||
@Schema(description = "响应码", defaultValue = "200") val code: Int,
|
||||
|
||||
@Schema(description = "是否调用成功") val success: Boolean,
|
||||
|
||||
@Schema(description = "信息") val msg: String,
|
||||
|
||||
@Schema(description = "数据") val data: T?
|
||||
) : Serializable {
|
||||
companion object {
|
||||
/**
|
||||
* Build response result object
|
||||
*
|
||||
* @param code Response code
|
||||
* @param success Is successful
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
fun <T> build(code: Int, success: Boolean, msg: String, data: T?) =
|
||||
ResponseResult(code, success, msg, data)
|
||||
|
||||
/**
|
||||
* Build response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param success Is successful
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> build(code: ResponseCode, success: Boolean, msg: String, data: T?) =
|
||||
build(code.code, success, msg, data)
|
||||
|
||||
/**
|
||||
* Build successful response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> success(code: ResponseCode = ResponseCode.SYSTEM_OK, msg: String = "success", data: T? = null) =
|
||||
build(code, true, msg, data)
|
||||
|
||||
/**
|
||||
* Build failure response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> fail(code: ResponseCode = ResponseCode.SYSTEM_ERROR, msg: String = "fail", data: T? = null) =
|
||||
build(code, false, msg, data)
|
||||
|
||||
/**
|
||||
* Build database successful response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> databaseSuccess(
|
||||
code: ResponseCode = ResponseCode.DATABASE_SELECT_SUCCESS, msg: String = "success", data: T? = null
|
||||
) = build(code, true, msg, data)
|
||||
|
||||
/**
|
||||
* Build database failure response result object
|
||||
*
|
||||
* @param code Response code object
|
||||
* @param msg Response message
|
||||
* @param data Response data
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see ResponseCode
|
||||
*/
|
||||
fun <T> databaseFail(
|
||||
code: ResponseCode = ResponseCode.DATABASE_SELECT_FAILED, msg: String = "fail", data: T? = null
|
||||
) = build(code, false, msg, data)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Function entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_func")
|
||||
class Func : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Parent ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("parent_id")
|
||||
var parentId: Long? = null
|
||||
|
||||
/**
|
||||
* Menu ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("menu_id")
|
||||
var menuId: Long? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Func(id=$id, name=$name, parentId=$parentId, menuId=$menuId)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Group entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_group")
|
||||
class Group : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Enable
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("enable")
|
||||
var enable: Int? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
/**
|
||||
* Role list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Role
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var roles: List<Role>? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Group(id=$id, name=$name, enable=$enable, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, roles=$roles)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo
|
||||
import org.springframework.security.core.GrantedAuthority
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority
|
||||
import org.springframework.security.core.userdetails.UserDetails
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneOffset
|
||||
|
||||
/**
|
||||
* Login user entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see UserDetails
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
|
||||
class LoginUser() : UserDetails {
|
||||
/**
|
||||
* User object
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see User
|
||||
*/
|
||||
lateinit var user: User
|
||||
|
||||
@JsonIgnore
|
||||
private var authorities: List<GrantedAuthority>? = null
|
||||
|
||||
constructor(user: User) : this() {
|
||||
this.user = user
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
override fun getAuthorities(): List<GrantedAuthority> {
|
||||
authorities?.let { return it }
|
||||
authorities = user.operations?.map { SimpleGrantedAuthority(it.code) } ?: emptyList()
|
||||
|
||||
return authorities as List<GrantedAuthority>
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
override fun getPassword() = user.password
|
||||
|
||||
@JsonIgnore
|
||||
override fun getUsername() = user.username
|
||||
|
||||
@JsonIgnore
|
||||
override fun isAccountNonExpired() =
|
||||
user.expiration == null || user.expiration!!.isAfter(LocalDateTime.now(ZoneOffset.UTC))
|
||||
|
||||
@JsonIgnore
|
||||
override fun isAccountNonLocked() = user.locking == 0
|
||||
|
||||
@JsonIgnore
|
||||
override fun isCredentialsNonExpired() =
|
||||
user.credentialsExpiration == null || user.credentialsExpiration!!.isAfter(LocalDateTime.now(ZoneOffset.UTC))
|
||||
|
||||
@JsonIgnore
|
||||
override fun isEnabled() = user.enable == 1
|
||||
|
||||
override fun toString(): String {
|
||||
return "LoginUser(user=$user, authorities=$authorities)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Menu entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_menu")
|
||||
class Menu : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* URL
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("url")
|
||||
var url: String? = null
|
||||
|
||||
/**
|
||||
* Parent ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("parent_id")
|
||||
var parentId: Long? = null
|
||||
|
||||
/**
|
||||
* Module ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("module_id")
|
||||
var moduleId: Long? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Menu(id=$id, name=$name, url=$url, parentId=$parentId, moduleId=$moduleId)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Module Entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_module")
|
||||
class Module : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Module(id=$id, name=$name)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Operation entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_operation")
|
||||
class Operation : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Code
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("code")
|
||||
var code: String? = null
|
||||
|
||||
/**
|
||||
* Function ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("func_id")
|
||||
var funcId: Long? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Operation(id=$id, name=$name, code=$code, funcId=$funcId)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Power entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_power")
|
||||
class Power : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Type ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("type_id")
|
||||
var typeId: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Power(id=$id, typeId=$typeId)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Set of power entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class PowerSet : Serializable {
|
||||
/**
|
||||
* Module list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Module
|
||||
*/
|
||||
var moduleList: List<Module>? = null
|
||||
|
||||
/**
|
||||
* Menu list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Menu
|
||||
*/
|
||||
var menuList: List<Menu>? = null
|
||||
|
||||
/**
|
||||
* Function list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Func
|
||||
*/
|
||||
var funcList: List<Func>? = null
|
||||
|
||||
/**
|
||||
* Operation list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Operation
|
||||
*/
|
||||
var operationList: List<Operation>? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "PowerSet(moduleList=$moduleList, menuList=$menuList, funcList=$funcList, operationList=$operationList)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField
|
||||
import com.baomidou.mybatisplus.annotation.TableId
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Power type entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_power_type")
|
||||
class PowerType : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "PowerType(id=$id, name=$name)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Power role intermediate entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_r_power_role")
|
||||
class RPowerRole : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Power ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("power_id")
|
||||
var powerId: Long? = null
|
||||
|
||||
/**
|
||||
* Role ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("role_id")
|
||||
var roleId: Long? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "RPowerRole(id=$id, powerId=$powerId, roleId=$roleId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Role group intermediate entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_r_role_group")
|
||||
class RRoleGroup : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Role ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("role_id")
|
||||
var roleId: Long? = null
|
||||
|
||||
/**
|
||||
* Group ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("group_id")
|
||||
var groupId: Long? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "RRoleGroup(id=$id, roleId=$roleId, groupId=$groupId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* User group intermediate entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_r_user_group")
|
||||
class RUserGroup : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* User ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("user_id")
|
||||
var userId: Long? = null
|
||||
|
||||
/**
|
||||
* Group ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("group_id")
|
||||
var groupId: Long? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "RUserGroup(id=$id, userId=$userId, groupId=$groupId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* User role intermediate entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_r_user_role")
|
||||
class RUserRole : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* User ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("user_id")
|
||||
var userId: Long? = null
|
||||
|
||||
/**
|
||||
* Role ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("role_id")
|
||||
var roleId: Long? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "RUserRole(id=$id, userId=$userId, roleId=$roleId, deleted=$deleted, version=$version)"
|
||||
}
|
||||
}
|
||||
135
src/main/kotlin/top/fatweb/oxygen/api/entity/permission/Role.kt
Normal file
135
src/main/kotlin/top/fatweb/oxygen/api/entity/permission/Role.kt
Normal file
@@ -0,0 +1,135 @@
|
||||
package top.fatweb.oxygen.api.entity.permission
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*
|
||||
import java.io.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Role entity
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableName("t_s_role")
|
||||
class Role : Serializable {
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableId("id")
|
||||
var id: Long? = null
|
||||
|
||||
/**
|
||||
* Name
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("name")
|
||||
var name: String? = null
|
||||
|
||||
/**
|
||||
* Enable
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("enable")
|
||||
var enable: Int? = null
|
||||
|
||||
/**
|
||||
* Create time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("create_time", fill = FieldFill.INSERT)
|
||||
var createTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Update time
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see LocalDateTime
|
||||
*/
|
||||
@TableField("update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
var updateTime: LocalDateTime? = null
|
||||
|
||||
/**
|
||||
* Deleted
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
var deleted: Long? = null
|
||||
|
||||
/**
|
||||
* Version
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TableField("version")
|
||||
@Version
|
||||
var version: Int? = null
|
||||
|
||||
/**
|
||||
* Module list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Module
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var modules: List<Module>? = null
|
||||
|
||||
/**
|
||||
* Menu list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Menu
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var menus: List<Menu>? = null
|
||||
|
||||
/**
|
||||
* Function list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Func
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var funcs: List<Func>? = null
|
||||
|
||||
/**
|
||||
* Operation list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Operation
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var operations: List<Operation>? = null
|
||||
|
||||
/**
|
||||
* Power list
|
||||
*
|
||||
* @author FatttSnake, fatttsnake@gmail.com
|
||||
* @since 1.0.0
|
||||
* @see Power
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
var powers: List<Power>? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "Role(id=$id, name=$name, enable=$enable, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, modules=$modules, menus=$menus, funcs=$funcs, operations=$operations, powers=$powers)"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user