Commit 162d604644a1c9876799fe3fd332f32ccadc7518

Authored by YunaiV
2 parents 0fedc8fe 4779413b

Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into sms_temp_zzf_0127

Showing 111 changed files with 3584 additions and 2487 deletions
... ... @@ -22,15 +22,15 @@
22 22 <maven.compiler.target>${java.version}</maven.compiler.target>
23 23 <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
24 24 <!-- 统一依赖管理 -->
25   - <spring.boot.version>2.4.2</spring.boot.version>
  25 + <spring.boot.version>2.4.4</spring.boot.version>
26 26 <!-- Web 相关 -->
27 27 <knife4j.version>3.0.2</knife4j.version>
28 28 <swagger-annotations.version>1.5.22</swagger-annotations.version>
29 29 <!-- DB 相关 -->
30 30 <mysql-connector-java.version>5.1.46</mysql-connector-java.version>
31 31 <druid.version>1.2.4</druid.version>
32   - <mybatis-plus.version>3.4.1</mybatis-plus.version>
33   - <redisson.version>3.14.1</redisson.version>
  32 + <mybatis-plus.version>3.4.2</mybatis-plus.version>
  33 + <redisson.version>3.15.1</redisson.version>
34 34 <!-- Config 配置中心相关 -->
35 35 <apollo.version>1.7.0</apollo.version>
36 36 <!-- 服务保障相关 -->
... ... @@ -42,7 +42,7 @@
42 42 <!-- 工具类相关 -->
43 43 <lombok.version>1.16.14</lombok.version>
44 44 <mapstruct.version>1.4.1.Final</mapstruct.version>
45   - <hutool.version>5.5.6</hutool.version>
  45 + <hutool.version>5.6.1</hutool.version>
46 46 <easyexcel.verion>2.2.7</easyexcel.verion>
47 47 <velocity.version>2.2</velocity.version>
48 48 <screw.version>1.0.5</screw.version>
... ... @@ -249,27 +249,7 @@
249 249  
250 250 <dependency>
251 251 <groupId>cn.hutool</groupId>
252   - <artifactId>hutool-core</artifactId>
253   - <version>${hutool.version}</version>
254   - </dependency>
255   - <dependency>
256   - <groupId>cn.hutool</groupId>
257   - <artifactId>hutool-extra</artifactId>
258   - <version>${hutool.version}</version>
259   - </dependency>
260   - <dependency>
261   - <groupId>cn.hutool</groupId>
262   - <artifactId>hutool-captcha</artifactId>
263   - <version>${hutool.version}</version>
264   - </dependency>
265   - <dependency>
266   - <groupId>cn.hutool</groupId>
267   - <artifactId>hutool-http</artifactId>
268   - <version>${hutool.version}</version>
269   - </dependency>
270   - <dependency>
271   - <groupId>cn.hutool</groupId>
272   - <artifactId>hutool-crypto</artifactId>
  252 + <artifactId>hutool-all</artifactId>
273 253 <version>${hutool.version}</version>
274 254 </dependency>
275 255  
... ...
ruoyi-ui/src/api/system/dept.js
... ... @@ -46,7 +46,7 @@ export function addDept(data) {
46 46 export function updateDept(data) {
47 47 return request({
48 48 url: '/system/dept/update',
49   - method: 'post',
  49 + method: 'put',
50 50 data: data
51 51 })
52 52 }
... ... @@ -55,6 +55,6 @@ export function updateDept(data) {
55 55 export function delDept(id) {
56 56 return request({
57 57 url: '/system/dept/delete?id=' + id,
58   - method: 'post'
  58 + method: 'delete'
59 59 })
60 60 }
... ...
ruoyi-ui/src/api/system/dict/data.js
... ... @@ -38,7 +38,7 @@ export function addData(data) {
38 38 export function updateData(data) {
39 39 return request({
40 40 url: '/system/dict-data/update',
41   - method: 'post',
  41 + method: 'put',
42 42 data: data
43 43 })
44 44 }
... ... @@ -47,7 +47,7 @@ export function updateData(data) {
47 47 export function delData(dictCode) {
48 48 return request({
49 49 url: '/system/dict-data/delete?id=' + dictCode,
50   - method: 'post'
  50 + method: 'delete'
51 51 })
52 52 }
53 53  
... ...
ruoyi-ui/src/api/system/dict/type.js
... ... @@ -30,7 +30,7 @@ export function addType(data) {
30 30 export function updateType(data) {
31 31 return request({
32 32 url: '/system/dict-type/update',
33   - method: 'post',
  33 + method: 'put',
34 34 data: data
35 35 })
36 36 }
... ... @@ -39,7 +39,7 @@ export function updateType(data) {
39 39 export function delType(dictId) {
40 40 return request({
41 41 url: '/system/dict-type/delete?id=' + dictId,
42   - method: 'post'
  42 + method: 'delete'
43 43 })
44 44 }
45 45  
... ...
ruoyi-ui/src/api/system/menu.js
... ... @@ -38,7 +38,7 @@ export function addMenu(data) {
38 38 export function updateMenu(data) {
39 39 return request({
40 40 url: '/system/menu/update',
41   - method: 'post',
  41 + method: 'put',
42 42 data: data
43 43 })
44 44 }
... ... @@ -47,6 +47,6 @@ export function updateMenu(data) {
47 47 export function delMenu(id) {
48 48 return request({
49 49 url: '/system/menu/delete?id=' + id,
50   - method: 'post'
  50 + method: 'delete'
51 51 })
52 52 }
... ...
ruoyi-ui/src/api/system/notice.js
... ... @@ -30,7 +30,7 @@ export function addNotice(data) {
30 30 export function updateNotice(data) {
31 31 return request({
32 32 url: '/system/notice/update',
33   - method: 'post',
  33 + method: 'put',
34 34 data: data
35 35 })
36 36 }
... ... @@ -39,6 +39,6 @@ export function updateNotice(data) {
39 39 export function delNotice(noticeId) {
40 40 return request({
41 41 url: '/system/notice/delete?id=' + noticeId,
42   - method: 'post'
  42 + method: 'delete'
43 43 })
44 44 }
... ...
ruoyi-ui/src/api/system/post.js
... ... @@ -38,7 +38,7 @@ export function addPost(data) {
38 38 export function updatePost(data) {
39 39 return request({
40 40 url: '/system/post/update',
41   - method: 'post',
  41 + method: 'put',
42 42 data: data
43 43 })
44 44 }
... ... @@ -47,7 +47,7 @@ export function updatePost(data) {
47 47 export function delPost(postId) {
48 48 return request({
49 49 url: '/system/post/delete?id=' + postId,
50   - method: 'post'
  50 + method: 'delete'
51 51 })
52 52 }
53 53  
... ...
ruoyi-ui/src/api/system/role.js
... ... @@ -38,7 +38,7 @@ export function addRole(data) {
38 38 export function updateRole(data) {
39 39 return request({
40 40 url: '/system/role/update',
41   - method: 'post',
  41 + method: 'put',
42 42 data: data
43 43 })
44 44 }
... ... @@ -51,7 +51,7 @@ export function changeRoleStatus(id, status) {
51 51 }
52 52 return request({
53 53 url: '/system/role/update-status',
54   - method: 'post',
  54 + method: 'put',
55 55 data: data
56 56 })
57 57 }
... ... @@ -60,7 +60,7 @@ export function changeRoleStatus(id, status) {
60 60 export function delRole(roleId) {
61 61 return request({
62 62 url: '/system/role/delete?id=' + roleId,
63   - method: 'post'
  63 + method: 'delete'
64 64 })
65 65 }
66 66  
... ...
ruoyi-ui/src/api/system/user.js
... ... @@ -31,7 +31,7 @@ export function addUser(data) {
31 31 export function updateUser(data) {
32 32 return request({
33 33 url: '/system/user/update',
34   - method: 'post',
  34 + method: 'put',
35 35 data: data
36 36 })
37 37 }
... ... @@ -62,7 +62,7 @@ export function resetUserPwd(id, password) {
62 62 }
63 63 return request({
64 64 url: '/system/user/update-password',
65   - method: 'post',
  65 + method: 'put',
66 66 data: data
67 67 })
68 68 }
... ... @@ -75,7 +75,7 @@ export function changeUserStatus(id, status) {
75 75 }
76 76 return request({
77 77 url: '/system/user/update-status',
78   - method: 'post',
  78 + method: 'put',
79 79 data: data
80 80 })
81 81 }
... ... @@ -83,7 +83,7 @@ export function changeUserStatus(id, status) {
83 83 // 查询用户个人信息
84 84 export function getUserProfile() {
85 85 return request({
86   - url: '/system/user/profile',
  86 + url: '/system/user/profile/get',
87 87 method: 'get'
88 88 })
89 89 }
... ... @@ -91,7 +91,7 @@ export function getUserProfile() {
91 91 // 修改用户个人信息
92 92 export function updateUserProfile(data) {
93 93 return request({
94   - url: '/system/user/profile',
  94 + url: '/system/user/profile/update',
95 95 method: 'put',
96 96 data: data
97 97 })
... ... @@ -104,9 +104,9 @@ export function updateUserPwd(oldPassword, newPassword) {
104 104 newPassword
105 105 }
106 106 return request({
107   - url: '/system/user/profile/updatePwd',
  107 + url: '/system/user/profile/update-password',
108 108 method: 'put',
109   - params: data
  109 + data: data
110 110 })
111 111 }
112 112  
... ... @@ -114,7 +114,7 @@ export function updateUserPwd(oldPassword, newPassword) {
114 114 export function uploadAvatar(data) {
115 115 return request({
116 116 url: '/system/user/profile/avatar',
117   - method: 'post',
  117 + method: 'put',
118 118 data: data
119 119 })
120 120 }
... ...
ruoyi-ui/src/store/modules/user.js
... ... @@ -53,7 +53,7 @@ const user = {
53 53 getInfo(state.token).then(res => {
54 54 res = res.data; // 读取 data 数据
55 55 const user = res.user
56   - const avatar = user.avatar === "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
  56 + const avatar = user.avatar === "" ? require("@/assets/images/profile.jpg") : user.avatar;
57 57 if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
58 58 commit('SET_ROLES', res.roles)
59 59 commit('SET_PERMISSIONS', res.permissions)
... ...
ruoyi-ui/src/views/system/dept/index.vue
... ... @@ -2,22 +2,11 @@
2 2 <div class="app-container">
3 3 <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch">
4 4 <el-form-item label="部门名称" prop="name">
5   - <el-input
6   - v-model="queryParams.name"
7   - placeholder="请输入部门名称"
8   - clearable
9   - size="small"
10   - @keyup.enter.native="handleQuery"
11   - />
  5 + <el-input v-model="queryParams.name" placeholder="请输入部门名称" clearable size="small" @keyup.enter.native="handleQuery"/>
12 6 </el-form-item>
13 7 <el-form-item label="状态" prop="status">
14 8 <el-select v-model="queryParams.status" placeholder="菜单状态" clearable size="small">
15   - <el-option
16   - v-for="dict in statusDictDatas"
17   - :key="parseInt(dict.value)"
18   - :label="dict.label"
19   - :value="parseInt(dict.value)"
20   - />
  9 + <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
21 10 </el-select>
22 11 </el-form-item>
23 12 <el-form-item>
... ... @@ -28,24 +17,13 @@
28 17  
29 18 <el-row :gutter="10" class="mb8">
30 19 <el-col :span="1.5">
31   - <el-button
32   - type="primary"
33   - icon="el-icon-plus"
34   - size="mini"
35   - @click="handleAdd"
36   - v-hasPermi="['system:dept:add']"
37   - >新增</el-button>
  20 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:dept:create']">新增</el-button>
38 21 </el-col>
39 22 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
40 23 </el-row>
41 24  
42   - <el-table
43   - v-loading="loading"
44   - :data="deptList"
45   - row-key="id"
46   - default-expand-all
47   - :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
48   - >
  25 + <el-table v-loading="loading" :data="deptList" row-key="id" default-expand-all
  26 + :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
49 27 <el-table-column prop="name" label="部门名称" width="260"></el-table-column>
50 28 <el-table-column prop="sort" label="排序" width="200"></el-table-column>
51 29 <el-table-column prop="status" label="状态" :formatter="statusFormat" width="100"></el-table-column>
... ... @@ -56,28 +34,12 @@
56 34 </el-table-column>
57 35 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
58 36 <template slot-scope="scope">
59   - <el-button
60   - size="mini"
61   - type="text"
62   - icon="el-icon-edit"
63   - @click="handleUpdate(scope.row)"
64   - v-hasPermi="['system:dept:edit']"
65   - >修改</el-button>
66   - <el-button
67   - size="mini"
68   - type="text"
69   - icon="el-icon-plus"
70   - @click="handleAdd(scope.row)"
71   - v-hasPermi="['system:dept:add']"
72   - >新增</el-button>
73   - <el-button
74   - v-if="scope.row.parentId !== 0"
75   - size="mini"
76   - type="text"
77   - icon="el-icon-delete"
78   - @click="handleDelete(scope.row)"
79   - v-hasPermi="['system:dept:remove']"
80   - >删除</el-button>
  37 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  38 + v-hasPermi="['system:dept:update']">修改</el-button>
  39 + <el-button size="mini" type="text" icon="el-icon-plus" @click="handleAdd(scope.row)"
  40 + v-hasPermi="['system:dept:create']">新增</el-button>
  41 + <el-button v-if="scope.row.parentId !== 0" size="mini" type="text" icon="el-icon-delete"
  42 + @click="handleDelete(scope.row)" v-hasPermi="['system:dept:delete']">删除</el-button>
81 43 </template>
82 44 </el-table-column>
83 45 </el-table>
... ... @@ -119,11 +81,8 @@
119 81 <el-col :span="12">
120 82 <el-form-item label="部门状态" prop="status">
121 83 <el-radio-group v-model="form.status">
122   - <el-radio
123   - v-for="dict in statusDictDatas"
124   - :key="parseInt(dict.value)"
125   - :label="parseInt(dict.value)"
126   - >{{dict.label}}</el-radio>
  84 + <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
  85 + {{dict.label}}</el-radio>
127 86 </el-radio-group>
128 87 </el-form-item>
129 88 </el-col>
... ...
ruoyi-ui/src/views/system/dict/data.vue
... ... @@ -3,31 +3,15 @@
3 3 <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
4 4 <el-form-item label="字典名称" prop="dictType">
5 5 <el-select v-model="queryParams.dictType" size="small">
6   - <el-option
7   - v-for="item in typeOptions"
8   - :key="item.id"
9   - :label="item.name"
10   - :value="item.type"
11   - />
  6 + <el-option v-for="item in typeOptions" :key="item.id" :label="item.name" :value="item.type"/>
12 7 </el-select>
13 8 </el-form-item>
14 9 <el-form-item label="字典标签" prop="label">
15   - <el-input
16   - v-model="queryParams.label"
17   - placeholder="请输入字典标签"
18   - clearable
19   - size="small"
20   - @keyup.enter.native="handleQuery"
21   - />
  10 + <el-input v-model="queryParams.label" placeholder="请输入字典标签" clearable size="small" @keyup.enter.native="handleQuery"/>
22 11 </el-form-item>
23 12 <el-form-item label="状态" prop="status">
24 13 <el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small">
25   - <el-option
26   - v-for="dict in statusOptions"
27   - :key="dict.value"
28   - :label="dict.label"
29   - :value="dict.value"
30   - />
  14 + <el-option v-for="dict in statusOptions" :key="dict.value" :label="dict.label" :value="dict.value"/>
31 15 </el-select>
32 16 </el-form-item>
33 17 <el-form-item>
... ... @@ -38,22 +22,12 @@
38 22  
39 23 <el-row :gutter="10" class="mb8">
40 24 <el-col :span="1.5">
41   - <el-button
42   - type="primary"
43   - icon="el-icon-plus"
44   - size="mini"
45   - @click="handleAdd"
46   - v-hasPermi="['system:dict:add']"
47   - >新增</el-button>
  25 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd"
  26 + v-hasPermi="['system:dict:create']">新增</el-button>
48 27 </el-col>
49 28 <el-col :span="1.5">
50   - <el-button
51   - type="warning"
52   - icon="el-icon-download"
53   - size="mini"
54   - @click="handleExport"
55   - v-hasPermi="['system:dict:export']"
56   - >导出</el-button>
  29 + <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport"
  30 + v-hasPermi="['system:dict:export']">导出</el-button>
57 31 </el-col>
58 32 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
59 33 </el-row>
... ... @@ -72,31 +46,16 @@
72 46 </el-table-column>
73 47 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
74 48 <template slot-scope="scope">
75   - <el-button
76   - size="mini"
77   - type="text"
78   - icon="el-icon-edit"
79   - @click="handleUpdate(scope.row)"
80   - v-hasPermi="['system:dict:edit']"
81   - >修改</el-button>
82   - <el-button
83   - size="mini"
84   - type="text"
85   - icon="el-icon-delete"
86   - @click="handleDelete(scope.row)"
87   - v-hasPermi="['system:dict:remove']"
88   - >删除</el-button>
  49 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  50 + v-hasPermi="['system:dict:update']">修改</el-button>
  51 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  52 + v-hasPermi="['system:dict:delete']">删除</el-button>
89 53 </template>
90 54 </el-table-column>
91 55 </el-table>
92 56  
93   - <pagination
94   - v-show="total>0"
95   - :total="total"
96   - :page.sync="queryParams.pageNo"
97   - :limit.sync="queryParams.pageSize"
98   - @pagination="getList"
99   - />
  57 + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  58 + @pagination="getList"/>
100 59  
101 60 <!-- 添加或修改参数配置对话框 -->
102 61 <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
... ... @@ -115,11 +74,7 @@
115 74 </el-form-item>
116 75 <el-form-item label="状态" prop="status">
117 76 <el-radio-group v-model="form.status">
118   - <el-radio
119   - v-for="dict in statusDictDatas"
120   - :key="parseInt(dict.value)"
121   - :label="parseInt(dict.value)"
122   - >{{dict.label}}</el-radio>
  77 + <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">{{dict.label}}</el-radio>
123 78 </el-radio-group>
124 79 </el-form-item>
125 80 <el-form-item label="备注" prop="remark">
... ...
ruoyi-ui/src/views/system/dict/index.vue
... ... @@ -2,52 +2,19 @@
2 2 <div class="app-container">
3 3 <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
4 4 <el-form-item label="字典名称" prop="name">
5   - <el-input
6   - v-model="queryParams.name"
7   - placeholder="请输入字典名称"
8   - clearable
9   - size="small"
10   - style="width: 240px"
11   - @keyup.enter.native="handleQuery"
12   - />
  5 + <el-input v-model="queryParams.name" placeholder="请输入字典名称" clearable size="small" style="width: 240px" @keyup.enter.native="handleQuery"/>
13 6 </el-form-item>
14 7 <el-form-item label="字典类型" prop="type">
15   - <el-input
16   - v-model="queryParams.type"
17   - placeholder="请输入字典类型"
18   - clearable
19   - size="small"
20   - style="width: 240px"
21   - @keyup.enter.native="handleQuery"
22   - />
  8 + <el-input v-model="queryParams.type" placeholder="请输入字典类型" clearable size="small" style="width: 240px" @keyup.enter.native="handleQuery"/>
23 9 </el-form-item>
24 10 <el-form-item label="状态" prop="status">
25   - <el-select
26   - v-model="queryParams.status"
27   - placeholder="字典状态"
28   - clearable
29   - size="small"
30   - style="width: 240px"
31   - >
32   - <el-option
33   - v-for="dict in statusDictDatas"
34   - :key="parseInt(dict.value)"
35   - :label="dict.label"
36   - :value="parseInt(dict.value)"
37   - />
  11 + <el-select v-model="queryParams.status" placeholder="字典状态" clearable size="small" style="width: 240px">
  12 + <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
38 13 </el-select>
39 14 </el-form-item>
40 15 <el-form-item label="创建时间">
41   - <el-date-picker
42   - v-model="dateRangeCreateTime"
43   - size="small"
44   - style="width: 240px"
45   - value-format="yyyy-MM-dd"
46   - type="daterange"
47   - range-separator="-"
48   - start-placeholder="开始日期"
49   - end-placeholder="结束日期"
50   - ></el-date-picker>
  16 + <el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"
  17 + range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
51 18 </el-form-item>
52 19 <el-form-item>
53 20 <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
... ... @@ -57,22 +24,12 @@
57 24  
58 25 <el-row :gutter="10" class="mb8">
59 26 <el-col :span="1.5">
60   - <el-button
61   - type="primary"
62   - icon="el-icon-plus"
63   - size="mini"
64   - @click="handleAdd"
65   - v-hasPermi="['system:dict:add']"
66   - >新增</el-button>
  27 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd"
  28 + v-hasPermi="['system:dict:create']">新增</el-button>
67 29 </el-col>
68 30 <el-col :span="1.5">
69   - <el-button
70   - type="warning"
71   - icon="el-icon-download"
72   - size="mini"
73   - @click="handleExport"
74   - v-hasPermi="['system:dict:export']"
75   - >导出</el-button>
  31 + <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport"
  32 + v-hasPermi="['system:dict:export']">导出</el-button>
76 33 </el-col>
77 34 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
78 35 </el-row>
... ... @@ -96,31 +53,16 @@
96 53 </el-table-column>
97 54 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
98 55 <template slot-scope="scope">
99   - <el-button
100   - size="mini"
101   - type="text"
102   - icon="el-icon-edit"
103   - @click="handleUpdate(scope.row)"
104   - v-hasPermi="['system:dict:edit']"
105   - >修改</el-button>
106   - <el-button
107   - size="mini"
108   - type="text"
109   - icon="el-icon-delete"
110   - @click="handleDelete(scope.row)"
111   - v-hasPermi="['system:dict:remove']"
112   - >删除</el-button>
  56 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  57 + v-hasPermi="['system:dict:update']">修改</el-button>
  58 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  59 + v-hasPermi="['system:dict:delete']">删除</el-button>
113 60 </template>
114 61 </el-table-column>
115 62 </el-table>
116 63  
117   - <pagination
118   - v-show="total>0"
119   - :total="total"
120   - :page.sync="queryParams.pageNo"
121   - :limit.sync="queryParams.pageSize"
122   - @pagination="getList"
123   - />
  64 + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  65 + @pagination="getList"/>
124 66  
125 67 <!-- 添加或修改参数配置对话框 -->
126 68 <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
... ... @@ -133,11 +75,7 @@
133 75 </el-form-item>
134 76 <el-form-item label="状态" prop="status">
135 77 <el-radio-group v-model="form.status">
136   - <el-radio
137   - v-for="dict in statusDictDatas"
138   - :key="parseInt(dict.value)"
139   - :label="parseInt(dict.value)"
140   - >{{dict.label}}</el-radio>
  78 + <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">{{dict.label}}</el-radio>
141 79 </el-radio-group>
142 80 </el-form-item>
143 81 <el-form-item label="备注" prop="remark">
... ...
ruoyi-ui/src/views/system/loginlog/index.vue
... ... @@ -2,56 +2,22 @@
2 2 <div class="app-container">
3 3 <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
4 4 <el-form-item label="登录地址" prop="userIp">
5   - <el-input
6   - v-model="queryParams.userIp"
7   - placeholder="请输入登录地址"
8   - clearable
9   - style="width: 240px;"
10   - size="small"
11   - @keyup.enter.native="handleQuery"
12   - />
  5 + <el-input v-model="queryParams.userIp" placeholder="请输入登录地址" clearable style="width: 240px;" size="small"
  6 + @keyup.enter.native="handleQuery"/>
13 7 </el-form-item>
14 8 <el-form-item label="用户名称" prop="username">
15   - <el-input
16   - v-model="queryParams.username"
17   - placeholder="请输入用户名称"
18   - clearable
19   - style="width: 240px;"
20   - size="small"
21   - @keyup.enter.native="handleQuery"
22   - />
  9 + <el-input v-model="queryParams.username" placeholder="请输入用户名称" clearable style="width: 240px;" size="small"
  10 + @keyup.enter.native="handleQuery"/>
23 11 </el-form-item>
24 12 <el-form-item label="状态" prop="status">
25   - <el-select
26   - v-model="queryParams.status"
27   - placeholder="结果"
28   - clearable
29   - size="small"
30   - style="width: 240px"
31   - >
32   - <el-option
33   - :key="true"
34   - label="成功"
35   - :value="true"
36   - />
37   - <el-option
38   - :key="false"
39   - label="失败"
40   - :value="false"
41   - />
  13 + <el-select v-model="queryParams.status" placeholder="结果" clearable size="small" style="width: 240px">
  14 + <el-option :key="true" label="成功" :value="true"/>
  15 + <el-option :key="false" label="失败" :value="false"/>
42 16 </el-select>
43 17 </el-form-item>
44 18 <el-form-item label="登录时间">
45   - <el-date-picker
46   - v-model="dateRange"
47   - size="small"
48   - style="width: 240px"
49   - value-format="yyyy-MM-dd"
50   - type="daterange"
51   - range-separator="-"
52   - start-placeholder="开始日期"
53   - end-placeholder="结束日期"
54   - ></el-date-picker>
  19 + <el-date-picker v-model="dateRange" size="small" style="width: 240px" value-format="yyyy-MM-dd"
  20 + type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
55 21 </el-form-item>
56 22 <el-form-item>
57 23 <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
... ... @@ -61,13 +27,8 @@
61 27  
62 28 <el-row :gutter="10" class="mb8">
63 29 <el-col :span="1.5">
64   - <el-button
65   - type="warning"
66   - icon="el-icon-download"
67   - size="mini"
68   - @click="handleExport"
69   - v-hasPermi="['system:login-log:export']"
70   - >导出</el-button>
  30 + <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport"
  31 + v-hasPermi="['system:login-log:export']">导出</el-button>
71 32 </el-col>
72 33 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
73 34 </el-row>
... ... @@ -76,7 +37,7 @@
76 37 <el-table-column label="访问编号" align="center" prop="id" />
77 38 <el-table-column label="日志类型" align="center" prop="logType">
78 39 <template slot-scope="scope">
79   - <span>{{ scope.row.logType === 1 ? '登录' : '退出' }}</span>
  40 + <span>{{ scope.row.logType === 100 ? '登录' : '退出' }}</span>
80 41 </template>
81 42 </el-table-column>
82 43 <el-table-column label="用户名称" align="center" prop="username" />
... ... @@ -95,13 +56,8 @@
95 56 </el-table-column>
96 57 </el-table>
97 58  
98   - <pagination
99   - v-show="total>0"
100   - :total="total"
101   - :page.sync="queryParams.pageNo"
102   - :limit.sync="queryParams.pageSize"
103   - @pagination="getList"
104   - />
  59 + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  60 + @pagination="getList"/>
105 61 </div>
106 62 </template>
107 63  
... ...
ruoyi-ui/src/views/system/menu/index.vue
... ... @@ -2,22 +2,11 @@
2 2 <div class="app-container">
3 3 <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch">
4 4 <el-form-item label="菜单名称" prop="name">
5   - <el-input
6   - v-model="queryParams.name"
7   - placeholder="请输入菜单名称"
8   - clearable
9   - size="small"
10   - @keyup.enter.native="handleQuery"
11   - />
  5 + <el-input v-model="queryParams.name" placeholder="请输入菜单名称" clearable size="small" @keyup.enter.native="handleQuery"/>
12 6 </el-form-item>
13 7 <el-form-item label="状态" prop="status">
14 8 <el-select v-model="queryParams.status" placeholder="菜单状态" clearable size="small">
15   - <el-option
16   - v-for="dict in statusDictDatas"
17   - :key="parseInt(dict.value)"
18   - :label="dict.label"
19   - :value="parseInt(dict.value)"
20   - />
  9 + <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
21 10 </el-select>
22 11 </el-form-item>
23 12 <el-form-item>
... ... @@ -28,23 +17,14 @@
28 17  
29 18 <el-row :gutter="10" class="mb8">
30 19 <el-col :span="1.5">
31   - <el-button
32   - type="primary"
33   - icon="el-icon-plus"
34   - size="mini"
35   - @click="handleAdd"
36   - v-hasPermi="['system:menu:add']"
37   - >新增</el-button>
  20 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd"
  21 + v-hasPermi="['system:menu:create']">新增</el-button>
38 22 </el-col>
39 23 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
40 24 </el-row>
41 25  
42   - <el-table
43   - v-loading="loading"
44   - :data="menuList"
45   - row-key="id"
46   - :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
47   - >
  26 + <el-table v-loading="loading" :data="menuList" row-key="id"
  27 + :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
48 28 <el-table-column prop="name" label="菜单名称" :show-overflow-tooltip="true" width="200"></el-table-column>
49 29 <el-table-column prop="icon" label="图标" align="center" width="100">
50 30 <template slot-scope="scope">
... ... @@ -62,26 +42,12 @@
62 42 </el-table-column>
63 43 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
64 44 <template slot-scope="scope">
65   - <el-button size="mini"
66   - type="text"
67   - icon="el-icon-edit"
68   - @click="handleUpdate(scope.row)"
69   - v-hasPermi="['system:menu:edit']"
70   - >修改</el-button>
71   - <el-button
72   - size="mini"
73   - type="text"
74   - icon="el-icon-plus"
75   - @click="handleAdd(scope.row)"
76   - v-hasPermi="['system:menu:add']"
77   - >新增</el-button>
78   - <el-button
79   - size="mini"
80   - type="text"
81   - icon="el-icon-delete"
82   - @click="handleDelete(scope.row)"
83   - v-hasPermi="['system:menu:remove']"
84   - >删除</el-button>
  45 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  46 + v-hasPermi="['system:menu:update']">修改</el-button>
  47 + <el-button size="mini" type="text" icon="el-icon-plus" @click="handleAdd(scope.row)"
  48 + v-hasPermi="['system:menu:create']">新增</el-button>
  49 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  50 + v-hasPermi="['system:menu:delete']">删除</el-button>
85 51 </template>
86 52 </el-table-column>
87 53 </el-table>
... ... @@ -92,43 +58,25 @@
92 58 <el-row>
93 59 <el-col :span="24">
94 60 <el-form-item label="上级菜单">
95   - <treeselect
96   - v-model="form.parentId"
97   - :options="menuOptions"
98   - :normalizer="normalizer"
99   - :show-count="true"
100   - placeholder="选择上级菜单"
101   - />
  61 + <treeselect v-model="form.parentId" :options="menuOptions" :normalizer="normalizer" :show-count="true"
  62 + placeholder="选择上级菜单"/>
102 63 </el-form-item>
103 64 </el-col>
104 65 <el-col :span="24">
105 66 <el-form-item label="菜单类型" prop="type">
106 67 <el-radio-group v-model="form.type">
107   - <el-radio
108   - v-for="dict in menuTypeDictDatas"
109   - :key="parseInt(dict.value)"
110   - :label="parseInt(dict.value)"
111   - >{{dict.label}}</el-radio>
  68 + <el-radio v-for="dict in menuTypeDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
  69 + {{dict.label}}</el-radio>
112 70 </el-radio-group>
113 71 </el-form-item>
114 72 </el-col>
115 73 <el-col :span="24">
116 74 <el-form-item v-if="form.type != '3'" label="菜单图标">
117   - <el-popover
118   - placement="bottom-start"
119   - width="460"
120   - trigger="click"
121   - @show="$refs['iconSelect'].reset()"
122   - >
  75 + <el-popover placement="bottom-start" width="460" trigger="click" @show="$refs['iconSelect'].reset()">
123 76 <IconSelect ref="iconSelect" @selected="selected" />
124 77 <el-input slot="reference" v-model="form.icon" placeholder="点击选择图标" readonly>
125   - <svg-icon
126   - v-if="form.icon"
127   - slot="prefix"
128   - :icon-class="form.icon"
129   - class="el-input__icon"
130   - style="height: 32px;width: 16px;"
131   - />
  78 + <svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon"
  79 + style="height: 32px;width: 16px;"/>
132 80 <i v-else slot="prefix" class="el-icon-search el-input__icon" />
133 81 </el-input>
134 82 </el-popover>
... ...
ruoyi-ui/src/views/system/notice/index.vue
... ... @@ -2,31 +2,14 @@
2 2 <div class="app-container">
3 3 <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
4 4 <el-form-item label="公告标题" prop="title">
5   - <el-input
6   - v-model="queryParams.title"
7   - placeholder="请输入公告标题"
8   - clearable
9   - size="small"
10   - @keyup.enter.native="handleQuery"
11   - />
  5 + <el-input v-model="queryParams.title" placeholder="请输入公告标题" clearable size="small" @keyup.enter.native="handleQuery"/>
12 6 </el-form-item>
13 7 <el-form-item label="操作人员" prop="createBy">
14   - <el-input
15   - v-model="queryParams.createBy"
16   - placeholder="请输入操作人员"
17   - clearable
18   - size="small"
19   - @keyup.enter.native="handleQuery"
20   - />
  8 + <el-input v-model="queryParams.createBy" placeholder="请输入操作人员" clearable size="small" @keyup.enter.native="handleQuery"/>
21 9 </el-form-item>
22 10 <el-form-item label="类型" prop="type">
23 11 <el-select v-model="queryParams.type" placeholder="公告类型" clearable size="small">
24   - <el-option
25   - v-for="dict in noticeTypeDictDatas"
26   - :key="parseInt(dict.value)"
27   - :label="dict.label"
28   - :value="parseInt(dict.value)"
29   - />
  12 + <el-option v-for="dict in noticeTypeDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
30 13 </el-select>
31 14 </el-form-item>
32 15 <el-form-item>
... ... @@ -37,39 +20,16 @@
37 20  
38 21 <el-row :gutter="10" class="mb8">
39 22 <el-col :span="1.5">
40   - <el-button
41   - type="primary"
42   - icon="el-icon-plus"
43   - size="mini"
44   - @click="handleAdd"
45   - v-hasPermi="['system:notice:add']"
46   - >新增</el-button>
  23 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:notice:create']"s>新增</el-button>
47 24 </el-col>
48 25 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
49 26 </el-row>
50 27  
51 28 <el-table v-loading="loading" :data="noticeList">
52 29 <el-table-column label="序号" align="center" prop="id" width="100" />
53   - <el-table-column
54   - label="公告标题"
55   - align="center"
56   - prop="title"
57   - :show-overflow-tooltip="true"
58   - />
59   - <el-table-column
60   - label="公告类型"
61   - align="center"
62   - prop="type"
63   - :formatter="typeFormat"
64   - width="100"
65   - />
66   - <el-table-column
67   - label="状态"
68   - align="center"
69   - prop="status"
70   - :formatter="statusFormat"
71   - width="100"
72   - />
  30 + <el-table-column label="公告标题" align="center" prop="title" :show-overflow-tooltip="true"/>
  31 + <el-table-column label="公告类型" align="center" prop="type" :formatter="typeFormat" width="100"/>
  32 + <el-table-column label="状态" align="center" prop="status" :formatter="statusFormat" width="100"/>
73 33 <el-table-column label="创建者" align="center" prop="createBy" width="100" />
74 34 <el-table-column label="创建时间" align="center" prop="createTime" width="100">
75 35 <template slot-scope="scope">
... ... @@ -78,31 +38,16 @@
78 38 </el-table-column>
79 39 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
80 40 <template slot-scope="scope">
81   - <el-button
82   - size="mini"
83   - type="text"
84   - icon="el-icon-edit"
85   - @click="handleUpdate(scope.row)"
86   - v-hasPermi="['system:notice:edit']"
87   - >修改</el-button>
88   - <el-button
89   - size="mini"
90   - type="text"
91   - icon="el-icon-delete"
92   - @click="handleDelete(scope.row)"
93   - v-hasPermi="['system:notice:remove']"
94   - >删除</el-button>
  41 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  42 + v-hasPermi="['system:notice:update']">修改</el-button>
  43 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  44 + v-hasPermi="['system:notice:delete']">删除</el-button>
95 45 </template>
96 46 </el-table-column>
97 47 </el-table>
98 48  
99   - <pagination
100   - v-show="total>0"
101   - :total="total"
102   - :page.sync="queryParams.pageNo"
103   - :limit.sync="queryParams.pageSize"
104   - @pagination="getList"
105   - />
  49 + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  50 + @pagination="getList"/>
106 51  
107 52 <!-- 添加或修改公告对话框 -->
108 53 <el-dialog :title="title" :visible.sync="open" width="780px" append-to-body>
... ...
ruoyi-ui/src/views/system/operatelog/index.vue
... ... @@ -2,72 +2,28 @@
2 2 <div class="app-container">
3 3 <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
4 4 <el-form-item label="系统模块" prop="title">
5   - <el-input
6   - v-model="queryParams.title"
7   - placeholder="请输入系统模块"
8   - clearable
9   - style="width: 240px;"
10   - size="small"
11   - @keyup.enter.native="handleQuery"
12   - />
  5 + <el-input v-model="queryParams.title" placeholder="请输入系统模块" clearable style="width: 240px;" size="small"
  6 + @keyup.enter.native="handleQuery"/>
13 7 </el-form-item>
14 8 <el-form-item label="操作人员" prop="operName">
15   - <el-input
16   - v-model="queryParams.operName"
17   - placeholder="请输入操作人员"
18   - clearable
19   - style="width: 240px;"
20   - size="small"
21   - @keyup.enter.native="handleQuery"
22   - />
  9 + <el-input v-model="queryParams.operName" placeholder="请输入操作人员" clearable style="width: 240px;" size="small"
  10 + @keyup.enter.native="handleQuery"/>
23 11 </el-form-item>
24 12 <el-form-item label="类型" prop="type">
25   - <el-select
26   - v-model="queryParams.type"
27   - placeholder="操作类型"
28   - clearable
29   - size="small"
30   - style="width: 240px"
31   - >
32   - <el-option
33   - v-for="dict in this.getDictDatas(DICT_TYPE.SYS_OPERATE_TYPE)"
34   - :key="parseInt(dict.value)"
35   - :label="dict.label"
36   - :value="parseInt(dict.value)"
37   - />
  13 + <el-select v-model="queryParams.type" placeholder="操作类型" clearable size="small" style="width: 240px">
  14 + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYS_OPERATE_TYPE)" :key="parseInt(dict.value)"
  15 + :label="dict.label" :value="parseInt(dict.value)"/>
38 16 </el-select>
39 17 </el-form-item>
40 18 <el-form-item label="状态" prop="status">
41   - <el-select
42   - v-model="queryParams.success"
43   - placeholder="操作状态"
44   - clearable
45   - size="small"
46   - style="width: 240px"
47   - >
48   - <el-option
49   - :key="true"
50   - label="成功"
51   - :value="true"
52   - />
53   - <el-option
54   - :key="false"
55   - label="失败"
56   - :value="false"
57   - />
  19 + <el-select v-model="queryParams.success" placeholder="操作状态" clearable size="small" style="width: 240px">
  20 + <el-option :key="true" label="成功" :value="true"/>
  21 + <el-option :key="false" label="失败" :value="false"/>
58 22 </el-select>
59 23 </el-form-item>
60 24 <el-form-item label="操作时间">
61   - <el-date-picker
62   - v-model="dateRange"
63   - size="small"
64   - style="width: 240px"
65   - value-format="yyyy-MM-dd"
66   - type="daterange"
67   - range-separator="-"
68   - start-placeholder="开始日期"
69   - end-placeholder="结束日期"
70   - ></el-date-picker>
  25 + <el-date-picker v-model="dateRange" size="small" style="width: 240px" value-format="yyyy-MM-dd"
  26 + type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
71 27 </el-form-item>
72 28 <el-form-item>
73 29 <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
... ... @@ -77,13 +33,8 @@
77 33  
78 34 <el-row :gutter="10" class="mb8">
79 35 <el-col :span="1.5">
80   - <el-button
81   - type="warning"
82   - icon="el-icon-download"
83   - size="mini"
84   - @click="handleExport"
85   - v-hasPermi="['system:config:export']"
86   - >导出</el-button>
  36 + <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport"
  37 + v-hasPermi="['system:operate-log:export']">导出</el-button>
87 38 </el-col>
88 39 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
89 40 </el-row>
... ...
ruoyi-ui/src/views/system/post/index.vue
... ... @@ -2,31 +2,14 @@
2 2 <div class="app-container">
3 3 <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
4 4 <el-form-item label="岗位编码" prop="code">
5   - <el-input
6   - v-model="queryParams.code"
7   - placeholder="请输入岗位编码"
8   - clearable
9   - size="small"
10   - @keyup.enter.native="handleQuery"
11   - />
  5 + <el-input v-model="queryParams.code" placeholder="请输入岗位编码" clearable size="small" @keyup.enter.native="handleQuery"/>
12 6 </el-form-item>
13 7 <el-form-item label="岗位名称" prop="name">
14   - <el-input
15   - v-model="queryParams.name"
16   - placeholder="请输入岗位名称"
17   - clearable
18   - size="small"
19   - @keyup.enter.native="handleQuery"
20   - />
  8 + <el-input v-model="queryParams.name" placeholder="请输入岗位名称" clearable size="small" @keyup.enter.native="handleQuery"/>
21 9 </el-form-item>
22 10 <el-form-item label="状态" prop="status">
23 11 <el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small">
24   - <el-option
25   - v-for="dict in statusDictDatas"
26   - :key="parseInt(dict.value)"
27   - :label="dict.label"
28   - :value="parseInt(dict.value)"
29   - />
  12 + <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
30 13 </el-select>
31 14 </el-form-item>
32 15 <el-form-item>
... ... @@ -37,22 +20,12 @@
37 20  
38 21 <el-row :gutter="10" class="mb8">
39 22 <el-col :span="1.5">
40   - <el-button
41   - type="primary"
42   - icon="el-icon-plus"
43   - size="mini"
44   - @click="handleAdd"
45   - v-hasPermi="['system:post:add']"
46   - >新增</el-button>
  23 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd"
  24 + v-hasPermi="['system:post:create']">新增</el-button>
47 25 </el-col>
48 26 <el-col :span="1.5">
49   - <el-button
50   - type="warning"
51   - icon="el-icon-download"
52   - size="mini"
53   - @click="handleExport"
54   - v-hasPermi="['system:post:export']"
55   - >导出</el-button>
  27 + <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport"
  28 + v-hasPermi="['system:post:export']">导出</el-button>
56 29 </el-col>
57 30 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
58 31 </el-row>
... ... @@ -70,31 +43,16 @@
70 43 </el-table-column>
71 44 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
72 45 <template slot-scope="scope">
73   - <el-button
74   - size="mini"
75   - type="text"
76   - icon="el-icon-edit"
77   - @click="handleUpdate(scope.row)"
78   - v-hasPermi="['system:post:edit']"
79   - >修改</el-button>
80   - <el-button
81   - size="mini"
82   - type="text"
83   - icon="el-icon-delete"
84   - @click="handleDelete(scope.row)"
85   - v-hasPermi="['system:post:remove']"
86   - >删除</el-button>
  46 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  47 + v-hasPermi="['system:post:update']">修改</el-button>
  48 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  49 + v-hasPermi="['system:post:delete']">删除</el-button>
87 50 </template>
88 51 </el-table-column>
89 52 </el-table>
90 53  
91   - <pagination
92   - v-show="total>0"
93   - :total="total"
94   - :page.sync="queryParams.pageNo"
95   - :limit.sync="queryParams.pageSize"
96   - @pagination="getList"
97   - />
  54 + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  55 + @pagination="getList"/>
98 56  
99 57 <!-- 添加或修改岗位对话框 -->
100 58 <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
... ... @@ -110,11 +68,8 @@
110 68 </el-form-item>
111 69 <el-form-item label="岗位状态" prop="status">
112 70 <el-radio-group v-model="form.status">
113   - <el-radio
114   - v-for="dict in statusDictDatas"
115   - :key="parseInt(dict.value)"
116   - :label="parseInt(dict.value)"
117   - >{{dict.label}}</el-radio>
  71 + <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
  72 + {{dict.label}}</el-radio>
118 73 </el-radio-group>
119 74 </el-form-item>
120 75 <el-form-item label="备注" prop="remark">
... ...
ruoyi-ui/src/views/system/role/index.vue
... ... @@ -2,52 +2,21 @@
2 2 <div class="app-container">
3 3 <el-form :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true">
4 4 <el-form-item label="角色名称" prop="name">
5   - <el-input
6   - v-model="queryParams.name"
7   - placeholder="请输入角色名称"
8   - clearable
9   - size="small"
10   - style="width: 240px"
11   - @keyup.enter.native="handleQuery"
12   - />
  5 + <el-input v-model="queryParams.name" placeholder="请输入角色名称" clearable size="small" style="width: 240px"
  6 + @keyup.enter.native="handleQuery"/>
13 7 </el-form-item>
14 8 <el-form-item label="角色标识" prop="code">
15   - <el-input
16   - v-model="queryParams.code"
17   - placeholder="请输入角色标识"
18   - clearable
19   - size="small"
20   - style="width: 240px"
21   - @keyup.enter.native="handleQuery"
22   - />
  9 + <el-input v-model="queryParams.code" placeholder="请输入角色标识" clearable size="small" style="width: 240px"
  10 + @keyup.enter.native="handleQuery"/>
23 11 </el-form-item>
24 12 <el-form-item label="状态" prop="status">
25   - <el-select
26   - v-model="queryParams.status"
27   - placeholder="角色状态"
28   - clearable
29   - size="small"
30   - style="width: 240px"
31   - >
32   - <el-option
33   - v-for="dict in statusDictDatas"
34   - :key="parseInt(dict.value)"
35   - :label="dict.label"
36   - :value="parseInt(dict.value)"
37   - />
  13 + <el-select v-model="queryParams.status" placeholder="角色状态" clearable size="small" style="width: 240px">
  14 + <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
38 15 </el-select>
39 16 </el-form-item>
40 17 <el-form-item label="创建时间">
41   - <el-date-picker
42   - v-model="dateRange"
43   - size="small"
44   - style="width: 240px"
45   - value-format="yyyy-MM-dd"
46   - type="daterange"
47   - range-separator="-"
48   - start-placeholder="开始日期"
49   - end-placeholder="结束日期"
50   - ></el-date-picker>
  18 + <el-date-picker v-model="dateRange" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"
  19 + range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
51 20 </el-form-item>
52 21 <el-form-item>
53 22 <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
... ... @@ -57,22 +26,12 @@
57 26  
58 27 <el-row :gutter="10" class="mb8">
59 28 <el-col :span="1.5">
60   - <el-button
61   - type="primary"
62   - icon="el-icon-plus"
63   - size="mini"
64   - @click="handleAdd"
65   - v-hasPermi="['system:role:add']"
66   - >新增</el-button>
  29 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd"
  30 + v-hasPermi="['system:role:create']">新增</el-button>
67 31 </el-col>
68 32 <el-col :span="1.5">
69   - <el-button
70   - type="warning"
71   - icon="el-icon-download"
72   - size="mini"
73   - @click="handleExport"
74   - v-hasPermi="['system:role:export']"
75   - >导出</el-button>
  33 + <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport"
  34 + v-hasPermi="['system:role:export']">导出</el-button>
76 35 </el-col>
77 36 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
78 37 </el-row>
... ... @@ -85,12 +44,7 @@
85 44 <el-table-column label="显示顺序" prop="sort" width="100" />
86 45 <el-table-column label="状态" align="center" width="100">
87 46 <template slot-scope="scope">
88   - <el-switch
89   - v-model="scope.row.status"
90   - :active-value="0"
91   - :inactive-value="1"
92   - @change="handleStatusChange(scope.row)"
93   - ></el-switch>
  47 + <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
94 48 </template>
95 49 </el-table-column>
96 50 <el-table-column label="创建时间" align="center" prop="createTime" width="180">
... ... @@ -100,45 +54,20 @@
100 54 </el-table-column>
101 55 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
102 56 <template slot-scope="scope">
103   - <el-button
104   - size="mini"
105   - type="text"
106   - icon="el-icon-edit"
107   - @click="handleUpdate(scope.row)"
108   - v-hasPermi="['system:role:edit']"
109   - >修改</el-button>
110   - <el-button
111   - size="mini"
112   - type="text"
113   - icon="el-icon-circle-check"
114   - @click="handleMenu(scope.row)"
115   - v-hasPermi="['system:permission:assign-role-menu']"
116   - >菜单权限</el-button>
117   - <el-button
118   - size="mini"
119   - type="text"
120   - icon="el-icon-circle-check"
121   - @click="handleDataScope(scope.row)"
122   - v-hasPermi="['system:permission:assign-role-data-scope']"
123   - >数据权限</el-button>
124   - <el-button
125   - size="mini"
126   - type="text"
127   - icon="el-icon-delete"
128   - @click="handleDelete(scope.row)"
129   - v-hasPermi="['system:role:remove']"
130   - >删除</el-button>
  57 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  58 + v-hasPermi="['system:role:update']">修改</el-button>
  59 + <el-button size="mini" type="text" icon="el-icon-circle-check" @click="handleMenu(scope.row)"
  60 + v-hasPermi="['system:permission:assign-role-menu']">菜单权限</el-button>
  61 + <el-button size="mini" type="text" icon="el-icon-circle-check" @click="handleDataScope(scope.row)"
  62 + v-hasPermi="['system:permission:assign-role-data-scope']">数据权限</el-button>
  63 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  64 + v-hasPermi="['system:role:delete']">删除</el-button>
131 65 </template>
132 66 </el-table-column>
133 67 </el-table>
134 68  
135   - <pagination
136   - v-show="total>0"
137   - :total="total"
138   - :page.sync="queryParams.pageNum"
139   - :limit.sync="queryParams.pageSize"
140   - @pagination="getList"
141   - />
  69 + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
  70 + @pagination="getList"/>
142 71  
143 72 <!-- 添加或修改角色配置对话框 -->
144 73 <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
... ...
ruoyi-ui/src/views/system/user/index.vue
... ... @@ -4,77 +4,32 @@
4 4 <!--部门数据-->
5 5 <el-col :span="4" :xs="24">
6 6 <div class="head-container">
7   - <el-input
8   - v-model="deptName"
9   - placeholder="请输入部门名称"
10   - clearable
11   - size="small"
12   - prefix-icon="el-icon-search"
13   - style="margin-bottom: 20px"
14   - />
  7 + <el-input v-model="deptName" placeholder="请输入部门名称" clearable size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px"/>
15 8 </div>
16 9 <div class="head-container">
17   - <el-tree
18   - :data="deptOptions"
19   - :props="defaultProps"
20   - :expand-on-click-node="false"
21   - :filter-node-method="filterNode"
22   - ref="tree"
23   - default-expand-all
24   - @node-click="handleNodeClick"
25   - />
  10 + <el-tree :data="deptOptions" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode"
  11 + ref="tree" default-expand-all @node-click="handleNodeClick"/>
26 12 </div>
27 13 </el-col>
28 14 <!--用户数据-->
29 15 <el-col :span="20" :xs="24">
30 16 <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
31 17 <el-form-item label="用户名称" prop="username">
32   - <el-input
33   - v-model="queryParams.username"
34   - placeholder="请输入用户名称"
35   - clearable
36   - size="small"
37   - style="width: 240px"
38   - @keyup.enter.native="handleQuery"
39   - />
  18 + <el-input v-model="queryParams.username" placeholder="请输入用户名称" clearable size="small" style="width: 240px"
  19 + @keyup.enter.native="handleQuery"/>
40 20 </el-form-item>
41 21 <el-form-item label="手机号码" prop="mobile">
42   - <el-input
43   - v-model="queryParams.mobile"
44   - placeholder="请输入手机号码"
45   - clearable
46   - size="small"
47   - style="width: 240px"
48   - @keyup.enter.native="handleQuery"
49   - />
  22 + <el-input v-model="queryParams.mobile" placeholder="请输入手机号码" clearable size="small" style="width: 240px"
  23 + @keyup.enter.native="handleQuery"/>
50 24 </el-form-item>
51 25 <el-form-item label="状态" prop="status">
52   - <el-select
53   - v-model="queryParams.status"
54   - placeholder="用户状态"
55   - clearable
56   - size="small"
57   - style="width: 240px"
58   - >
59   - <el-option
60   - v-for="dict in statusDictDatas"
61   - :key="parseInt(dict.value)"
62   - :label="dict.label"
63   - :value="parseInt(dict.value)"
64   - />
  26 + <el-select v-model="queryParams.status" placeholder="用户状态" clearable size="small" style="width: 240px">
  27 + <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
65 28 </el-select>
66 29 </el-form-item>
67 30 <el-form-item label="创建时间">
68   - <el-date-picker
69   - v-model="dateRange"
70   - size="small"
71   - style="width: 240px"
72   - value-format="yyyy-MM-dd"
73   - type="daterange"
74   - range-separator="-"
75   - start-placeholder="开始日期"
76   - end-placeholder="结束日期"
77   - ></el-date-picker>
  31 + <el-date-picker v-model="dateRange" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"
  32 + range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
78 33 </el-form-item>
79 34 <el-form-item>
80 35 <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
... ... @@ -84,31 +39,16 @@
84 39  
85 40 <el-row :gutter="10" class="mb8">
86 41 <el-col :span="1.5">
87   - <el-button
88   - type="primary"
89   - icon="el-icon-plus"
90   - size="mini"
91   - @click="handleAdd"
92   - v-hasPermi="['system:user:add']"
93   - >新增</el-button>
  42 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd"
  43 + v-hasPermi="['system:user:create']">新增</el-button>
94 44 </el-col>
95 45 <el-col :span="1.5">
96   - <el-button
97   - type="info"
98   - icon="el-icon-upload2"
99   - size="mini"
100   - @click="handleImport"
101   - v-hasPermi="['system:user:import']"
102   - >导入</el-button>
  46 + <el-button type="info" icon="el-icon-upload2" size="mini" @click="handleImport"
  47 + v-hasPermi="['system:user:import']">导入</el-button>
103 48 </el-col>
104 49 <el-col :span="1.5">
105   - <el-button
106   - type="warning"
107   - icon="el-icon-download"
108   - size="mini"
109   - @click="handleExport"
110   - v-hasPermi="['system:user:export']"
111   - >导出</el-button>
  50 + <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport"
  51 + v-hasPermi="['system:user:export']">导出</el-button>
112 52 </el-col>
113 53 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
114 54 </el-row>
... ... @@ -121,12 +61,7 @@
121 61 <el-table-column label="手机号码" align="center" prop="mobile" width="120" />
122 62 <el-table-column label="状态" align="center">
123 63 <template slot-scope="scope">
124   - <el-switch
125   - v-model="scope.row.status"
126   - :active-value="0"
127   - :inactive-value="1"
128   - @change="handleStatusChange(scope.row)"
129   - ></el-switch>
  64 + <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)" />
130 65 </template>
131 66 </el-table-column>
132 67 <el-table-column label="创建时间" align="center" prop="createTime" width="160">
... ... @@ -134,60 +69,29 @@
134 69 <span>{{ parseTime(scope.row.createTime) }}</span>
135 70 </template>
136 71 </el-table-column>
137   - <el-table-column
138   - label="操作"
139   - align="center"
140   - width="160"
141   - class-name="small-padding fixed-width"
142   - >
  72 + <el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
143 73 <template slot-scope="scope">
144   - <el-button
145   - size="large"
146   - type="text"
147   - icon="el-icon-edit"
148   - @click="handleUpdate(scope.row)"
149   - v-hasPermi="['system:role:edit']"
150   - >修改</el-button>
  74 + <el-button size="large" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  75 + v-hasPermi="['system:role:update']">修改</el-button>
151 76 <el-dropdown @command="(command) => handleCommand(command, scope.$index, scope.row)">
152 77 <span class="el-dropdown-link">
153 78 更多操作<i class="el-icon-arrow-down el-icon--right"></i>
154 79 </span>
155 80 <el-dropdown-menu slot="dropdown">
156   - <el-dropdown-item
157   - command="handleDelete"
158   - v-if="scope.row.id !== 1"
159   - size="mini"
160   - type="text"
161   - icon="el-icon-delete"
162   - v-hasPermi="['system:user:remove']"
163   - >删除</el-dropdown-item>
164   - <el-dropdown-item
165   - command="handleResetPwd"
166   - size="mini"
167   - type="text"
168   - icon="el-icon-key"
169   - v-hasPermi="['system:user:resetPwd']"
170   - >重置</el-dropdown-item>
171   - <el-dropdown-item
172   - command="handleRole"
173   - size="mini"
174   - type="text"
175   - icon="el-icon-circle-check"
176   - v-hasPermi="['system:permission:assign-user-role']"
177   - >分配角色</el-dropdown-item>
  81 + <el-dropdown-item command="handleDelete" v-if="scope.row.id !== 1" size="mini" type="text" icon="el-icon-delete"
  82 + v-hasPermi="['system:user:delete']">删除</el-dropdown-item>
  83 + <el-dropdown-item command="handleResetPwd" size="mini" type="text" icon="el-icon-key"
  84 + v-hasPermi="['system:user:update-password']">重置密码</el-dropdown-item>
  85 + <el-dropdown-item command="handleRole" size="mini" type="text" icon="el-icon-circle-check"
  86 + v-hasPermi="['system:permission:assign-user-role']">分配角色</el-dropdown-item>
178 87 </el-dropdown-menu>
179 88 </el-dropdown>
180 89 </template>
181 90 </el-table-column>
182 91 </el-table>
183 92  
184   - <pagination
185   - v-show="total>0"
186   - :total="total"
187   - :page.sync="queryParams.pageNo"
188   - :limit.sync="queryParams.pageSize"
189   - @pagination="getList"
190   - />
  93 + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  94 + @pagination="getList"/>
191 95 </el-col>
192 96 </el-row>
193 97  
... ... @@ -203,8 +107,7 @@
203 107 <el-col :span="12">
204 108 <el-form-item label="归属部门" prop="deptId">
205 109 <treeselect v-model="form.deptId" :options="deptOptions" :show-count="true"
206   - placeholder="请选择归属部门" :normalizer="normalizer"
207   - />
  110 + placeholder="请选择归属部门" :normalizer="normalizer"/>
208 111 </el-form-item>
209 112 </el-col>
210 113 </el-row>
... ... @@ -236,12 +139,7 @@
236 139 <el-col :span="12">
237 140 <el-form-item label="用户性别">
238 141 <el-select v-model="form.sex" placeholder="请选择">
239   - <el-option
240   - v-for="dict in sexDictDatas"
241   - :key="parseInt(dict.value)"
242   - :label="dict.label"
243   - :value="parseInt(dict.value)"
244   - ></el-option>
  142 + <el-option v-for="dict in sexDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
245 143 </el-select>
246 144 </el-form-item>
247 145 </el-col>
... ... @@ -333,8 +231,18 @@
333 231 </template>
334 232  
335 233 <script>
336   -import { listUser, getUser, delUser, addUser, updateUser, exportUser, resetUserPwd, changeUserStatus, importTemplate } from "@/api/system/user";
337   -import { getToken } from "@/utils/auth";
  234 +import {
  235 + addUser,
  236 + changeUserStatus,
  237 + delUser,
  238 + exportUser,
  239 + getUser,
  240 + importTemplate,
  241 + listUser,
  242 + resetUserPwd,
  243 + updateUser
  244 +} from "@/api/system/user";
  245 +import {getToken} from "@/utils/auth";
338 246 import Treeselect from "@riophae/vue-treeselect";
339 247 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
340 248  
... ...
ruoyi-ui/src/views/system/user/profile/index.vue
... ... @@ -13,11 +13,11 @@
13 13 <ul class="list-group list-group-striped">
14 14 <li class="list-group-item">
15 15 <svg-icon icon-class="user" />用户名称
16   - <div class="pull-right">{{ user.userName }}</div>
  16 + <div class="pull-right">{{ user.username }}</div>
17 17 </li>
18 18 <li class="list-group-item">
19 19 <svg-icon icon-class="phone" />手机号码
20   - <div class="pull-right">{{ user.phonenumber }}</div>
  20 + <div class="pull-right">{{ user.mobile }}</div>
21 21 </li>
22 22 <li class="list-group-item">
23 23 <svg-icon icon-class="email" />用户邮箱
... ... @@ -25,15 +25,19 @@
25 25 </li>
26 26 <li class="list-group-item">
27 27 <svg-icon icon-class="tree" />所属部门
28   - <div class="pull-right" v-if="user.dept">{{ user.dept.deptName }} / {{ postGroup }}</div>
  28 + <div class="pull-right" v-if="user.dept">{{ user.dept.name }}</div>
  29 + </li>
  30 + <li class="list-group-item">
  31 + <svg-icon icon-class="tree" />所属岗位
  32 + <div class="pull-right" v-if="user.posts">{{ user.posts.map(post => post.name).join(',') }}</div>
29 33 </li>
30 34 <li class="list-group-item">
31 35 <svg-icon icon-class="peoples" />所属角色
32   - <div class="pull-right">{{ roleGroup }}</div>
  36 + <div class="pull-right">{{ user.roles.map(post => post.name).join(',') }}</div>
33 37 </li>
34 38 <li class="list-group-item">
35 39 <svg-icon icon-class="date" />创建日期
36   - <div class="pull-right">{{ user.createTime }}</div>
  40 + <div class="pull-right">{{ parseTime(user.createTime) }}</div>
37 41 </li>
38 42 </ul>
39 43 </div>
... ... @@ -82,8 +86,6 @@ export default {
82 86 getUser() {
83 87 getUserProfile().then(response => {
84 88 this.user = response.data;
85   - this.roleGroup = response.roleGroup;
86   - this.postGroup = response.postGroup;
87 89 });
88 90 }
89 91 }
... ...
ruoyi-ui/src/views/system/user/profile/userInfo.vue
1 1 <template>
2 2 <el-form ref="form" :model="user" :rules="rules" label-width="80px">
3 3 <el-form-item label="用户昵称" prop="nickName">
4   - <el-input v-model="user.nickName" />
5   - </el-form-item>
6   - <el-form-item label="手机号码" prop="phonenumber">
7   - <el-input v-model="user.phonenumber" maxlength="11" />
  4 + <el-input v-model="user.nickname" />
  5 + </el-form-item>
  6 + <el-form-item label="手机号码" prop="mobile">
  7 + <el-input v-model="user.mobile" maxlength="11" />
8 8 </el-form-item>
9 9 <el-form-item label="邮箱" prop="email">
10 10 <el-input v-model="user.email" maxlength="50" />
11 11 </el-form-item>
12 12 <el-form-item label="性别">
13 13 <el-radio-group v-model="user.sex">
14   - <el-radio label="0">男</el-radio>
15   - <el-radio label="1">女</el-radio>
  14 + <el-radio :label="1">男</el-radio>
  15 + <el-radio :label="2">女</el-radio>
16 16 </el-radio-group>
17 17 </el-form-item>
18 18 <el-form-item>
... ... @@ -35,7 +35,7 @@ export default {
35 35 return {
36 36 // 表单校验
37 37 rules: {
38   - nickName: [
  38 + nickname: [
39 39 { required: true, message: "用户昵称不能为空", trigger: "blur" }
40 40 ],
41 41 email: [
... ... @@ -46,7 +46,7 @@ export default {
46 46 trigger: ["blur", "change"]
47 47 }
48 48 ],
49   - phonenumber: [
  49 + mobile: [
50 50 { required: true, message: "手机号码不能为空", trigger: "blur" },
51 51 {
52 52 pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
... ...
sql/quartz.sql
... ... @@ -178,3 +178,11 @@ CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIG
178 178 CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
179 179  
180 180 commit;
  181 +
  182 +-- 初始化默认任务 用户 Session 超时 Job
  183 +INSERT INTO QRTZ_JOB_DETAILS VALUES ('schedulerName', 'sysUserSessionTimeoutJob', 'DEFAULT', NULL, 'cn.iocoder.dashboard.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000047400104A4F425F48414E444C45525F4E414D457400187379735573657253657373696F6E54696D656F75744A6F627800);
  184 +commit;
  185 +INSERT INTO QRTZ_TRIGGERS VALUES ('schedulerName', 'sysUserSessionTimeoutJob', 'DEFAULT', 'sysUserSessionTimeoutJob', 'DEFAULT', NULL, 1615706340000, 1615706280000, 5, 'WAITING', 'CRON', 1615706125000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000007D074000F4A4F425F52455452595F434F554E547371007E0009000000037800);
  186 +commit;
  187 +INSERT INTO QRTZ_CRON_TRIGGERS VALUES ('schedulerName', 'sysUserSessionTimeoutJob', 'DEFAULT', '0 * * * * ? *', 'Asia/Shanghai');
  188 +commit;
... ...
sql/ruoyi-vue-pro.sql
... ... @@ -11,7 +11,7 @@
11 11 Target Server Version : 50718
12 12 File Encoding : 65001
13 13  
14   - Date: 14/03/2021 13:12:25
  14 + Date: 21/03/2021 18:53:24
15 15 */
16 16  
17 17 SET NAMES utf8mb4;
... ... @@ -43,155 +43,12 @@ CREATE TABLE `inf_api_access_log` (
43 43 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
44 44 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
45 45 PRIMARY KEY (`id`) USING BTREE
46   -) ENGINE=InnoDB AUTO_INCREMENT=592 DEFAULT CHARSET=utf8mb4 COMMENT='API 访问日志表';
  46 +) ENGINE=InnoDB AUTO_INCREMENT=1318 DEFAULT CHARSET=utf8mb4 COMMENT='API 访问日志表';
47 47  
48 48 -- ----------------------------
49 49 -- Records of inf_api_access_log
50 50 -- ----------------------------
51 51 BEGIN;
52   -INSERT INTO `inf_api_access_log` VALUES (449, 'f22b9b8b-baf1-4e79-9858-c5417b12d808', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:12', '2021-03-13 13:32:12', 153, 0, '', NULL, '2021-03-13 13:32:12', NULL, '2021-03-13 13:32:12', b'0');
53   -INSERT INTO `inf_api_access_log` VALUES (450, '0a38df74-a77c-48fd-89e5-11182a2ee6a8', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:12', '2021-03-13 13:32:12', 153, 0, '', NULL, '2021-03-13 13:32:12', NULL, '2021-03-13 13:32:12', b'0');
54   -INSERT INTO `inf_api_access_log` VALUES (451, 'ee2dffcd-6423-488f-bdc5-be78f6e2576d', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:12', '2021-03-13 13:32:12', 13, 0, '', NULL, '2021-03-13 13:32:12', NULL, '2021-03-13 13:32:12', b'0');
55   -INSERT INTO `inf_api_access_log` VALUES (452, 'a71edfed-315b-4f60-9d60-f4d65eb71934', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:12', '2021-03-13 13:32:13', 23, 0, '', NULL, '2021-03-13 13:32:13', NULL, '2021-03-13 13:32:13', b'0');
56   -INSERT INTO `inf_api_access_log` VALUES (453, '71d26ef0-e0ff-4d00-9e88-fcc1586b5ed7', 1, 2, 'dashboard', 'GET', '/api/system/dept/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:13', '2021-03-13 13:32:13', 32, 0, '', NULL, '2021-03-13 13:32:13', NULL, '2021-03-13 13:32:13', b'0');
57   -INSERT INTO `inf_api_access_log` VALUES (454, '11cbd450-214c-4217-9ab3-eebfdcc668d2', 1, 2, 'dashboard', 'GET', '/api/system/post/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:13', '2021-03-13 13:32:13', 29, 0, '', NULL, '2021-03-13 13:32:13', NULL, '2021-03-13 13:32:13', b'0');
58   -INSERT INTO `inf_api_access_log` VALUES (455, '9400d6b4-16f6-4a19-ade8-0e3b788e386f', 1, 2, 'dashboard', 'GET', '/api/infra/config/get-value-by-key', '{\"query\":{\"key\":\"sys.user.initPassword\"},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:13', '2021-03-13 13:32:13', 51, 0, '', NULL, '2021-03-13 13:32:13', NULL, '2021-03-13 13:32:13', b'0');
59   -INSERT INTO `inf_api_access_log` VALUES (456, '74bd4331-3765-4e57-9207-7f461c0bf4a3', 1, 2, 'dashboard', 'GET', '/api/system/user/page', '{\"query\":{\"pageNo\":\"1\",\"pageSize\":\"10\"},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:12', '2021-03-13 13:32:13', 162, 0, '', NULL, '2021-03-13 13:32:13', NULL, '2021-03-13 13:32:13', b'0');
60   -INSERT INTO `inf_api_access_log` VALUES (457, '84877f91-7e13-4150-8cc6-1c4a2a769e85', 1, 2, 'dashboard', 'GET', '/api/infra/file/page', '{\"query\":{\"pageNo\":\"1\",\"pageSize\":\"10\"},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:24', '2021-03-13 13:32:24', 37, 0, '', NULL, '2021-03-13 13:32:24', NULL, '2021-03-13 13:32:24', b'0');
61   -INSERT INTO `inf_api_access_log` VALUES (458, 'a50536b1-94a2-419a-9c81-2ae812cd1e26', 0, 2, 'dashboard', 'GET', '/api/infra/file/get/5e8609290e915c4fa8b08e67.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:24', '2021-03-13 13:32:24', 14, 0, '', NULL, '2021-03-13 13:32:24', NULL, '2021-03-13 13:32:24', b'0');
62   -INSERT INTO `inf_api_access_log` VALUES (459, '82da8546-b43b-4290-9a8e-1e7dcd9dbd1c', 0, 2, 'dashboard', 'GET', '/api/infra/file/get/427.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:24', '2021-03-13 13:32:24', 14, 0, '', NULL, '2021-03-13 13:32:24', NULL, '2021-03-13 13:32:24', b'0');
63   -INSERT INTO `inf_api_access_log` VALUES (460, '8886554b-d6af-4538-b3fb-51584363b567', 0, 2, 'dashboard', 'GET', '/api/infra/file/get/8448cada8c714e4ab61f521c8da21990', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:32:24', '2021-03-13 13:32:24', 12, 0, '', NULL, '2021-03-13 13:32:24', NULL, '2021-03-13 13:32:24', b'0');
64   -INSERT INTO `inf_api_access_log` VALUES (461, '528742f2-6311-49d9-8c15-54e1d89730bb', 1, 2, 'dashboard', 'GET', '/api/tool/codegen/table/page', '{\"query\":{\"pageNo\":\"1\",\"pageSize\":\"10\"},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:35:08', '2021-03-13 13:35:08', 40, 0, '', NULL, '2021-03-13 13:35:08', NULL, '2021-03-13 13:35:08', b'0');
65   -INSERT INTO `inf_api_access_log` VALUES (462, 'c62d9055-d12c-4236-af7c-16753905a0dd', 1, 2, 'dashboard', 'GET', '/api/tool/codegen/preview', '{\"query\":{\"tableId\":\"33\"},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:35:12', '2021-03-13 13:35:12', 235, 0, '', NULL, '2021-03-13 13:35:12', NULL, '2021-03-13 13:35:12', b'0');
66   -INSERT INTO `inf_api_access_log` VALUES (463, '0aebc46f-2852-4300-afb6-323a97e1d45c', 1, 2, 'dashboard', 'GET', '/api/tool/codegen/detail', '{\"query\":{\"tableId\":\"33\"},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:35:48', '2021-03-13 13:35:48', 26, 0, '', NULL, '2021-03-13 13:35:48', NULL, '2021-03-13 13:35:48', b'0');
67   -INSERT INTO `inf_api_access_log` VALUES (464, 'ed36b980-e12d-474e-99fe-53962b4fcde7', 1, 2, 'dashboard', 'GET', '/api/system/dict-type/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:35:48', '2021-03-13 13:35:48', 20, 0, '', NULL, '2021-03-13 13:35:48', NULL, '2021-03-13 13:35:48', b'0');
68   -INSERT INTO `inf_api_access_log` VALUES (465, 'bac9bea3-1e07-4642-8252-469bb0c58ab8', 1, 2, 'dashboard', 'GET', '/api/system/menu/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-13 13:35:48', '2021-03-13 13:35:48', 34, 0, '', NULL, '2021-03-13 13:35:48', NULL, '2021-03-13 13:35:48', b'0');
69   -INSERT INTO `inf_api_access_log` VALUES (466, 'b8c6972c-0cd0-475a-8cbe-c25f965233ec', 0, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:32', '2021-03-14 00:31:32', 35, 0, '', NULL, '2021-03-14 00:31:32', NULL, '2021-03-14 00:31:32', b'0');
70   -INSERT INTO `inf_api_access_log` VALUES (467, '3223baf6-510b-44ac-b174-1e8f754f274e', 0, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:32', '2021-03-14 00:31:32', 35, 0, '', NULL, '2021-03-14 00:31:32', NULL, '2021-03-14 00:31:32', b'0');
71   -INSERT INTO `inf_api_access_log` VALUES (468, '43158144-4ea2-459d-a677-0431effdc434', 0, 2, 'dashboard', 'POST', '/api/logout', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:32', '2021-03-14 00:31:32', 4, 0, '', NULL, '2021-03-14 00:31:32', NULL, '2021-03-14 00:31:32', b'0');
72   -INSERT INTO `inf_api_access_log` VALUES (469, '02497e40-c460-4ba1-8b56-f0ec6d327371', 0, 2, 'dashboard', 'POST', '/api/logout', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:34', '2021-03-14 00:31:34', 2, 0, '', NULL, '2021-03-14 00:31:34', NULL, '2021-03-14 00:31:34', b'0');
73   -INSERT INTO `inf_api_access_log` VALUES (470, '3cfcc80d-150e-42f5-bace-472b52db4898', 0, 2, 'dashboard', 'GET', '/api/system/captcha/get-image', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:32', '2021-03-14 00:31:34', 2432, 0, '', NULL, '2021-03-14 00:31:34', NULL, '2021-03-14 00:31:34', b'0');
74   -INSERT INTO `inf_api_access_log` VALUES (471, 'd8d4767b-9064-4e2d-a619-08755e31758a', 0, 2, 'dashboard', 'GET', '/api/system/captcha/get-image', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:34', '2021-03-14 00:31:34', 30, 0, '', NULL, '2021-03-14 00:31:34', NULL, '2021-03-14 00:31:34', b'0');
75   -INSERT INTO `inf_api_access_log` VALUES (472, '5a937554-c758-4d39-8473-84078eb23708', 0, 2, 'dashboard', 'POST', '/api/login', '{\"query\":{},\"body\":\"{\\\"username\\\":\\\"admin\\\",\\\"password\\\":\\\"admin123\\\",\\\"code\\\":\\\"0j0pw\\\",\\\"uuid\\\":\\\"cf44d21646cb4dc4b6bd0207dec9c387\\\"}\"}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:39', '2021-03-14 00:31:39', 55, 1002000004, '验证码不正确', NULL, '2021-03-14 00:31:39', NULL, '2021-03-14 00:31:39', b'0');
76   -INSERT INTO `inf_api_access_log` VALUES (473, '0b0a61ba-3b13-4f7e-8eac-d037854afbe5', 0, 2, 'dashboard', 'GET', '/api/system/captcha/get-image', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:39', '2021-03-14 00:31:39', 15, 0, '', NULL, '2021-03-14 00:31:39', NULL, '2021-03-14 00:31:39', b'0');
77   -INSERT INTO `inf_api_access_log` VALUES (474, '3fbef0e6-da78-408f-bf58-2b09e9316285', 0, 2, 'dashboard', 'POST', '/api/login', '{\"query\":{},\"body\":\"{\\\"username\\\":\\\"admin\\\",\\\"password\\\":\\\"admin123\\\",\\\"code\\\":\\\"18nyi\\\",\\\"uuid\\\":\\\"f39a9a64154c4e72a7fa4deda5b83052\\\"}\"}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:43', '2021-03-14 00:31:43', 244, 0, '', NULL, '2021-03-14 00:31:43', NULL, '2021-03-14 00:31:43', b'0');
78   -INSERT INTO `inf_api_access_log` VALUES (475, '0d50b4d2-b545-44e2-9cfb-ea1961c58e9a', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:43', '2021-03-14 00:31:43', 29, 0, '', NULL, '2021-03-14 00:31:43', NULL, '2021-03-14 00:31:43', b'0');
79   -INSERT INTO `inf_api_access_log` VALUES (476, 'a837de17-c5bc-4223-91ac-2f9b79c536e3', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:43', '2021-03-14 00:31:43', 29, 0, '', NULL, '2021-03-14 00:31:43', NULL, '2021-03-14 00:31:43', b'0');
80   -INSERT INTO `inf_api_access_log` VALUES (477, 'e57342e2-7db6-4b7b-9ab5-55169ef7d042', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:43', '2021-03-14 00:31:43', 11, 0, '', NULL, '2021-03-14 00:31:43', NULL, '2021-03-14 00:31:43', b'0');
81   -INSERT INTO `inf_api_access_log` VALUES (478, '7bb82837-8a93-4357-a14f-f1d0856074c8', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:43', '2021-03-14 00:31:43', 4, 0, '', NULL, '2021-03-14 00:31:44', NULL, '2021-03-14 00:31:44', b'0');
82   -INSERT INTO `inf_api_access_log` VALUES (479, 'ee9e5588-1704-4c35-afca-f42007c17079', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:31:49', '2021-03-14 00:31:50', 549, 0, '', NULL, '2021-03-14 00:31:50', NULL, '2021-03-14 00:31:50', b'0');
83   -INSERT INTO `inf_api_access_log` VALUES (480, '07e9d2a7-a35d-4d46-aedf-37a899c50f77', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:32:17', '2021-03-14 00:32:17', 9, 0, '', NULL, '2021-03-14 00:32:17', NULL, '2021-03-14 00:32:17', b'0');
84   -INSERT INTO `inf_api_access_log` VALUES (481, '7b2e7d88-baa9-4b3a-bef9-97d1cb9a27c7', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:32:17', '2021-03-14 00:32:17', 17, 0, '', NULL, '2021-03-14 00:32:17', NULL, '2021-03-14 00:32:17', b'0');
85   -INSERT INTO `inf_api_access_log` VALUES (482, '0078c48a-beb9-4b34-b44e-b75ff3aa974b', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:32:17', '2021-03-14 00:32:17', 7, 0, '', NULL, '2021-03-14 00:32:17', NULL, '2021-03-14 00:32:17', b'0');
86   -INSERT INTO `inf_api_access_log` VALUES (483, '8d8541f4-7921-46da-9804-3922ea43ccab', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:32:18', '2021-03-14 00:32:18', 4, 0, '', NULL, '2021-03-14 00:32:18', NULL, '2021-03-14 00:32:18', b'0');
87   -INSERT INTO `inf_api_access_log` VALUES (484, '442c170e-7eb8-43a7-aad4-7cd10a75f64a', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:32:18', '2021-03-14 00:32:18', 132, 0, '', NULL, '2021-03-14 00:32:18', NULL, '2021-03-14 00:32:18', b'0');
88   -INSERT INTO `inf_api_access_log` VALUES (485, 'b3d0f1e8-e31e-4611-9463-615adca3a89e', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:15', '2021-03-14 00:34:15', 9, 0, '', NULL, '2021-03-14 00:34:15', NULL, '2021-03-14 00:34:15', b'0');
89   -INSERT INTO `inf_api_access_log` VALUES (486, '12040d3b-c59c-4727-b646-a9633a71a9bc', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:15', '2021-03-14 00:34:15', 14, 0, '', NULL, '2021-03-14 00:34:15', NULL, '2021-03-14 00:34:15', b'0');
90   -INSERT INTO `inf_api_access_log` VALUES (487, 'df248447-6cf7-4cca-be03-dd98330fbafe', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:15', '2021-03-14 00:34:15', 6, 0, '', NULL, '2021-03-14 00:34:15', NULL, '2021-03-14 00:34:15', b'0');
91   -INSERT INTO `inf_api_access_log` VALUES (488, '243764af-294c-47e5-aedc-529c9939a37e', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:16', '2021-03-14 00:34:16', 6, 0, '', NULL, '2021-03-14 00:34:16', NULL, '2021-03-14 00:34:16', b'0');
92   -INSERT INTO `inf_api_access_log` VALUES (489, '737d22fc-3d3d-4104-919a-8cec3ac5b837', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:16', '2021-03-14 00:34:16', 215, 0, '', NULL, '2021-03-14 00:34:16', NULL, '2021-03-14 00:34:16', b'0');
93   -INSERT INTO `inf_api_access_log` VALUES (490, '33d35537-8a07-4197-8930-e78d351f393f', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:57', '2021-03-14 00:34:57', 8, 0, '', NULL, '2021-03-14 00:34:57', NULL, '2021-03-14 00:34:57', b'0');
94   -INSERT INTO `inf_api_access_log` VALUES (491, '28c0cccd-0130-476b-89c6-f601f7b8b445', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:57', '2021-03-14 00:34:57', 16, 0, '', NULL, '2021-03-14 00:34:57', NULL, '2021-03-14 00:34:57', b'0');
95   -INSERT INTO `inf_api_access_log` VALUES (492, 'c649f830-e6b1-41db-9bdb-94bb5a7b8167', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:57', '2021-03-14 00:34:57', 4, 0, '', NULL, '2021-03-14 00:34:57', NULL, '2021-03-14 00:34:57', b'0');
96   -INSERT INTO `inf_api_access_log` VALUES (493, 'b66c63cf-3d74-4a74-acd6-2cd806062b62', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:57', '2021-03-14 00:34:57', 4, 0, '', NULL, '2021-03-14 00:34:57', NULL, '2021-03-14 00:34:57', b'0');
97   -INSERT INTO `inf_api_access_log` VALUES (494, '2d6d575f-c380-47c1-acc6-20989092060c', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:34:57', '2021-03-14 00:34:58', 225, 0, '', NULL, '2021-03-14 00:34:58', NULL, '2021-03-14 00:34:58', b'0');
98   -INSERT INTO `inf_api_access_log` VALUES (495, 'ffd49974-e6b7-425d-98cd-be851e38815e', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:35:04', '2021-03-14 00:35:04', 121, 0, '', NULL, '2021-03-14 00:35:04', NULL, '2021-03-14 00:35:04', b'0');
99   -INSERT INTO `inf_api_access_log` VALUES (496, '5292d11b-6981-49f5-9879-94f30cf93db4', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:35:10', '2021-03-14 00:35:10', 10, 0, '', NULL, '2021-03-14 00:35:10', NULL, '2021-03-14 00:35:10', b'0');
100   -INSERT INTO `inf_api_access_log` VALUES (497, '9e4816d7-b70a-46f5-afc5-f6fc7061fee3', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:35:10', '2021-03-14 00:35:10', 17, 0, '', NULL, '2021-03-14 00:35:10', NULL, '2021-03-14 00:35:10', b'0');
101   -INSERT INTO `inf_api_access_log` VALUES (498, 'df961948-f3f7-4fad-8d77-944820152305', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:35:10', '2021-03-14 00:35:10', 4, 0, '', NULL, '2021-03-14 00:35:10', NULL, '2021-03-14 00:35:10', b'0');
102   -INSERT INTO `inf_api_access_log` VALUES (499, 'dd5c28a0-76e1-47e6-bac7-293001d91f40', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:35:11', '2021-03-14 00:35:11', 4, 0, '', NULL, '2021-03-14 00:35:11', NULL, '2021-03-14 00:35:11', b'0');
103   -INSERT INTO `inf_api_access_log` VALUES (500, 'e15bf39c-80c8-432e-96fb-46543a892471', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:35:11', '2021-03-14 00:35:11', 184, 0, '', NULL, '2021-03-14 00:35:11', NULL, '2021-03-14 00:35:11', b'0');
104   -INSERT INTO `inf_api_access_log` VALUES (501, '564d7339-60f6-4c4e-8989-ef984a7dbe9c', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:35:16', '2021-03-14 00:35:16', 112, 0, '', NULL, '2021-03-14 00:35:16', NULL, '2021-03-14 00:35:16', b'0');
105   -INSERT INTO `inf_api_access_log` VALUES (502, '5d9562a7-ee32-4bd0-95b9-465685c4b037', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:35:31', '2021-03-14 00:35:31', 109, 0, '', NULL, '2021-03-14 00:35:31', NULL, '2021-03-14 00:35:31', b'0');
106   -INSERT INTO `inf_api_access_log` VALUES (503, '5eb9207f-4093-43af-aac4-8652d3088e7a', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:35:35', '2021-03-14 00:35:35', 102, 0, '', NULL, '2021-03-14 00:35:35', NULL, '2021-03-14 00:35:35', b'0');
107   -INSERT INTO `inf_api_access_log` VALUES (504, '0d7ec6da-0fb4-48c0-ac0e-d07d147970be', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:45:11', '2021-03-14 00:45:11', 21, 0, '', NULL, '2021-03-14 00:45:11', NULL, '2021-03-14 00:45:11', b'0');
108   -INSERT INTO `inf_api_access_log` VALUES (505, 'a9553f2b-c43b-4c65-a8bd-f62b462cd2ff', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:45:11', '2021-03-14 00:45:11', 30, 0, '', NULL, '2021-03-14 00:45:11', NULL, '2021-03-14 00:45:11', b'0');
109   -INSERT INTO `inf_api_access_log` VALUES (506, '850e7e9a-41fa-4321-a75b-ea74b3e0929e', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:45:11', '2021-03-14 00:45:11', 5, 0, '', NULL, '2021-03-14 00:45:11', NULL, '2021-03-14 00:45:11', b'0');
110   -INSERT INTO `inf_api_access_log` VALUES (507, 'd7e021f2-c943-4dd8-a47a-aabb7f0d4b98', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:45:12', '2021-03-14 00:45:12', 4, 0, '', NULL, '2021-03-14 00:45:12', NULL, '2021-03-14 00:45:12', b'0');
111   -INSERT INTO `inf_api_access_log` VALUES (508, '2a06b244-12b5-4ede-a1dc-487185515454', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:45:12', '2021-03-14 00:45:12', 141, 0, '', NULL, '2021-03-14 00:45:12', NULL, '2021-03-14 00:45:12', b'0');
112   -INSERT INTO `inf_api_access_log` VALUES (509, '1c8eeb85-895d-44b0-8872-aa80518c4644', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:22', '2021-03-14 00:46:22', 10, 0, '', NULL, '2021-03-14 00:46:22', NULL, '2021-03-14 00:46:22', b'0');
113   -INSERT INTO `inf_api_access_log` VALUES (510, '28d8923f-30f2-476e-9747-d6d8f5db464e', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:22', '2021-03-14 00:46:22', 6, 0, '', NULL, '2021-03-14 00:46:22', NULL, '2021-03-14 00:46:22', b'0');
114   -INSERT INTO `inf_api_access_log` VALUES (511, 'e16652a5-9eab-4717-945c-dfd157f71f3d', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:22', '2021-03-14 00:46:22', 4, 0, '', NULL, '2021-03-14 00:46:22', NULL, '2021-03-14 00:46:22', b'0');
115   -INSERT INTO `inf_api_access_log` VALUES (512, 'f8ebcae7-0292-4d54-b759-91dd0a82be05', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:23', '2021-03-14 00:46:23', 3, 0, '', NULL, '2021-03-14 00:46:23', NULL, '2021-03-14 00:46:23', b'0');
116   -INSERT INTO `inf_api_access_log` VALUES (513, 'a9f375d3-8da8-4459-9a22-74aad944ce43', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:23', '2021-03-14 00:46:23', 121, 0, '', NULL, '2021-03-14 00:46:23', NULL, '2021-03-14 00:46:23', b'0');
117   -INSERT INTO `inf_api_access_log` VALUES (514, '77043f29-8918-4d07-a7f3-30dff623607d', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:29', '2021-03-14 00:46:29', 127, 0, '', NULL, '2021-03-14 00:46:29', NULL, '2021-03-14 00:46:29', b'0');
118   -INSERT INTO `inf_api_access_log` VALUES (515, '8dfc5fe3-1f31-4a6a-8539-0ae3e599180b', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:35', '2021-03-14 00:46:35', 8, 0, '', NULL, '2021-03-14 00:46:35', NULL, '2021-03-14 00:46:35', b'0');
119   -INSERT INTO `inf_api_access_log` VALUES (516, '2fe23869-fbe2-463e-8b60-6c31b9ba4216', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:35', '2021-03-14 00:46:35', 13, 0, '', NULL, '2021-03-14 00:46:35', NULL, '2021-03-14 00:46:35', b'0');
120   -INSERT INTO `inf_api_access_log` VALUES (517, 'a1f78480-d3ee-4d66-aa2f-9c9ae8a410c6', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:35', '2021-03-14 00:46:35', 5, 0, '', NULL, '2021-03-14 00:46:35', NULL, '2021-03-14 00:46:35', b'0');
121   -INSERT INTO `inf_api_access_log` VALUES (518, '960426c8-a155-4000-8021-97463dae5f63', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:36', '2021-03-14 00:46:36', 4, 0, '', NULL, '2021-03-14 00:46:36', NULL, '2021-03-14 00:46:36', b'0');
122   -INSERT INTO `inf_api_access_log` VALUES (519, '6f074c2e-a508-4f62-87cb-af209d4bde98', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:36', '2021-03-14 00:46:36', 143, 0, '', NULL, '2021-03-14 00:46:36', NULL, '2021-03-14 00:46:36', b'0');
123   -INSERT INTO `inf_api_access_log` VALUES (520, 'efab06d5-343f-46ba-9e4f-9ba76b91b571', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:45', '2021-03-14 00:46:45', 5, 0, '', NULL, '2021-03-14 00:46:45', NULL, '2021-03-14 00:46:45', b'0');
124   -INSERT INTO `inf_api_access_log` VALUES (521, 'd1ee71ee-a30f-4123-8db3-7c3d885a6b50', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:45', '2021-03-14 00:46:45', 10, 0, '', NULL, '2021-03-14 00:46:45', NULL, '2021-03-14 00:46:45', b'0');
125   -INSERT INTO `inf_api_access_log` VALUES (522, 'e0d9c8f7-d12b-4791-8cd4-a6b8dbebc2d4', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:45', '2021-03-14 00:46:45', 5, 0, '', NULL, '2021-03-14 00:46:45', NULL, '2021-03-14 00:46:45', b'0');
126   -INSERT INTO `inf_api_access_log` VALUES (523, 'f17372a7-b9e1-43ce-a89a-9aef741fe679', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:46', '2021-03-14 00:46:46', 3, 0, '', NULL, '2021-03-14 00:46:46', NULL, '2021-03-14 00:46:46', b'0');
127   -INSERT INTO `inf_api_access_log` VALUES (524, 'e3b7d7fb-1c63-4623-aa7a-eb6931e703b3', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:46:46', '2021-03-14 00:46:46', 92, 0, '', NULL, '2021-03-14 00:46:46', NULL, '2021-03-14 00:46:46', b'0');
128   -INSERT INTO `inf_api_access_log` VALUES (525, 'd8e688e0-443c-4845-a666-fed7a77d5638', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:47:24', '2021-03-14 00:47:24', 118, 0, '', NULL, '2021-03-14 00:47:24', NULL, '2021-03-14 00:47:24', b'0');
129   -INSERT INTO `inf_api_access_log` VALUES (526, 'daa5a590-346c-4101-bfdf-c366e43e0714', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:47:25', '2021-03-14 00:47:25', 12, 0, '', NULL, '2021-03-14 00:47:25', NULL, '2021-03-14 00:47:25', b'0');
130   -INSERT INTO `inf_api_access_log` VALUES (527, 'dd28ff77-9d5b-4c34-a8d1-4fa6dcd68f68', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:47:25', '2021-03-14 00:47:25', 8, 0, '', NULL, '2021-03-14 00:47:25', NULL, '2021-03-14 00:47:25', b'0');
131   -INSERT INTO `inf_api_access_log` VALUES (528, '800bc255-e685-40a7-a623-ef1fc8087663', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:47:25', '2021-03-14 00:47:25', 6, 0, '', NULL, '2021-03-14 00:47:25', NULL, '2021-03-14 00:47:25', b'0');
132   -INSERT INTO `inf_api_access_log` VALUES (529, 'f3b59dce-a8d0-4b21-84b7-697498e19b63', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:47:26', '2021-03-14 00:47:26', 4, 0, '', NULL, '2021-03-14 00:47:26', NULL, '2021-03-14 00:47:26', b'0');
133   -INSERT INTO `inf_api_access_log` VALUES (530, 'ededd21f-77ef-4131-8c68-88815f9ca0bf', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:47:26', '2021-03-14 00:47:26', 121, 0, '', NULL, '2021-03-14 00:47:26', NULL, '2021-03-14 00:47:26', b'0');
134   -INSERT INTO `inf_api_access_log` VALUES (531, '17133597-d007-437b-9d5f-b04a6a412d89', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:47:28', '2021-03-14 00:47:28', 106, 0, '', NULL, '2021-03-14 00:47:28', NULL, '2021-03-14 00:47:28', b'0');
135   -INSERT INTO `inf_api_access_log` VALUES (532, '71daef1d-151c-48f9-9258-76210c22ecb2', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:48:56', '2021-03-14 00:48:56', 11, 0, '', NULL, '2021-03-14 00:48:56', NULL, '2021-03-14 00:48:56', b'0');
136   -INSERT INTO `inf_api_access_log` VALUES (533, '63d267ee-c6be-424b-a1d7-c75ef9135beb', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:48:56', '2021-03-14 00:48:56', 14, 0, '', NULL, '2021-03-14 00:48:56', NULL, '2021-03-14 00:48:56', b'0');
137   -INSERT INTO `inf_api_access_log` VALUES (534, '8b4be6d4-c505-4645-a46d-d74ea13b1221', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:48:56', '2021-03-14 00:48:56', 8, 0, '', NULL, '2021-03-14 00:48:56', NULL, '2021-03-14 00:48:56', b'0');
138   -INSERT INTO `inf_api_access_log` VALUES (535, '0d3fbb85-6d30-4e5f-a05b-c1939aca2f6b', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:48:56', '2021-03-14 00:48:56', 4, 0, '', NULL, '2021-03-14 00:48:56', NULL, '2021-03-14 00:48:56', b'0');
139   -INSERT INTO `inf_api_access_log` VALUES (536, '4594a8c9-95d2-4065-a5ca-6bbabb68a118', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:48:56', '2021-03-14 00:48:57', 121, 0, '', NULL, '2021-03-14 00:48:57', NULL, '2021-03-14 00:48:57', b'0');
140   -INSERT INTO `inf_api_access_log` VALUES (537, '6ebbcd89-38c1-4149-9238-1fa88ead86cf', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:49:40', '2021-03-14 00:49:40', 9, 0, '', NULL, '2021-03-14 00:49:40', NULL, '2021-03-14 00:49:40', b'0');
141   -INSERT INTO `inf_api_access_log` VALUES (538, '62931059-c92b-44d8-85fb-96ab71763ad6', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:49:40', '2021-03-14 00:49:40', 11, 0, '', NULL, '2021-03-14 00:49:40', NULL, '2021-03-14 00:49:40', b'0');
142   -INSERT INTO `inf_api_access_log` VALUES (539, '4f3a27de-2994-451d-b33c-048e6479aebb', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:49:40', '2021-03-14 00:49:40', 5, 0, '', NULL, '2021-03-14 00:49:40', NULL, '2021-03-14 00:49:40', b'0');
143   -INSERT INTO `inf_api_access_log` VALUES (540, 'f1ccb45d-ec2d-4cc5-845a-4e120d2f2aa5', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:49:41', '2021-03-14 00:49:41', 4, 0, '', NULL, '2021-03-14 00:49:41', NULL, '2021-03-14 00:49:41', b'0');
144   -INSERT INTO `inf_api_access_log` VALUES (541, '26359dfe-1c16-459c-a84e-24cb03e4c065', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:49:41', '2021-03-14 00:49:41', 139, 0, '', NULL, '2021-03-14 00:49:41', NULL, '2021-03-14 00:49:41', b'0');
145   -INSERT INTO `inf_api_access_log` VALUES (542, '7b669973-5430-4655-8800-64c0ac83b1a3', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:50:20', '2021-03-14 00:50:20', 8, 0, '', NULL, '2021-03-14 00:50:20', NULL, '2021-03-14 00:50:20', b'0');
146   -INSERT INTO `inf_api_access_log` VALUES (543, 'd24724d2-318a-4876-b706-58aea1ef7dc5', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:50:20', '2021-03-14 00:50:20', 8, 0, '', NULL, '2021-03-14 00:50:20', NULL, '2021-03-14 00:50:20', b'0');
147   -INSERT INTO `inf_api_access_log` VALUES (544, 'cd024db3-fb5e-40ff-a574-674361441bc2', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:50:20', '2021-03-14 00:50:20', 4, 0, '', NULL, '2021-03-14 00:50:20', NULL, '2021-03-14 00:50:20', b'0');
148   -INSERT INTO `inf_api_access_log` VALUES (545, 'd2eec64e-7a8c-498d-89fc-42e958cb8408', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:50:21', '2021-03-14 00:50:21', 4, 0, '', NULL, '2021-03-14 00:50:21', NULL, '2021-03-14 00:50:21', b'0');
149   -INSERT INTO `inf_api_access_log` VALUES (546, '28859271-d60e-4644-a600-a5b77538e5c4', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:50:21', '2021-03-14 00:50:21', 97, 0, '', NULL, '2021-03-14 00:50:21', NULL, '2021-03-14 00:50:21', b'0');
150   -INSERT INTO `inf_api_access_log` VALUES (547, '571b1d57-465a-43f2-955b-fa63d6b0181e', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:00', '2021-03-14 00:51:00', 83, 0, '', NULL, '2021-03-14 00:51:00', NULL, '2021-03-14 00:51:00', b'0');
151   -INSERT INTO `inf_api_access_log` VALUES (548, 'b1afa1bd-bf40-4c69-a1df-bb214853a70c', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:02', '2021-03-14 00:51:02', 7, 0, '', NULL, '2021-03-14 00:51:02', NULL, '2021-03-14 00:51:02', b'0');
152   -INSERT INTO `inf_api_access_log` VALUES (549, 'a7a60980-6a8b-4624-abb9-c2f8d22dbdc9', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:02', '2021-03-14 00:51:02', 8, 0, '', NULL, '2021-03-14 00:51:02', NULL, '2021-03-14 00:51:02', b'0');
153   -INSERT INTO `inf_api_access_log` VALUES (550, '14690b9d-ae7b-493d-994c-68b9c0b3ebf6', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:02', '2021-03-14 00:51:02', 11, 0, '', NULL, '2021-03-14 00:51:02', NULL, '2021-03-14 00:51:02', b'0');
154   -INSERT INTO `inf_api_access_log` VALUES (551, 'd2851315-11ee-4762-af1a-64a94c07678d', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:03', '2021-03-14 00:51:03', 3, 0, '', NULL, '2021-03-14 00:51:03', NULL, '2021-03-14 00:51:03', b'0');
155   -INSERT INTO `inf_api_access_log` VALUES (552, 'a9c16cb6-5549-4041-a062-4dce54466dce', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:03', '2021-03-14 00:51:03', 107, 0, '', NULL, '2021-03-14 00:51:03', NULL, '2021-03-14 00:51:03', b'0');
156   -INSERT INTO `inf_api_access_log` VALUES (553, 'cbaea7cc-33cf-4422-b572-be0ea36bb0ae', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:04', '2021-03-14 00:51:04', 103, 0, '', NULL, '2021-03-14 00:51:04', NULL, '2021-03-14 00:51:04', b'0');
157   -INSERT INTO `inf_api_access_log` VALUES (554, '5c129cb2-65f4-4590-97dd-7300169190c4', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:10', '2021-03-14 00:51:10', 76, 0, '', NULL, '2021-03-14 00:51:10', NULL, '2021-03-14 00:51:10', b'0');
158   -INSERT INTO `inf_api_access_log` VALUES (555, '4bc3e1e7-ed14-4ccb-8c55-72d6de7918ca', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:31', '2021-03-14 00:51:31', 82, 0, '', NULL, '2021-03-14 00:51:31', NULL, '2021-03-14 00:51:31', b'0');
159   -INSERT INTO `inf_api_access_log` VALUES (556, 'ee785bdd-bc34-4f32-80fc-4640b82b9ac0', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:51:51', '2021-03-14 00:51:51', 84, 0, '', NULL, '2021-03-14 00:51:51', NULL, '2021-03-14 00:51:51', b'0');
160   -INSERT INTO `inf_api_access_log` VALUES (557, '7e0599b4-40a0-4483-a894-3aac27433b3c', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:13', '2021-03-14 00:55:13', 18, 0, '', NULL, '2021-03-14 00:55:13', NULL, '2021-03-14 00:55:13', b'0');
161   -INSERT INTO `inf_api_access_log` VALUES (558, '9ba6d255-fc1f-4404-928f-7043db300fd4', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:13', '2021-03-14 00:55:13', 16, 0, '', NULL, '2021-03-14 00:55:13', NULL, '2021-03-14 00:55:13', b'0');
162   -INSERT INTO `inf_api_access_log` VALUES (559, 'e6666077-1657-4379-9450-d3d85d4c1258', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:13', '2021-03-14 00:55:13', 3, 0, '', NULL, '2021-03-14 00:55:13', NULL, '2021-03-14 00:55:13', b'0');
163   -INSERT INTO `inf_api_access_log` VALUES (560, 'b25155cf-2cd8-4ce0-87f4-71e070df815b', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:13', '2021-03-14 00:55:13', 3, 0, '', NULL, '2021-03-14 00:55:13', NULL, '2021-03-14 00:55:13', b'0');
164   -INSERT INTO `inf_api_access_log` VALUES (561, '2ccd65ca-69b0-4057-abd9-b1a966651fc5', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:13', '2021-03-14 00:55:13', 117, 0, '', NULL, '2021-03-14 00:55:13', NULL, '2021-03-14 00:55:13', b'0');
165   -INSERT INTO `inf_api_access_log` VALUES (562, '587de0ff-1252-4205-bd17-a803b74ddb2e', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:16', '2021-03-14 00:55:16', 8, 0, '', NULL, '2021-03-14 00:55:16', NULL, '2021-03-14 00:55:16', b'0');
166   -INSERT INTO `inf_api_access_log` VALUES (563, 'ee876570-68aa-4ded-ba7d-2165747211a5', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:16', '2021-03-14 00:55:16', 7, 0, '', NULL, '2021-03-14 00:55:16', NULL, '2021-03-14 00:55:16', b'0');
167   -INSERT INTO `inf_api_access_log` VALUES (564, '0369c181-f2c3-4d3b-8929-e6363adb8b2e', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:16', '2021-03-14 00:55:16', 4, 0, '', NULL, '2021-03-14 00:55:16', NULL, '2021-03-14 00:55:16', b'0');
168   -INSERT INTO `inf_api_access_log` VALUES (565, '2871031c-fb9c-401f-b877-37ec9ab3f4ad', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:16', '2021-03-14 00:55:16', 3, 0, '', NULL, '2021-03-14 00:55:16', NULL, '2021-03-14 00:55:16', b'0');
169   -INSERT INTO `inf_api_access_log` VALUES (566, '3bd22cb5-6ace-487d-82e6-50697644c317', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:16', '2021-03-14 00:55:16', 101, 0, '', NULL, '2021-03-14 00:55:16', NULL, '2021-03-14 00:55:16', b'0');
170   -INSERT INTO `inf_api_access_log` VALUES (567, '3a57f69f-4606-436c-9735-680089207fc5', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:30', '2021-03-14 00:55:30', 10, 0, '', NULL, '2021-03-14 00:55:30', NULL, '2021-03-14 00:55:30', b'0');
171   -INSERT INTO `inf_api_access_log` VALUES (568, '22f1460b-2326-47fd-9cd0-ea6df3a44914', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:30', '2021-03-14 00:55:30', 7, 0, '', NULL, '2021-03-14 00:55:30', NULL, '2021-03-14 00:55:30', b'0');
172   -INSERT INTO `inf_api_access_log` VALUES (569, 'c60675ce-fa92-4a7e-9cc9-d87ce3b3262a', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:30', '2021-03-14 00:55:30', 3, 0, '', NULL, '2021-03-14 00:55:30', NULL, '2021-03-14 00:55:30', b'0');
173   -INSERT INTO `inf_api_access_log` VALUES (570, 'a8b1a03e-5dad-4600-8e11-6d843568e408', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:31', '2021-03-14 00:55:31', 3, 0, '', NULL, '2021-03-14 00:55:31', NULL, '2021-03-14 00:55:31', b'0');
174   -INSERT INTO `inf_api_access_log` VALUES (571, 'c32df32a-7e50-48d8-8063-8b3a6d25f923', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:31', '2021-03-14 00:55:31', 104, 0, '', NULL, '2021-03-14 00:55:31', NULL, '2021-03-14 00:55:31', b'0');
175   -INSERT INTO `inf_api_access_log` VALUES (572, '752e6282-961b-4f02-901e-9433e440c5fa', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-word', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:32', '2021-03-14 00:55:32', 145, 0, '', NULL, '2021-03-14 00:55:32', NULL, '2021-03-14 00:55:32', b'0');
176   -INSERT INTO `inf_api_access_log` VALUES (573, 'af6920a9-d027-428a-91ac-339bff58a5cd', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:55:54', '2021-03-14 00:55:54', 89, 0, '', NULL, '2021-03-14 00:55:54', NULL, '2021-03-14 00:55:54', b'0');
177   -INSERT INTO `inf_api_access_log` VALUES (574, 'f69013a1-1ccc-48d4-b0d0-7cad81242e98', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:14', '2021-03-14 00:56:15', 89, 0, '', NULL, '2021-03-14 00:56:15', NULL, '2021-03-14 00:56:15', b'0');
178   -INSERT INTO `inf_api_access_log` VALUES (575, '57019f8e-4d4f-4e79-84d5-010e3c7cccac', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:40', '2021-03-14 00:56:40', 6, 0, '', NULL, '2021-03-14 00:56:40', NULL, '2021-03-14 00:56:40', b'0');
179   -INSERT INTO `inf_api_access_log` VALUES (576, '27da3255-4f47-4c77-b001-d44a7f12d09f', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:40', '2021-03-14 00:56:40', 8, 0, '', NULL, '2021-03-14 00:56:40', NULL, '2021-03-14 00:56:40', b'0');
180   -INSERT INTO `inf_api_access_log` VALUES (577, '58f40949-366d-4df3-8a10-ee8b88c7ac7e', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:40', '2021-03-14 00:56:40', 3, 0, '', NULL, '2021-03-14 00:56:40', NULL, '2021-03-14 00:56:40', b'0');
181   -INSERT INTO `inf_api_access_log` VALUES (578, 'b1d195de-c8ed-4001-b701-666dcfc6c4bb', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:41', '2021-03-14 00:56:41', 4, 0, '', NULL, '2021-03-14 00:56:41', NULL, '2021-03-14 00:56:41', b'0');
182   -INSERT INTO `inf_api_access_log` VALUES (579, 'b12d0c14-6251-4fad-99b7-c7a74d1e28c5', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:41', '2021-03-14 00:56:41', 183, 0, '', NULL, '2021-03-14 00:56:41', NULL, '2021-03-14 00:56:41', b'0');
183   -INSERT INTO `inf_api_access_log` VALUES (580, '05994cf8-30e3-443b-b9bd-defcee3c34b7', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:58', '2021-03-14 00:56:58', 7, 0, '', NULL, '2021-03-14 00:56:58', NULL, '2021-03-14 00:56:58', b'0');
184   -INSERT INTO `inf_api_access_log` VALUES (581, '569e9723-8f80-418d-8862-048061abd517', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:58', '2021-03-14 00:56:58', 5, 0, '', NULL, '2021-03-14 00:56:58', NULL, '2021-03-14 00:56:58', b'0');
185   -INSERT INTO `inf_api_access_log` VALUES (582, '84fc7483-7197-4652-96fe-eaef3fc1e72f', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:58', '2021-03-14 00:56:58', 3, 0, '', NULL, '2021-03-14 00:56:58', NULL, '2021-03-14 00:56:58', b'0');
186   -INSERT INTO `inf_api_access_log` VALUES (583, '022cd5b7-4b5b-48ee-ae3b-34fa5d627ff4', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:59', '2021-03-14 00:56:59', 3, 0, '', NULL, '2021-03-14 00:56:59', NULL, '2021-03-14 00:56:59', b'0');
187   -INSERT INTO `inf_api_access_log` VALUES (584, '8f76d7b3-5302-4f95-9158-45bd91c5a468', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:56:59', '2021-03-14 00:56:59', 97, 0, '', NULL, '2021-03-14 00:56:59', NULL, '2021-03-14 00:56:59', b'0');
188   -INSERT INTO `inf_api_access_log` VALUES (585, 'fb3868ea-e5f4-4e33-b1ff-277bf17d3581', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-markdown', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:57:00', '2021-03-14 00:57:00', 111, 0, '', NULL, '2021-03-14 00:57:00', NULL, '2021-03-14 00:57:00', b'0');
189   -INSERT INTO `inf_api_access_log` VALUES (586, '3ffb100a-5e77-4a9f-b2d8-6bf4e2904451', 1, 2, 'dashboard', 'GET', '/api/system/dict-data/list-all-simple', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:57:23', '2021-03-14 00:57:23', 13, 0, '', NULL, '2021-03-14 00:57:23', NULL, '2021-03-14 00:57:23', b'0');
190   -INSERT INTO `inf_api_access_log` VALUES (587, 'cdc2e1f8-35b2-41b1-b3ba-f9ec1fa1e6d0', 1, 2, 'dashboard', 'GET', '/api/get-permission-info', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:57:23', '2021-03-14 00:57:23', 7, 0, '', NULL, '2021-03-14 00:57:23', NULL, '2021-03-14 00:57:23', b'0');
191   -INSERT INTO `inf_api_access_log` VALUES (588, 'b9815e22-5c15-429e-800c-736f52fe99a9', 1, 2, 'dashboard', 'GET', '/api/list-menus', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:57:23', '2021-03-14 00:57:23', 4, 0, '', NULL, '2021-03-14 00:57:23', NULL, '2021-03-14 00:57:23', b'0');
192   -INSERT INTO `inf_api_access_log` VALUES (589, '8da35ff9-526e-4b76-a486-c1c27c744493', 0, 2, 'dashboard', 'GET', '/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:57:23', '2021-03-14 00:57:23', 3, 0, '', NULL, '2021-03-14 00:57:23', NULL, '2021-03-14 00:57:23', b'0');
193   -INSERT INTO `inf_api_access_log` VALUES (590, '604ae467-e8a2-48cf-b19f-0c7d79aa0c9c', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-html', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:57:23', '2021-03-14 00:57:23', 100, 0, '', NULL, '2021-03-14 00:57:23', NULL, '2021-03-14 00:57:23', b'0');
194   -INSERT INTO `inf_api_access_log` VALUES (591, 'eba82a07-fcde-4566-a8db-cd4f55c42d4a', 1, 2, 'dashboard', 'GET', '/api/infra/db-doc/export-markdown', '{\"query\":{},\"body\":null}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', '2021-03-14 00:57:25', '2021-03-14 00:57:25', 87, 0, '', NULL, '2021-03-14 00:57:25', NULL, '2021-03-14 00:57:25', b'0');
195 52 COMMIT;
196 53  
197 54 -- ----------------------------
... ... @@ -344,162 +201,12 @@ CREATE TABLE `inf_job_log` (
344 201 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
345 202 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
346 203 PRIMARY KEY (`id`) USING BTREE
347   -) ENGINE=InnoDB AUTO_INCREMENT=435 DEFAULT CHARSET=utf8mb4 COMMENT='定时任务日志表';
  204 +) ENGINE=InnoDB AUTO_INCREMENT=627 DEFAULT CHARSET=utf8mb4 COMMENT='定时任务日志表';
348 205  
349 206 -- ----------------------------
350 207 -- Records of inf_job_log
351 208 -- ----------------------------
352 209 BEGIN;
353   -INSERT INTO `inf_job_log` VALUES (285, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:31:44', '2021-03-13 13:31:44', 63, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:31:44', NULL, '2021-03-13 13:31:44', b'0');
354   -INSERT INTO `inf_job_log` VALUES (286, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:32:00', '2021-03-13 13:32:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:32:00', NULL, '2021-03-13 13:32:00', b'0');
355   -INSERT INTO `inf_job_log` VALUES (287, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:33:00', '2021-03-13 13:33:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:33:00', NULL, '2021-03-13 13:33:00', b'0');
356   -INSERT INTO `inf_job_log` VALUES (288, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:34:00', '2021-03-13 13:34:00', 9, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:34:00', NULL, '2021-03-13 13:34:00', b'0');
357   -INSERT INTO `inf_job_log` VALUES (289, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:35:00', '2021-03-13 13:35:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:35:00', NULL, '2021-03-13 13:35:00', b'0');
358   -INSERT INTO `inf_job_log` VALUES (290, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:36:00', '2021-03-13 13:36:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:36:00', NULL, '2021-03-13 13:36:00', b'0');
359   -INSERT INTO `inf_job_log` VALUES (291, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:37:00', '2021-03-13 13:37:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:37:00', NULL, '2021-03-13 13:37:00', b'0');
360   -INSERT INTO `inf_job_log` VALUES (292, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:38:00', '2021-03-13 13:38:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:38:00', NULL, '2021-03-13 13:38:00', b'0');
361   -INSERT INTO `inf_job_log` VALUES (293, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:39:00', '2021-03-13 13:39:00', 9, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:39:00', NULL, '2021-03-13 13:39:00', b'0');
362   -INSERT INTO `inf_job_log` VALUES (294, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:40:00', '2021-03-13 13:40:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:40:00', NULL, '2021-03-13 13:40:00', b'0');
363   -INSERT INTO `inf_job_log` VALUES (295, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-13 13:41:00', '2021-03-13 13:41:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-13 13:41:00', NULL, '2021-03-13 13:41:00', b'0');
364   -INSERT INTO `inf_job_log` VALUES (296, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:31:13', '2021-03-14 00:31:13', 133, 1, '移除在线会话数量为 1 个', NULL, '2021-03-14 00:31:13', NULL, '2021-03-14 00:31:13', b'0');
365   -INSERT INTO `inf_job_log` VALUES (297, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:32:00', '2021-03-14 00:32:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:32:00', NULL, '2021-03-14 00:32:00', b'0');
366   -INSERT INTO `inf_job_log` VALUES (298, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:33:00', '2021-03-14 00:33:00', 14, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:33:00', NULL, '2021-03-14 00:33:00', b'0');
367   -INSERT INTO `inf_job_log` VALUES (299, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:34:00', '2021-03-14 00:34:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:34:00', NULL, '2021-03-14 00:34:00', b'0');
368   -INSERT INTO `inf_job_log` VALUES (300, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:35:00', '2021-03-14 00:35:00', 11, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:35:00', NULL, '2021-03-14 00:35:00', b'0');
369   -INSERT INTO `inf_job_log` VALUES (301, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:36:00', '2021-03-14 00:36:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:36:00', NULL, '2021-03-14 00:36:00', b'0');
370   -INSERT INTO `inf_job_log` VALUES (302, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:37:00', '2021-03-14 00:37:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:37:00', NULL, '2021-03-14 00:37:00', b'0');
371   -INSERT INTO `inf_job_log` VALUES (303, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:38:00', '2021-03-14 00:38:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:38:00', NULL, '2021-03-14 00:38:00', b'0');
372   -INSERT INTO `inf_job_log` VALUES (304, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:39:00', '2021-03-14 00:39:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:39:00', NULL, '2021-03-14 00:39:00', b'0');
373   -INSERT INTO `inf_job_log` VALUES (305, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:40:00', '2021-03-14 00:40:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:40:00', NULL, '2021-03-14 00:40:00', b'0');
374   -INSERT INTO `inf_job_log` VALUES (306, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:41:00', '2021-03-14 00:41:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:41:00', NULL, '2021-03-14 00:41:00', b'0');
375   -INSERT INTO `inf_job_log` VALUES (307, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:42:00', '2021-03-14 00:42:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:42:00', NULL, '2021-03-14 00:42:00', b'0');
376   -INSERT INTO `inf_job_log` VALUES (308, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:43:00', '2021-03-14 00:43:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:43:00', NULL, '2021-03-14 00:43:00', b'0');
377   -INSERT INTO `inf_job_log` VALUES (309, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:44:00', '2021-03-14 00:44:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:44:00', NULL, '2021-03-14 00:44:00', b'0');
378   -INSERT INTO `inf_job_log` VALUES (310, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:45:00', '2021-03-14 00:45:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:45:00', NULL, '2021-03-14 00:45:00', b'0');
379   -INSERT INTO `inf_job_log` VALUES (311, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:46:00', '2021-03-14 00:46:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:46:00', NULL, '2021-03-14 00:46:00', b'0');
380   -INSERT INTO `inf_job_log` VALUES (312, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:47:00', '2021-03-14 00:47:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:47:00', NULL, '2021-03-14 00:47:00', b'0');
381   -INSERT INTO `inf_job_log` VALUES (313, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:48:00', '2021-03-14 00:48:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:48:00', NULL, '2021-03-14 00:48:00', b'0');
382   -INSERT INTO `inf_job_log` VALUES (314, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:49:00', '2021-03-14 00:49:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:49:00', NULL, '2021-03-14 00:49:00', b'0');
383   -INSERT INTO `inf_job_log` VALUES (315, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:50:00', '2021-03-14 00:50:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:50:00', NULL, '2021-03-14 00:50:00', b'0');
384   -INSERT INTO `inf_job_log` VALUES (316, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:51:00', '2021-03-14 00:51:00', 9, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:51:00', NULL, '2021-03-14 00:51:00', b'0');
385   -INSERT INTO `inf_job_log` VALUES (317, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:52:00', '2021-03-14 00:52:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:52:00', NULL, '2021-03-14 00:52:00', b'0');
386   -INSERT INTO `inf_job_log` VALUES (318, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:53:00', '2021-03-14 00:53:00', 8, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:53:00', NULL, '2021-03-14 00:53:00', b'0');
387   -INSERT INTO `inf_job_log` VALUES (319, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:54:00', '2021-03-14 00:54:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:54:00', NULL, '2021-03-14 00:54:00', b'0');
388   -INSERT INTO `inf_job_log` VALUES (320, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:55:00', '2021-03-14 00:55:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:55:00', NULL, '2021-03-14 00:55:00', b'0');
389   -INSERT INTO `inf_job_log` VALUES (321, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:56:00', '2021-03-14 00:56:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:56:00', NULL, '2021-03-14 00:56:00', b'0');
390   -INSERT INTO `inf_job_log` VALUES (322, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:57:00', '2021-03-14 00:57:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:57:00', NULL, '2021-03-14 00:57:00', b'0');
391   -INSERT INTO `inf_job_log` VALUES (323, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:58:00', '2021-03-14 00:58:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:58:00', NULL, '2021-03-14 00:58:00', b'0');
392   -INSERT INTO `inf_job_log` VALUES (324, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 00:59:00', '2021-03-14 00:59:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 00:59:00', NULL, '2021-03-14 00:59:00', b'0');
393   -INSERT INTO `inf_job_log` VALUES (325, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:00:00', '2021-03-14 01:00:00', 4, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:00:00', NULL, '2021-03-14 01:00:00', b'0');
394   -INSERT INTO `inf_job_log` VALUES (326, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:01:00', '2021-03-14 01:01:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:01:00', NULL, '2021-03-14 01:01:00', b'0');
395   -INSERT INTO `inf_job_log` VALUES (327, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:02:00', '2021-03-14 01:02:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:02:00', NULL, '2021-03-14 01:02:00', b'0');
396   -INSERT INTO `inf_job_log` VALUES (328, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:03:00', '2021-03-14 01:03:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:03:00', NULL, '2021-03-14 01:03:00', b'0');
397   -INSERT INTO `inf_job_log` VALUES (329, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:04:00', '2021-03-14 01:04:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:04:00', NULL, '2021-03-14 01:04:00', b'0');
398   -INSERT INTO `inf_job_log` VALUES (330, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:05:00', '2021-03-14 01:05:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:05:00', NULL, '2021-03-14 01:05:00', b'0');
399   -INSERT INTO `inf_job_log` VALUES (331, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:06:00', '2021-03-14 01:06:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:06:00', NULL, '2021-03-14 01:06:00', b'0');
400   -INSERT INTO `inf_job_log` VALUES (332, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:07:00', '2021-03-14 01:07:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:07:00', NULL, '2021-03-14 01:07:00', b'0');
401   -INSERT INTO `inf_job_log` VALUES (333, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:08:00', '2021-03-14 01:08:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:08:00', NULL, '2021-03-14 01:08:00', b'0');
402   -INSERT INTO `inf_job_log` VALUES (334, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:09:00', '2021-03-14 01:09:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:09:00', NULL, '2021-03-14 01:09:00', b'0');
403   -INSERT INTO `inf_job_log` VALUES (335, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:10:00', '2021-03-14 01:10:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:10:00', NULL, '2021-03-14 01:10:00', b'0');
404   -INSERT INTO `inf_job_log` VALUES (336, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:11:00', '2021-03-14 01:11:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:11:00', NULL, '2021-03-14 01:11:00', b'0');
405   -INSERT INTO `inf_job_log` VALUES (337, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:12:00', '2021-03-14 01:12:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:12:00', NULL, '2021-03-14 01:12:00', b'0');
406   -INSERT INTO `inf_job_log` VALUES (338, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:13:00', '2021-03-14 01:13:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:13:00', NULL, '2021-03-14 01:13:00', b'0');
407   -INSERT INTO `inf_job_log` VALUES (339, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:14:00', '2021-03-14 01:14:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:14:00', NULL, '2021-03-14 01:14:00', b'0');
408   -INSERT INTO `inf_job_log` VALUES (340, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:15:00', '2021-03-14 01:15:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:15:00', NULL, '2021-03-14 01:15:00', b'0');
409   -INSERT INTO `inf_job_log` VALUES (341, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:16:00', '2021-03-14 01:16:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:16:00', NULL, '2021-03-14 01:16:00', b'0');
410   -INSERT INTO `inf_job_log` VALUES (342, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:17:00', '2021-03-14 01:17:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:17:00', NULL, '2021-03-14 01:17:00', b'0');
411   -INSERT INTO `inf_job_log` VALUES (343, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:18:00', '2021-03-14 01:18:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:18:00', NULL, '2021-03-14 01:18:00', b'0');
412   -INSERT INTO `inf_job_log` VALUES (344, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:19:00', '2021-03-14 01:19:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:19:00', NULL, '2021-03-14 01:19:00', b'0');
413   -INSERT INTO `inf_job_log` VALUES (345, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:20:00', '2021-03-14 01:20:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:20:00', NULL, '2021-03-14 01:20:00', b'0');
414   -INSERT INTO `inf_job_log` VALUES (346, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:21:00', '2021-03-14 01:21:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:21:00', NULL, '2021-03-14 01:21:00', b'0');
415   -INSERT INTO `inf_job_log` VALUES (347, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:22:00', '2021-03-14 01:22:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:22:00', NULL, '2021-03-14 01:22:00', b'0');
416   -INSERT INTO `inf_job_log` VALUES (348, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:23:00', '2021-03-14 01:23:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:23:00', NULL, '2021-03-14 01:23:00', b'0');
417   -INSERT INTO `inf_job_log` VALUES (349, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:24:00', '2021-03-14 01:24:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:24:00', NULL, '2021-03-14 01:24:00', b'0');
418   -INSERT INTO `inf_job_log` VALUES (350, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:25:00', '2021-03-14 01:25:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:25:00', NULL, '2021-03-14 01:25:00', b'0');
419   -INSERT INTO `inf_job_log` VALUES (351, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:26:00', '2021-03-14 01:26:00', 16, 1, '移除在线会话数量为 1 个', NULL, '2021-03-14 01:26:00', NULL, '2021-03-14 01:26:00', b'0');
420   -INSERT INTO `inf_job_log` VALUES (352, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:27:00', '2021-03-14 01:27:00', 4, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:27:00', NULL, '2021-03-14 01:27:00', b'0');
421   -INSERT INTO `inf_job_log` VALUES (353, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:28:00', '2021-03-14 01:28:00', 4, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:28:00', NULL, '2021-03-14 01:28:00', b'0');
422   -INSERT INTO `inf_job_log` VALUES (354, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:29:00', '2021-03-14 01:29:00', 4, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:29:00', NULL, '2021-03-14 01:29:00', b'0');
423   -INSERT INTO `inf_job_log` VALUES (355, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:30:00', '2021-03-14 01:30:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:30:00', NULL, '2021-03-14 01:30:00', b'0');
424   -INSERT INTO `inf_job_log` VALUES (356, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:31:00', '2021-03-14 01:31:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:31:00', NULL, '2021-03-14 01:31:00', b'0');
425   -INSERT INTO `inf_job_log` VALUES (357, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:32:00', '2021-03-14 01:32:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:32:00', NULL, '2021-03-14 01:32:00', b'0');
426   -INSERT INTO `inf_job_log` VALUES (358, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:33:00', '2021-03-14 01:33:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:33:00', NULL, '2021-03-14 01:33:00', b'0');
427   -INSERT INTO `inf_job_log` VALUES (359, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:34:00', '2021-03-14 01:34:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:34:00', NULL, '2021-03-14 01:34:00', b'0');
428   -INSERT INTO `inf_job_log` VALUES (360, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:35:00', '2021-03-14 01:35:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:35:00', NULL, '2021-03-14 01:35:00', b'0');
429   -INSERT INTO `inf_job_log` VALUES (361, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:36:00', '2021-03-14 01:36:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:36:00', NULL, '2021-03-14 01:36:00', b'0');
430   -INSERT INTO `inf_job_log` VALUES (362, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:37:00', '2021-03-14 01:37:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:37:00', NULL, '2021-03-14 01:37:00', b'0');
431   -INSERT INTO `inf_job_log` VALUES (363, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:38:00', '2021-03-14 01:38:00', 4, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:38:00', NULL, '2021-03-14 01:38:00', b'0');
432   -INSERT INTO `inf_job_log` VALUES (364, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:39:00', '2021-03-14 01:39:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:39:00', NULL, '2021-03-14 01:39:00', b'0');
433   -INSERT INTO `inf_job_log` VALUES (365, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:40:00', '2021-03-14 01:40:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:40:00', NULL, '2021-03-14 01:40:00', b'0');
434   -INSERT INTO `inf_job_log` VALUES (366, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 01:41:00', '2021-03-14 01:41:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 01:41:00', NULL, '2021-03-14 01:41:00', b'0');
435   -INSERT INTO `inf_job_log` VALUES (367, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 02:30:57', '2021-03-14 02:30:57', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 02:30:57', NULL, '2021-03-14 02:30:57', b'0');
436   -INSERT INTO `inf_job_log` VALUES (368, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 02:31:00', '2021-03-14 02:31:00', 4, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 02:31:00', NULL, '2021-03-14 02:31:00', b'0');
437   -INSERT INTO `inf_job_log` VALUES (369, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 02:32:00', '2021-03-14 02:32:00', 32, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 02:32:00', NULL, '2021-03-14 02:32:00', b'0');
438   -INSERT INTO `inf_job_log` VALUES (370, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 02:33:00', '2021-03-14 02:33:00', 18, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 02:33:00', NULL, '2021-03-14 02:33:00', b'0');
439   -INSERT INTO `inf_job_log` VALUES (371, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 02:34:00', '2021-03-14 02:34:00', 18, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 02:34:00', NULL, '2021-03-14 02:34:00', b'0');
440   -INSERT INTO `inf_job_log` VALUES (372, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 06:25:17', '2021-03-14 06:25:17', 37, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 06:25:17', NULL, '2021-03-14 06:25:17', b'0');
441   -INSERT INTO `inf_job_log` VALUES (373, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 06:26:00', '2021-03-14 06:26:00', 18, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 06:26:00', NULL, '2021-03-14 06:26:00', b'0');
442   -INSERT INTO `inf_job_log` VALUES (374, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 06:27:00', '2021-03-14 06:27:00', 17, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 06:27:00', NULL, '2021-03-14 06:27:00', b'0');
443   -INSERT INTO `inf_job_log` VALUES (375, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 06:28:00', '2021-03-14 06:28:00', 17, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 06:28:00', NULL, '2021-03-14 06:28:00', b'0');
444   -INSERT INTO `inf_job_log` VALUES (376, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 07:06:09', '2021-03-14 07:06:09', 36, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 07:06:09', NULL, '2021-03-14 07:06:09', b'0');
445   -INSERT INTO `inf_job_log` VALUES (377, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 07:52:11', '2021-03-14 07:52:11', 32, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 07:52:11', NULL, '2021-03-14 07:52:11', b'0');
446   -INSERT INTO `inf_job_log` VALUES (378, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:00:55', '2021-03-14 10:00:55', 41, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:00:55', NULL, '2021-03-14 10:00:55', b'0');
447   -INSERT INTO `inf_job_log` VALUES (379, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:01:00', '2021-03-14 10:01:00', 17, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:01:00', NULL, '2021-03-14 10:01:00', b'0');
448   -INSERT INTO `inf_job_log` VALUES (380, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:02:00', '2021-03-14 10:02:00', 16, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:02:00', NULL, '2021-03-14 10:02:00', b'0');
449   -INSERT INTO `inf_job_log` VALUES (381, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:03:00', '2021-03-14 10:03:00', 16, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:03:00', NULL, '2021-03-14 10:03:00', b'0');
450   -INSERT INTO `inf_job_log` VALUES (382, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:04:00', '2021-03-14 10:04:00', 14, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:04:00', NULL, '2021-03-14 10:04:00', b'0');
451   -INSERT INTO `inf_job_log` VALUES (383, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:05:00', '2021-03-14 10:05:00', 13, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:05:00', NULL, '2021-03-14 10:05:00', b'0');
452   -INSERT INTO `inf_job_log` VALUES (384, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:06:00', '2021-03-14 10:06:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:06:00', NULL, '2021-03-14 10:06:00', b'0');
453   -INSERT INTO `inf_job_log` VALUES (385, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:07:00', '2021-03-14 10:07:00', 12, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:07:00', NULL, '2021-03-14 10:07:00', b'0');
454   -INSERT INTO `inf_job_log` VALUES (386, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:08:00', '2021-03-14 10:08:00', 14, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:08:00', NULL, '2021-03-14 10:08:00', b'0');
455   -INSERT INTO `inf_job_log` VALUES (387, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:09:00', '2021-03-14 10:09:00', 14, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:09:00', NULL, '2021-03-14 10:09:00', b'0');
456   -INSERT INTO `inf_job_log` VALUES (388, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:10:00', '2021-03-14 10:10:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:10:00', NULL, '2021-03-14 10:10:00', b'0');
457   -INSERT INTO `inf_job_log` VALUES (389, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:11:00', '2021-03-14 10:11:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:11:00', NULL, '2021-03-14 10:11:00', b'0');
458   -INSERT INTO `inf_job_log` VALUES (390, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:12:00', '2021-03-14 10:12:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:12:00', NULL, '2021-03-14 10:12:00', b'0');
459   -INSERT INTO `inf_job_log` VALUES (391, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:13:00', '2021-03-14 10:13:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:13:00', NULL, '2021-03-14 10:13:00', b'0');
460   -INSERT INTO `inf_job_log` VALUES (392, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:14:00', '2021-03-14 10:14:00', 17, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:14:00', NULL, '2021-03-14 10:14:00', b'0');
461   -INSERT INTO `inf_job_log` VALUES (393, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:15:00', '2021-03-14 10:15:00', 15, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:15:00', NULL, '2021-03-14 10:15:00', b'0');
462   -INSERT INTO `inf_job_log` VALUES (394, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:16:00', '2021-03-14 10:16:00', 13, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:16:00', NULL, '2021-03-14 10:16:00', b'0');
463   -INSERT INTO `inf_job_log` VALUES (395, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:17:00', '2021-03-14 10:17:00', 12, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:17:00', NULL, '2021-03-14 10:17:00', b'0');
464   -INSERT INTO `inf_job_log` VALUES (396, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:18:00', '2021-03-14 10:18:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:18:00', NULL, '2021-03-14 10:18:00', b'0');
465   -INSERT INTO `inf_job_log` VALUES (397, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:19:00', '2021-03-14 10:19:00', 11, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:19:00', NULL, '2021-03-14 10:19:00', b'0');
466   -INSERT INTO `inf_job_log` VALUES (398, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:20:00', '2021-03-14 10:20:00', 12, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:20:00', NULL, '2021-03-14 10:20:00', b'0');
467   -INSERT INTO `inf_job_log` VALUES (399, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:21:00', '2021-03-14 10:21:00', 13, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:21:00', NULL, '2021-03-14 10:21:00', b'0');
468   -INSERT INTO `inf_job_log` VALUES (400, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:22:00', '2021-03-14 10:22:00', 12, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:22:00', NULL, '2021-03-14 10:22:00', b'0');
469   -INSERT INTO `inf_job_log` VALUES (401, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:23:00', '2021-03-14 10:23:00', 13, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:23:00', NULL, '2021-03-14 10:23:00', b'0');
470   -INSERT INTO `inf_job_log` VALUES (402, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:24:00', '2021-03-14 10:24:00', 11, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:24:00', NULL, '2021-03-14 10:24:00', b'0');
471   -INSERT INTO `inf_job_log` VALUES (403, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:25:00', '2021-03-14 10:25:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:25:00', NULL, '2021-03-14 10:25:00', b'0');
472   -INSERT INTO `inf_job_log` VALUES (404, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:26:00', '2021-03-14 10:26:00', 12, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:26:00', NULL, '2021-03-14 10:26:00', b'0');
473   -INSERT INTO `inf_job_log` VALUES (405, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:27:00', '2021-03-14 10:27:00', 13, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:27:00', NULL, '2021-03-14 10:27:00', b'0');
474   -INSERT INTO `inf_job_log` VALUES (406, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:28:00', '2021-03-14 10:28:00', 14, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:28:00', NULL, '2021-03-14 10:28:00', b'0');
475   -INSERT INTO `inf_job_log` VALUES (407, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:29:00', '2021-03-14 10:29:00', 13, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:29:00', NULL, '2021-03-14 10:29:00', b'0');
476   -INSERT INTO `inf_job_log` VALUES (408, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:30:00', '2021-03-14 10:30:00', 11, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:30:00', NULL, '2021-03-14 10:30:00', b'0');
477   -INSERT INTO `inf_job_log` VALUES (409, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:31:00', '2021-03-14 10:31:00', 11, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:31:00', NULL, '2021-03-14 10:31:00', b'0');
478   -INSERT INTO `inf_job_log` VALUES (410, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:32:00', '2021-03-14 10:32:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:32:00', NULL, '2021-03-14 10:32:00', b'0');
479   -INSERT INTO `inf_job_log` VALUES (411, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:33:00', '2021-03-14 10:33:00', 12, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:33:00', NULL, '2021-03-14 10:33:00', b'0');
480   -INSERT INTO `inf_job_log` VALUES (412, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:34:00', '2021-03-14 10:34:00', 13, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:34:00', NULL, '2021-03-14 10:34:00', b'0');
481   -INSERT INTO `inf_job_log` VALUES (413, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:35:00', '2021-03-14 10:35:00', 13, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:35:00', NULL, '2021-03-14 10:35:00', b'0');
482   -INSERT INTO `inf_job_log` VALUES (414, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:36:00', '2021-03-14 10:36:00', 11, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:36:00', NULL, '2021-03-14 10:36:00', b'0');
483   -INSERT INTO `inf_job_log` VALUES (415, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:37:00', '2021-03-14 10:37:00', 11, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:37:00', NULL, '2021-03-14 10:37:00', b'0');
484   -INSERT INTO `inf_job_log` VALUES (416, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:38:00', '2021-03-14 10:38:00', 10, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:38:00', NULL, '2021-03-14 10:38:00', b'0');
485   -INSERT INTO `inf_job_log` VALUES (417, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:39:00', '2021-03-14 10:39:00', 12, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:39:00', NULL, '2021-03-14 10:39:00', b'0');
486   -INSERT INTO `inf_job_log` VALUES (418, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:40:00', '2021-03-14 10:40:00', 14, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:40:00', NULL, '2021-03-14 10:40:00', b'0');
487   -INSERT INTO `inf_job_log` VALUES (419, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:41:00', '2021-03-14 10:41:00', 14, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:41:00', NULL, '2021-03-14 10:41:00', b'0');
488   -INSERT INTO `inf_job_log` VALUES (420, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:42:00', '2021-03-14 10:42:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:42:00', NULL, '2021-03-14 10:42:00', b'0');
489   -INSERT INTO `inf_job_log` VALUES (421, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:43:00', '2021-03-14 10:43:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:43:00', NULL, '2021-03-14 10:43:00', b'0');
490   -INSERT INTO `inf_job_log` VALUES (422, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:44:00', '2021-03-14 10:44:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:44:00', NULL, '2021-03-14 10:44:00', b'0');
491   -INSERT INTO `inf_job_log` VALUES (423, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:45:00', '2021-03-14 10:45:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:45:00', NULL, '2021-03-14 10:45:00', b'0');
492   -INSERT INTO `inf_job_log` VALUES (424, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:46:00', '2021-03-14 10:46:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:46:00', NULL, '2021-03-14 10:46:00', b'0');
493   -INSERT INTO `inf_job_log` VALUES (425, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:47:00', '2021-03-14 10:47:00', 7, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:47:00', NULL, '2021-03-14 10:47:00', b'0');
494   -INSERT INTO `inf_job_log` VALUES (426, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:48:00', '2021-03-14 10:48:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:48:00', NULL, '2021-03-14 10:48:00', b'0');
495   -INSERT INTO `inf_job_log` VALUES (427, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:49:00', '2021-03-14 10:49:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:49:00', NULL, '2021-03-14 10:49:00', b'0');
496   -INSERT INTO `inf_job_log` VALUES (428, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:50:00', '2021-03-14 10:50:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:50:00', NULL, '2021-03-14 10:50:00', b'0');
497   -INSERT INTO `inf_job_log` VALUES (429, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:51:00', '2021-03-14 10:51:00', 4, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:51:00', NULL, '2021-03-14 10:51:00', b'0');
498   -INSERT INTO `inf_job_log` VALUES (430, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:52:00', '2021-03-14 10:52:00', 6, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:52:00', NULL, '2021-03-14 10:52:00', b'0');
499   -INSERT INTO `inf_job_log` VALUES (431, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:53:00', '2021-03-14 10:53:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:53:00', NULL, '2021-03-14 10:53:00', b'0');
500   -INSERT INTO `inf_job_log` VALUES (432, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:54:00', '2021-03-14 10:54:00', 4, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:54:00', NULL, '2021-03-14 10:54:00', b'0');
501   -INSERT INTO `inf_job_log` VALUES (433, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:55:00', '2021-03-14 10:55:00', 5, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:55:00', NULL, '2021-03-14 10:55:00', b'0');
502   -INSERT INTO `inf_job_log` VALUES (434, 3, 'sysUserSessionTimeoutJob', NULL, 1, '2021-03-14 10:56:00', '2021-03-14 10:56:00', 4, 1, '移除在线会话数量为 0 个', NULL, '2021-03-14 10:56:00', NULL, '2021-03-14 10:56:00', b'0');
503 210 COMMIT;
504 211  
505 212 -- ----------------------------
... ... @@ -528,7 +235,7 @@ CREATE TABLE `sys_dept` (
528 235 -- ----------------------------
529 236 BEGIN;
530 237 INSERT INTO `sys_dept` VALUES (100, '芋道源码', 0, 0, '若依', '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-01-06 19:45:52', b'0');
531   -INSERT INTO `sys_dept` VALUES (101, '深圳总公司', 100, 1, '若依', '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-01-05 17:03:47', b'0');
  238 +INSERT INTO `sys_dept` VALUES (101, '深圳总公司', 100, 1, '若依', '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2021-03-14 20:26:18', b'0');
532 239 INSERT INTO `sys_dept` VALUES (102, '长沙分公司', 100, 2, '若依', '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-01-05 17:03:47', b'0');
533 240 INSERT INTO `sys_dept` VALUES (103, '研发部门', 101, 1, '若依', '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-01-05 17:03:47', b'0');
534 241 INSERT INTO `sys_dept` VALUES (104, '市场部门', 101, 2, '若依', '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-01-05 17:03:47', b'0');
... ... @@ -679,16 +386,12 @@ CREATE TABLE `sys_login_log` (
679 386 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
680 387 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
681 388 PRIMARY KEY (`id`) USING BTREE
682   -) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COMMENT='系统访问记录';
  389 +) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COMMENT='系统访问记录';
683 390  
684 391 -- ----------------------------
685 392 -- Records of sys_login_log
686 393 -- ----------------------------
687 394 BEGIN;
688   -INSERT INTO `sys_login_log` VALUES (6, 201, 'f15eab42-8dc9-4da8-b231-3d3c6df5e0a6', 'admin', 0, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-14 00:31:13', NULL, '2021-03-14 00:31:13', b'0');
689   -INSERT INTO `sys_login_log` VALUES (7, 100, '65d43b8b-9e34-45f7-9925-67e64266de11', 'admin', 31, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-14 00:31:39', NULL, '2021-03-14 00:31:39', b'0');
690   -INSERT INTO `sys_login_log` VALUES (8, 100, 'fe66aec6-4196-43dd-8653-7f06d0bdaf7d', 'admin', 0, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-14 00:31:43', NULL, '2021-03-14 00:31:43', b'0');
691   -INSERT INTO `sys_login_log` VALUES (9, 201, '2b1a614d-1073-48b9-9bf3-502382af432c', 'admin', 0, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-14 01:26:00', NULL, '2021-03-14 01:26:00', b'0');
692 395 COMMIT;
693 396  
694 397 -- ----------------------------
... ... @@ -723,13 +426,13 @@ INSERT INTO `sys_menu` VALUES (2, &#39;基础设施&#39;, &#39;&#39;, 1, 2, 0, &#39;/infra&#39;, &#39;monito
723 426 INSERT INTO `sys_menu` VALUES (3, '研发工具', '', 1, 3, 0, '/tool', 'tool', NULL, 0, 'admin', '2021-01-05 17:03:48', '', '2021-02-06 12:44:42', b'0');
724 427 INSERT INTO `sys_menu` VALUES (4, '若依官网', '', 1, 4, 0, 'http://ruoyi.vip', 'guide', NULL, 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-20 21:54:28', b'1');
725 428 INSERT INTO `sys_menu` VALUES (100, '用户管理', 'system:user:list', 2, 1, 1, 'user', 'user', 'system/user/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
726   -INSERT INTO `sys_menu` VALUES (101, '角色管理', 'system:role:list', 2, 2, 1, 'role', 'peoples', 'system/role/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
727   -INSERT INTO `sys_menu` VALUES (102, '菜单管理', 'system:menu:list', 2, 3, 1, 'menu', 'tree-table', 'system/menu/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
728   -INSERT INTO `sys_menu` VALUES (103, '部门管理', 'system:dept:list', 2, 4, 1, 'dept', 'tree', 'system/dept/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
729   -INSERT INTO `sys_menu` VALUES (104, '岗位管理', 'system:post:list', 2, 5, 1, 'post', 'post', 'system/post/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
730   -INSERT INTO `sys_menu` VALUES (105, '字典管理', 'system:dict:list', 2, 6, 1, 'dict', 'dict', 'system/dict/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
  429 +INSERT INTO `sys_menu` VALUES (101, '角色管理', '', 2, 2, 1, 'role', 'peoples', 'system/role/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:04:49', b'0');
  430 +INSERT INTO `sys_menu` VALUES (102, '菜单管理', '', 2, 3, 1, 'menu', 'tree-table', 'system/menu/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:04:28', b'0');
  431 +INSERT INTO `sys_menu` VALUES (103, '部门管理', '', 2, 4, 1, 'dept', 'tree', 'system/dept/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:25:19', b'0');
  432 +INSERT INTO `sys_menu` VALUES (104, '岗位管理', '', 2, 5, 1, 'post', 'post', 'system/post/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:38:23', b'0');
  433 +INSERT INTO `sys_menu` VALUES (105, '字典管理', '', 2, 6, 1, 'dict', 'dict', 'system/dict/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:16:58', b'0');
731 434 INSERT INTO `sys_menu` VALUES (106, '配置管理', '', 2, 1, 2, 'config', 'edit', 'infra/config/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-10 01:12:10', b'0');
732   -INSERT INTO `sys_menu` VALUES (107, '通知公告', 'system:notice:list', 2, 8, 1, 'notice', 'message', 'system/notice/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
  435 +INSERT INTO `sys_menu` VALUES (107, '通知公告', '', 2, 8, 1, 'notice', 'message', 'system/notice/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:51:39', b'0');
733 436 INSERT INTO `sys_menu` VALUES (108, '日志管理', '', 1, 9, 1, 'log', 'log', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:34:28', b'0');
734 437 INSERT INTO `sys_menu` VALUES (109, '在线用户', 'system:user-session:list', 2, 10, 1, 'user-session', 'online', 'system/session/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-26 08:21:20', b'0');
735 438 INSERT INTO `sys_menu` VALUES (110, '定时任务', '', 2, 2, 2, 'job', 'job', 'infra/job/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-10 01:25:51', b'0');
... ... @@ -739,37 +442,37 @@ INSERT INTO `sys_menu` VALUES (113, &#39;Redis 监控&#39;, &#39;&#39;, 2, 5, 2, &#39;redis&#39;, &#39;redis
739 442 INSERT INTO `sys_menu` VALUES (114, '表单构建', 'tool:build:list', 2, 1, 3, 'build', 'build', 'tool/build/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
740 443 INSERT INTO `sys_menu` VALUES (115, '代码生成', 'tool:codegen:query', 2, 0, 3, 'codegen', 'code', 'tool/codegen/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-03-06 03:43:14', b'0');
741 444 INSERT INTO `sys_menu` VALUES (116, '系统接口', 'tool:swagger:list', 2, 3, 3, 'swagger', 'swagger', 'tool/swagger/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
742   -INSERT INTO `sys_menu` VALUES (500, '操作日志', 'system:operate-log:list', 2, 1, 108, 'operate-log', 'form', 'system/operatelog/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-16 18:25:45', b'0');
743   -INSERT INTO `sys_menu` VALUES (501, '登录日志', 'system:login-log:list', 2, 2, 108, 'login-log', 'logininfor', 'system/loginlog/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-18 05:29:58', b'0');
  445 +INSERT INTO `sys_menu` VALUES (500, '操作日志', '', 2, 1, 108, 'operate-log', 'form', 'system/operatelog/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:42:56', b'0');
  446 +INSERT INTO `sys_menu` VALUES (501, '登录日志', '', 2, 2, 108, 'login-log', 'logininfor', 'system/loginlog/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:39:23', b'0');
744 447 INSERT INTO `sys_menu` VALUES (1001, '用户查询', 'system:user:query', 3, 1, 100, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
745   -INSERT INTO `sys_menu` VALUES (1002, '用户新增', 'system:user:add', 3, 2, 100, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
746   -INSERT INTO `sys_menu` VALUES (1003, '用户修改', 'system:user:edit', 3, 3, 100, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
747   -INSERT INTO `sys_menu` VALUES (1004, '用户删除', 'system:user:remove', 3, 4, 100, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
  448 +INSERT INTO `sys_menu` VALUES (1002, '用户新增', 'system:user:create', 3, 2, 100, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:21:47', b'0');
  449 +INSERT INTO `sys_menu` VALUES (1003, '用户修改', 'system:user:update', 3, 3, 100, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:21:54', b'0');
  450 +INSERT INTO `sys_menu` VALUES (1004, '用户删除', 'system:user:delete', 3, 4, 100, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:22:03', b'0');
748 451 INSERT INTO `sys_menu` VALUES (1005, '用户导出', 'system:user:export', 3, 5, 100, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
749 452 INSERT INTO `sys_menu` VALUES (1006, '用户导入', 'system:user:import', 3, 6, 100, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
750   -INSERT INTO `sys_menu` VALUES (1007, '重置密码', 'system:user:resetPwd', 3, 7, 100, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
  453 +INSERT INTO `sys_menu` VALUES (1007, '重置密码', 'system:user:update-password', 3, 7, 100, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:20:55', b'0');
751 454 INSERT INTO `sys_menu` VALUES (1008, '角色查询', 'system:role:query', 3, 1, 101, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
752   -INSERT INTO `sys_menu` VALUES (1009, '角色新增', 'system:role:add', 3, 2, 101, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
753   -INSERT INTO `sys_menu` VALUES (1010, '角色修改', 'system:role:edit', 3, 3, 101, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
754   -INSERT INTO `sys_menu` VALUES (1011, '角色删除', 'system:role:remove', 3, 4, 101, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
  455 +INSERT INTO `sys_menu` VALUES (1009, '角色新增', 'system:role:create', 3, 2, 101, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:05:24', b'0');
  456 +INSERT INTO `sys_menu` VALUES (1010, '角色修改', 'system:role:update', 3, 3, 101, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:05:14', b'0');
  457 +INSERT INTO `sys_menu` VALUES (1011, '角色删除', 'system:role:delete', 3, 4, 101, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:05:05', b'0');
755 458 INSERT INTO `sys_menu` VALUES (1012, '角色导出', 'system:role:export', 3, 5, 101, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
756 459 INSERT INTO `sys_menu` VALUES (1013, '菜单查询', 'system:menu:query', 3, 1, 102, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
757   -INSERT INTO `sys_menu` VALUES (1014, '菜单新增', 'system:menu:add', 3, 2, 102, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
758   -INSERT INTO `sys_menu` VALUES (1015, '菜单修改', 'system:menu:edit', 3, 3, 102, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
759   -INSERT INTO `sys_menu` VALUES (1016, '菜单删除', 'system:menu:remove', 3, 4, 102, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
  460 +INSERT INTO `sys_menu` VALUES (1014, '菜单新增', 'system:menu:create', 3, 2, 102, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-03-13 15:49:36', b'0');
  461 +INSERT INTO `sys_menu` VALUES (1015, '菜单修改', 'system:menu:update', 3, 3, 102, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-03-13 15:49:30', b'0');
  462 +INSERT INTO `sys_menu` VALUES (1016, '菜单删除', 'system:menu:delete', 3, 4, 102, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-03-13 15:49:45', b'0');
760 463 INSERT INTO `sys_menu` VALUES (1017, '部门查询', 'system:dept:query', 3, 1, 103, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
761   -INSERT INTO `sys_menu` VALUES (1018, '部门新增', 'system:dept:add', 3, 2, 103, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
762   -INSERT INTO `sys_menu` VALUES (1019, '部门修改', 'system:dept:edit', 3, 3, 103, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
763   -INSERT INTO `sys_menu` VALUES (1020, '部门删除', 'system:dept:remove', 3, 4, 103, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
  464 +INSERT INTO `sys_menu` VALUES (1018, '部门新增', 'system:dept:create', 3, 2, 103, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:25:30', b'0');
  465 +INSERT INTO `sys_menu` VALUES (1019, '部门修改', 'system:dept:update', 3, 3, 103, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:25:37', b'0');
  466 +INSERT INTO `sys_menu` VALUES (1020, '部门删除', 'system:dept:delete', 3, 4, 103, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:25:43', b'0');
764 467 INSERT INTO `sys_menu` VALUES (1021, '岗位查询', 'system:post:query', 3, 1, 104, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
765   -INSERT INTO `sys_menu` VALUES (1022, '岗位新增', 'system:post:add', 3, 2, 104, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
766   -INSERT INTO `sys_menu` VALUES (1023, '岗位修改', 'system:post:edit', 3, 3, 104, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
767   -INSERT INTO `sys_menu` VALUES (1024, '岗位删除', 'system:post:remove', 3, 4, 104, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
  468 +INSERT INTO `sys_menu` VALUES (1022, '岗位新增', 'system:post:create', 3, 2, 104, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:38:34', b'0');
  469 +INSERT INTO `sys_menu` VALUES (1023, '岗位修改', 'system:post:update', 3, 3, 104, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:38:41', b'0');
  470 +INSERT INTO `sys_menu` VALUES (1024, '岗位删除', 'system:post:delete', 3, 4, 104, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:38:48', b'0');
768 471 INSERT INTO `sys_menu` VALUES (1025, '岗位导出', 'system:post:export', 3, 5, 104, '', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
769 472 INSERT INTO `sys_menu` VALUES (1026, '字典查询', 'system:dict:query', 3, 1, 105, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
770   -INSERT INTO `sys_menu` VALUES (1027, '字典新增', 'system:dict:add', 3, 2, 105, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
771   -INSERT INTO `sys_menu` VALUES (1028, '字典修改', 'system:dict:edit', 3, 3, 105, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
772   -INSERT INTO `sys_menu` VALUES (1029, '字典删除', 'system:dict:remove', 3, 4, 105, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
  473 +INSERT INTO `sys_menu` VALUES (1027, '字典新增', 'system:dict:create', 3, 2, 105, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:19:29', b'0');
  474 +INSERT INTO `sys_menu` VALUES (1028, '字典修改', 'system:dict:update', 3, 3, 105, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:19:36', b'0');
  475 +INSERT INTO `sys_menu` VALUES (1029, '字典删除', 'system:dict:delete', 3, 4, 105, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:19:45', b'0');
773 476 INSERT INTO `sys_menu` VALUES (1030, '字典导出', 'system:dict:export', 3, 5, 105, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
774 477 INSERT INTO `sys_menu` VALUES (1031, '配置查询', 'infra:config:query', 3, 1, 106, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-20 14:34:00', b'0');
775 478 INSERT INTO `sys_menu` VALUES (1032, '配置新增', 'infra:config:create', 3, 2, 106, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-10 01:12:18', b'0');
... ... @@ -777,9 +480,9 @@ INSERT INTO `sys_menu` VALUES (1033, &#39;配置修改&#39;, &#39;infra:config:update&#39;, 3, 3
777 480 INSERT INTO `sys_menu` VALUES (1034, '配置删除', 'infra:config:delete', 3, 4, 106, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-10 01:12:36', b'0');
778 481 INSERT INTO `sys_menu` VALUES (1035, '配置导出', 'infra:config:export', 3, 5, 106, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-20 14:34:19', b'0');
779 482 INSERT INTO `sys_menu` VALUES (1036, '公告查询', 'system:notice:query', 3, 1, 107, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
780   -INSERT INTO `sys_menu` VALUES (1037, '公告新增', 'system:notice:add', 3, 2, 107, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
781   -INSERT INTO `sys_menu` VALUES (1038, '公告修改', 'system:notice:edit', 3, 3, 107, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
782   -INSERT INTO `sys_menu` VALUES (1039, '公告删除', 'system:notice:remove', 3, 4, 107, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:55', b'0');
  483 +INSERT INTO `sys_menu` VALUES (1037, '公告新增', 'system:notice:create', 3, 2, 107, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:51:48', b'0');
  484 +INSERT INTO `sys_menu` VALUES (1038, '公告修改', 'system:notice:update', 3, 3, 107, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:51:55', b'0');
  485 +INSERT INTO `sys_menu` VALUES (1039, '公告删除', 'system:notice:delete', 3, 4, 107, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 21:52:01', b'0');
783 486 INSERT INTO `sys_menu` VALUES (1040, '操作查询', 'system:operate-log:query', 3, 1, 500, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-16 18:28:10', b'0');
784 487 INSERT INTO `sys_menu` VALUES (1042, '日志导出', 'system:operate-log:export', 3, 2, 500, '', '', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-16 18:28:23', b'0');
785 488 INSERT INTO `sys_menu` VALUES (1043, '登录查询', 'system:login-log:query', 3, 1, 501, '#', '#', '', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-18 05:29:26', b'0');
... ... @@ -886,7 +589,7 @@ CREATE TABLE `sys_operate_log` (
886 589 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
887 590 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
888 591 PRIMARY KEY (`id`) USING BTREE
889   -) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COMMENT='操作日志记录';
  592 +) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8mb4 COMMENT='操作日志记录';
890 593  
891 594 -- ----------------------------
892 595 -- Records of sys_operate_log
... ... @@ -917,8 +620,8 @@ CREATE TABLE `sys_post` (
917 620 -- Records of sys_post
918 621 -- ----------------------------
919 622 BEGIN;
920   -INSERT INTO `sys_post` VALUES (1, 'ceo', '董事长', 1, 0, '', 'admin', '2021-01-05 17:03:48', '', '2021-01-05 17:03:48', b'0');
921   -INSERT INTO `sys_post` VALUES (2, 'se', '项目经理', 2, 0, '', 'admin', '2021-01-05 17:03:48', '', '2021-01-05 17:03:48', b'0');
  623 +INSERT INTO `sys_post` VALUES (1, 'ceo', '董事长', 1, 0, '', 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:39:03', b'0');
  624 +INSERT INTO `sys_post` VALUES (2, 'se', '项目经理', 2, 0, '', 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 20:39:05', b'0');
922 625 INSERT INTO `sys_post` VALUES (3, 'hr', '人力资源', 3, 0, '', 'admin', '2021-01-05 17:03:48', '', '2021-01-05 17:03:48', b'0');
923 626 INSERT INTO `sys_post` VALUES (4, 'user', '普通员工', 4, 0, '', 'admin', '2021-01-05 17:03:48', '', '2021-01-05 17:03:48', b'0');
924 627 INSERT INTO `sys_post` VALUES (5, 'test', '测试岗位', 0, 1, '132', '', '2021-01-07 15:07:44', '', '2021-01-07 15:10:35', b'1');
... ... @@ -952,7 +655,7 @@ CREATE TABLE `sys_role` (
952 655 BEGIN;
953 656 INSERT INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, 1, '', 0, 1, '超级管理员', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 12:40:20', b'0');
954 657 INSERT INTO `sys_role` VALUES (2, '普通角色', 'common', 2, 2, '', 0, 1, '普通角色', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 11:46:58', b'0');
955   -INSERT INTO `sys_role` VALUES (101, '测试账号', 'test', 0, 2, '[104]', 0, 2, '132', '', '2021-01-06 13:49:35', '', '2021-01-21 02:15:26', b'0');
  658 +INSERT INTO `sys_role` VALUES (101, '测试账号', 'test', 0, 2, '[104]', 0, 2, '132', '', '2021-01-06 13:49:35', '1', '2021-03-14 22:17:20', b'0');
956 659 COMMIT;
957 660  
958 661 -- ----------------------------
... ... @@ -1162,11 +865,11 @@ CREATE TABLE `sys_user` (
1162 865 -- Records of sys_user
1163 866 -- ----------------------------
1164 867 BEGIN;
1165   -INSERT INTO `sys_user` VALUES (1, 'admin', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '若依', '管理员', 103, '[1]', 'ry@163.com', '15888888888', 1, 'http://127.0.0.1:8080/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', 0, '127.0.0.1', '2021-01-05 17:03:47', 'admin', '2021-01-05 17:03:47', '', '2021-01-13 17:51:06', b'0');
  868 +INSERT INTO `sys_user` VALUES (1, 'admin', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://127.0.0.1:8080/api/system/file/get/add5ec1891a7d97d2cc1d60847e16294.jpg', 0, '127.0.0.1', '2021-01-05 17:03:47', 'admin', '2021-01-05 17:03:47', '1', '2021-03-21 18:16:16', b'0');
1166 869 INSERT INTO `sys_user` VALUES (2, 'ry', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '若依', '测试员', 105, '[2]', 'ry@qq.com', '15666666666', 1, '', 0, '127.0.0.1', '2021-01-05 17:03:47', 'admin', '2021-01-05 17:03:47', '', '2021-01-05 17:03:47', b'0');
1167   -INSERT INTO `sys_user` VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 100, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '', NULL, '', '2021-01-07 09:07:17', '', '2021-01-13 23:53:12', b'0');
  870 +INSERT INTO `sys_user` VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 100, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '', NULL, '', '2021-01-07 09:07:17', '1', '2021-03-14 22:35:17', b'0');
1168 871 INSERT INTO `sys_user` VALUES (103, 'yuanma', '', '源码', NULL, 100, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '', NULL, '', '2021-01-13 23:50:35', '', '2021-01-13 23:50:35', b'0');
1169   -INSERT INTO `sys_user` VALUES (104, 'test', '$2a$10$wTJ.1LVmhxcujss2NR2SMeBo8AaFsjkoDfDafHYsdHmitAiwmnvce', '测试号', NULL, 100, '[]', '', '15601691200', 1, '', 0, '', NULL, '', '2021-01-21 02:13:53', '', '2021-01-21 02:14:13', b'0');
  872 +INSERT INTO `sys_user` VALUES (104, 'test', '$2a$10$.TOFpaIiI3PzEwkGrNq0Eu6Cc3rOqJMxTb1DqeSEM8StxaGPBRKoi', '测试号', NULL, 100, '[]', '', '15601691200', 1, '', 0, '', NULL, '', '2021-01-21 02:13:53', '1', '2021-03-14 22:36:38', b'0');
1170 873 COMMIT;
1171 874  
1172 875 -- ----------------------------
... ... @@ -1224,6 +927,10 @@ BEGIN;
1224 927 INSERT INTO `sys_user_session` VALUES ('505b4e7d8b0d4b40aa23bf540da81234', 1, '2021-03-14 01:25:13', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-14 00:31:43', NULL, '2021-03-13 07:35:26', b'1');
1225 928 INSERT INTO `sys_user_session` VALUES ('5a7248bf87d14e7e9f0578b05969986c', 1, '2021-03-13 10:42:50', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-13 09:37:36', NULL, '2021-03-12 19:53:07', b'1');
1226 929 INSERT INTO `sys_user_session` VALUES ('9ae27346d8b7491aad1385f51e8aa196', 1, '2021-03-13 14:02:12', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-13 10:43:06', NULL, '2021-03-13 06:40:35', b'1');
  930 +INSERT INTO `sys_user_session` VALUES ('ae9ee7452ee54e4b983d658188c15c4d', 1, '2021-03-14 21:32:57', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-14 20:25:00', NULL, '2021-03-13 15:19:10', b'1');
  931 +INSERT INTO `sys_user_session` VALUES ('d0adf48f82914212b947e5ab04d9fb65', 1, '2021-03-21 19:16:28', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36', NULL, '2021-03-21 18:13:37', NULL, '2021-03-21 18:46:28', b'0');
  932 +INSERT INTO `sys_user_session` VALUES ('e8872f5192584440a548641b83c877ef', 1, '2021-03-21 18:36:01', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36', NULL, '2021-03-21 17:51:48', NULL, '2021-03-15 03:54:20', b'1');
  933 +INSERT INTO `sys_user_session` VALUES ('f1ab99b09b5a475795579ff99d60ac78', 1, '2021-03-14 23:04:31', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-14 21:12:44', NULL, '2021-03-15 03:32:38', b'1');
1227 934 INSERT INTO `sys_user_session` VALUES ('f853b50d064340a581e9a49bba9411fc', 1, '2021-03-10 01:55:41', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', NULL, '2021-03-10 01:11:53', NULL, '2021-03-12 18:37:05', b'1');
1228 935 COMMIT;
1229 936  
... ...
src/main/java/cn/iocoder/dashboard/framework/jackson/config/JacksonConfig.java
1 1 package cn.iocoder.dashboard.framework.jackson.config;
2 2  
  3 +import cn.iocoder.dashboard.framework.jackson.deser.LocalDateTimeDeserializer;
  4 +import cn.iocoder.dashboard.framework.jackson.ser.LocalDateTimeSerializer;
3 5 import cn.iocoder.dashboard.util.json.JsonUtils;
4 6 import com.fasterxml.jackson.databind.ObjectMapper;
  7 +import com.fasterxml.jackson.databind.module.SimpleModule;
5 8 import org.springframework.context.annotation.Bean;
6 9 import org.springframework.context.annotation.Configuration;
7 10  
  11 +import java.time.LocalDateTime;
  12 +
8 13 @Configuration
9 14 public class JacksonConfig {
10 15  
11 16 @Bean
12 17 @SuppressWarnings("InstantiationOfUtilityClass")
13 18 public JsonUtils jsonUtils(ObjectMapper objectMapper) {
  19 + SimpleModule simpleModule = new SimpleModule();
  20 + /*
  21 + * 1. 新增Long类型序列化规则,数值超过2^53-1,在JS会出现精度丢失问题,因此Long自动序列化为字符串类型
  22 + * 2. 新增LocalDateTime序列化、反序列化规则
  23 + */
  24 + simpleModule
  25 +// .addSerializer(Long.class, ToStringSerializer.instance)
  26 +// .addSerializer(Long.TYPE, ToStringSerializer.instance)
  27 + .addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE)
  28 + .addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
  29 +
  30 + objectMapper.registerModules(simpleModule);
  31 +
14 32 JsonUtils.init(objectMapper);
15 33 return new JsonUtils();
16 34 }
17   -
18 35 }
... ...
src/main/java/cn/iocoder/dashboard/framework/jackson/deser/LocalDateTimeDeserializer.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.jackson.deser;
  2 +
  3 +import com.fasterxml.jackson.core.JsonParser;
  4 +import com.fasterxml.jackson.core.JsonProcessingException;
  5 +import com.fasterxml.jackson.databind.DeserializationContext;
  6 +import com.fasterxml.jackson.databind.JsonDeserializer;
  7 +
  8 +import java.io.IOException;
  9 +import java.time.Instant;
  10 +import java.time.LocalDateTime;
  11 +import java.time.ZoneId;
  12 +
  13 +/**
  14 + * LocalDateTime反序列化规则
  15 + * <p>
  16 + * 会将毫秒级时间戳反序列化为LocalDateTime
  17 + */
  18 +public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
  19 +
  20 + public static final LocalDateTimeDeserializer INSTANCE = new LocalDateTimeDeserializer();
  21 +
  22 + @Override
  23 + public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
  24 + return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getValueAsLong()), ZoneId.systemDefault());
  25 + }
  26 +}
... ...
src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LocalDateTimeSerializer.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.jackson.ser;
  2 +
  3 +import com.fasterxml.jackson.core.JsonGenerator;
  4 +import com.fasterxml.jackson.databind.JsonSerializer;
  5 +import com.fasterxml.jackson.databind.SerializerProvider;
  6 +
  7 +import java.io.IOException;
  8 +import java.time.LocalDateTime;
  9 +import java.time.ZoneId;
  10 +
  11 +/**
  12 + * LocalDateTime序列化规则
  13 + * <p>
  14 + * 会将LocalDateTime序列化为毫秒级时间戳
  15 + */
  16 +public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
  17 +
  18 + public static final LocalDateTimeSerializer INSTANCE = new LocalDateTimeSerializer();
  19 +
  20 + @Override
  21 + public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
  22 + gen.writeNumber(value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
  23 + }
  24 +}
... ...
src/main/java/cn/iocoder/dashboard/framework/logger/apilog/core/filter/ApiAccessLogFilter.java
... ... @@ -81,7 +81,7 @@ public class ApiAccessLogFilter extends OncePerRequestFilter {
81 81 Map<String, String> queryString, String requestBody, Exception ex) {
82 82 // 处理用户信息
83 83 accessLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
84   - accessLog.setUserType(WebFrameworkUtils.getUesrType(request));
  84 + accessLog.setUserType(WebFrameworkUtils.getUserType(request));
85 85 // 设置访问结果
86 86 CommonResult<?> result = WebFrameworkUtils.getCommonResult(request);
87 87 if (result != null) {
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/config/RedisConfig.java
1 1 package cn.iocoder.dashboard.framework.redis.config;
2 2  
  3 +import cn.hutool.system.SystemUtil;
3 4 import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener;
  5 +import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener;
4 6 import lombok.extern.slf4j.Slf4j;
5 7 import org.springframework.context.annotation.Bean;
6 8 import org.springframework.context.annotation.Configuration;
7 9 import org.springframework.data.redis.connection.RedisConnectionFactory;
  10 +import org.springframework.data.redis.connection.stream.Consumer;
  11 +import org.springframework.data.redis.connection.stream.ObjectRecord;
  12 +import org.springframework.data.redis.connection.stream.ReadOffset;
  13 +import org.springframework.data.redis.connection.stream.StreamOffset;
8 14 import org.springframework.data.redis.core.RedisTemplate;
9 15 import org.springframework.data.redis.listener.ChannelTopic;
10 16 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
11 17 import org.springframework.data.redis.serializer.RedisSerializer;
  18 +import org.springframework.data.redis.stream.StreamMessageListenerContainer;
12 19  
13 20 import java.util.List;
14 21  
... ... @@ -19,6 +26,9 @@ import java.util.List;
19 26 @Slf4j
20 27 public class RedisConfig {
21 28  
  29 + /**
  30 + * 创建 RedisTemplate Bean,使用 JSON 序列化方式
  31 + */
22 32 @Bean
23 33 public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
24 34 // 创建 RedisTemplate 对象
... ... @@ -27,11 +37,16 @@ public class RedisConfig {
27 37 template.setConnectionFactory(factory);
28 38 // 使用 String 序列化方式,序列化 KEY 。
29 39 template.setKeySerializer(RedisSerializer.string());
  40 + template.setHashKeySerializer(RedisSerializer.string());
30 41 // 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
31 42 template.setValueSerializer(RedisSerializer.json());
  43 + template.setHashValueSerializer(RedisSerializer.json());
32 44 return template;
33 45 }
34 46  
  47 + /**
  48 + * 创建 Redis Pub/Sub 广播消费的容器
  49 + */
35 50 @Bean
36 51 public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory,
37 52 List<AbstractChannelMessageListener<?>> listeners) {
... ... @@ -48,4 +63,57 @@ public class RedisConfig {
48 63 return container;
49 64 }
50 65  
  66 + /**
  67 + * 创建 Redis Stream 集群消费的容器
  68 + *
  69 + * Redis Stream 的 xreadgroup 命令:https://www.geek-book.com/src/docs/redis/redis/redis.io/commands/xreadgroup.html
  70 + */
  71 + @Bean(initMethod = "start", destroyMethod = "stop")
  72 + public StreamMessageListenerContainer<String, ObjectRecord<String, String>> redisStreamMessageListenerContainer(RedisTemplate<String, Object> redisTemplate,
  73 + List<AbstractStreamMessageListener<?>> listeners) {
  74 + // 第一步,创建 StreamMessageListenerContainer 容器
  75 + // 创建 options 配置
  76 + StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, ObjectRecord<String, String>> containerOptions =
  77 + StreamMessageListenerContainer.StreamMessageListenerContainerOptions.builder()
  78 + .batchSize(10) // 一次性最多拉取多少条消息
  79 + .targetType(String.class) // 目标类型。统一使用 String,通过自己封装的 AbstractStreamMessageListener 去反序列化
  80 + .build();
  81 + // 创建 container 对象
  82 + StreamMessageListenerContainer<String, ObjectRecord<String, String>> container = StreamMessageListenerContainer.create(
  83 + redisTemplate.getRequiredConnectionFactory(), containerOptions);
  84 +
  85 + // 第二步,注册监听器,消费对应的 Stream 主题
  86 + String consumerName = buildConsumerName();
  87 +// String consumerName = "110";
  88 + listeners.forEach(listener -> {
  89 + // 创建 listener 对应的消费者分组
  90 + try {
  91 + redisTemplate.opsForStream().createGroup(listener.getStreamKey(), listener.getGroup());
  92 + } catch (Exception ignore) {}
  93 + // 设置 listener 对应的 redisTemplate
  94 + listener.setRedisTemplate(redisTemplate);
  95 + // 创建 Consumer 对象
  96 + Consumer consumer = Consumer.from(listener.getGroup(), consumerName);
  97 + // 设置 Consumer 消费进度,以最小消费进度为准
  98 + StreamOffset<String> streamOffset = StreamOffset.create(listener.getStreamKey(), ReadOffset.lastConsumed());
  99 + // 设置 Consumer 监听
  100 + StreamMessageListenerContainer.StreamReadRequestBuilder<String> builder = StreamMessageListenerContainer.StreamReadRequest
  101 + .builder(streamOffset).consumer(consumer)
  102 + .autoAcknowledge(false) // 不自动 ack
  103 + .cancelOnError(throwable -> false); // 默认配置,发生异常就取消消费,显然不符合预期;因此,我们设置为 false
  104 + container.register(builder.build(), listener);
  105 + });
  106 + return container;
  107 + }
  108 +
  109 + /**
  110 + * 构建消费者名字,使用本地 IP + 进程编号的方式。
  111 + * 参考自 RocketMQ clientId 的实现
  112 + *
  113 + * @return 消费者名字
  114 + */
  115 + private static String buildConsumerName() {
  116 + return String.format("%s@%d", SystemUtil.getHostInfo().getAddress(), SystemUtil.getCurrentPID());
  117 + }
  118 +
51 119 }
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/core/pubsub/AbstractChannelMessageListener.java
1 1 package cn.iocoder.dashboard.framework.redis.core.pubsub;
2 2  
3   -import cn.hutool.core.util.ArrayUtil;
  3 +import cn.hutool.core.util.TypeUtil;
4 4 import cn.iocoder.dashboard.util.json.JsonUtils;
5 5 import lombok.SneakyThrows;
6 6 import org.springframework.data.redis.connection.Message;
7 7 import org.springframework.data.redis.connection.MessageListener;
8   -import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
9 8  
10 9 import java.lang.reflect.Type;
11 10  
... ... @@ -62,21 +61,11 @@ public abstract class AbstractChannelMessageListener&lt;T extends ChannelMessage&gt; i
62 61 */
63 62 @SuppressWarnings("unchecked")
64 63 private Class<T> getMessageClass() {
65   - Class<?> targetClass = getClass();
66   - while (targetClass.getSuperclass() != null) {
67   - // 如果不是 AbstractMessageListener 父类,继续向上查找
68   - if (targetClass.getSuperclass() != AbstractChannelMessageListener.class) {
69   - targetClass = targetClass.getSuperclass();
70   - continue;
71   - }
72   - // 如果是 AbstractMessageListener 父类,则解析泛型
73   - Type[] types = ((ParameterizedTypeImpl) targetClass.getGenericSuperclass()).getActualTypeArguments();
74   - if (ArrayUtil.isEmpty(types)) {
75   - throw new IllegalStateException(String.format("类型(%s) 需要设置消息类型", getClass().getName()));
76   - }
77   - return (Class<T>) types[0];
  64 + Type type = TypeUtil.getTypeArgument(getClass(), 0);
  65 + if (type == null) {
  66 + throw new IllegalStateException(String.format("类型(%s) 需要设置消息类型", getClass().getName()));
78 67 }
79   - throw new IllegalStateException(String.format("类型(%s) 找不到 AbstractMessageListener 父类", getClass().getName()));
  68 + return (Class<T>) type;
80 69 }
81 70  
82 71 }
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/core/pubsub/ChannelMessage.java
... ... @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
4 4  
5 5 /**
6 6 * Redis Channel Message 接口
  7 + *
  8 + * @author 芋道源码
7 9 */
8 10 public interface ChannelMessage {
9 11  
... ... @@ -12,7 +14,7 @@ public interface ChannelMessage {
12 14 *
13 15 * @return Channel
14 16 */
15   - @JsonIgnore // 必须序列化
  17 + @JsonIgnore // 避免序列化
16 18 String getChannel();
17 19  
18 20 }
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/core/stream/AbstractStreamMessageListener.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.redis.core.stream;
  2 +
  3 +import cn.hutool.core.util.TypeUtil;
  4 +import cn.iocoder.dashboard.util.json.JsonUtils;
  5 +import lombok.Getter;
  6 +import lombok.Setter;
  7 +import lombok.SneakyThrows;
  8 +import org.springframework.beans.factory.annotation.Value;
  9 +import org.springframework.data.redis.connection.stream.ObjectRecord;
  10 +import org.springframework.data.redis.core.RedisTemplate;
  11 +import org.springframework.data.redis.stream.StreamListener;
  12 +
  13 +import java.lang.reflect.Type;
  14 +
  15 +/**
  16 + * Redis Stream 监听器抽象类,用于实现集群消费
  17 + *
  18 + * @param <T> 消息类型。一定要填写噢,不然会报错
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +public abstract class AbstractStreamMessageListener<T extends StreamMessage>
  23 + implements StreamListener<String, ObjectRecord<String, String>> {
  24 +
  25 + /**
  26 + * 消息类型
  27 + */
  28 + private final Class<T> messageType;
  29 + /**
  30 + * Redis Channel
  31 + */
  32 + @Getter
  33 + private final String streamKey;
  34 +
  35 + /**
  36 + * Redis 消费者分组,默认使用 spring.application.name 名字
  37 + */
  38 + @Value("${spring.application.name}")
  39 + @Getter
  40 + private String group;
  41 + /**
  42 + *
  43 + */
  44 + @Setter
  45 + private RedisTemplate<String, ?> redisTemplate;
  46 +
  47 + @SneakyThrows
  48 + protected AbstractStreamMessageListener() {
  49 + this.messageType = getMessageClass();
  50 + this.streamKey = messageType.newInstance().getStreamKey();
  51 + }
  52 +
  53 + @Override
  54 + public void onMessage(ObjectRecord<String, String> message) {
  55 + // 消费消息
  56 + T messageObj = JsonUtils.parseObject(message.getValue(), messageType);
  57 + this.onMessage(messageObj);
  58 + // ack 消息消费完成
  59 + redisTemplate.opsForStream().acknowledge(group, message);
  60 + // TODO 芋艿:需要额外考虑以下几个点:
  61 + // 1. 处理异常的情况
  62 + // 2. 发送日志;以及事务的结合
  63 + // 3. 消费日志;以及通用的幂等性
  64 + // 4. 消费失败的重试,https://zhuanlan.zhihu.com/p/60501638
  65 + }
  66 +
  67 + /**
  68 + * 处理消息
  69 + *
  70 + * @param message 消息
  71 + */
  72 + public abstract void onMessage(T message);
  73 +
  74 + /**
  75 + * 通过解析类上的泛型,获得消息类型
  76 + *
  77 + * @return 消息类型
  78 + */
  79 + @SuppressWarnings("unchecked")
  80 + private Class<T> getMessageClass() {
  81 + Type type = TypeUtil.getTypeArgument(getClass(), 0);
  82 + if (type == null) {
  83 + throw new IllegalStateException(String.format("类型(%s) 需要设置消息类型", getClass().getName()));
  84 + }
  85 + return (Class<T>) type;
  86 + }
  87 +
  88 +}
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/core/stream/StreamMessage.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.redis.core.stream;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonIgnore;
  4 +
  5 +/**
  6 + * Redis Stream Message 接口
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +public interface StreamMessage {
  11 +
  12 + /**
  13 + * 获得 Redis Stream Key
  14 + *
  15 + * @return Channel
  16 + */
  17 + @JsonIgnore // 避免序列化
  18 + String getStreamKey();
  19 +
  20 +}
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/core/util/RedisMessageUtils.java
1 1 package cn.iocoder.dashboard.framework.redis.core.util;
2 2  
3 3 import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage;
  4 +import cn.iocoder.dashboard.framework.redis.core.stream.StreamMessage;
4 5 import cn.iocoder.dashboard.util.json.JsonUtils;
  6 +import org.springframework.data.redis.connection.stream.RecordId;
  7 +import org.springframework.data.redis.connection.stream.StreamRecords;
5 8 import org.springframework.data.redis.core.RedisTemplate;
6 9  
7 10 /**
... ... @@ -17,8 +20,21 @@ public class RedisMessageUtils {
17 20 * @param redisTemplate Redis 操作模板
18 21 * @param message 消息
19 22 */
20   - public static <T extends ChannelMessage> void sendChannelMessage(RedisTemplate<?, ?> redisTemplate, T message) {
  23 + public static <T extends ChannelMessage> void sendChannelMessage(RedisTemplate<?, ?> redisTemplate, T message) {
21 24 redisTemplate.convertAndSend(message.getChannel(), JsonUtils.toJsonString(message));
22 25 }
23 26  
  27 + /**
  28 + * 发送 Redis 消息,基于 Redis Stream 实现
  29 + *
  30 + * @param redisTemplate Redis 操作模板
  31 + * @param message 消息
  32 + * @return 消息记录的编号对象
  33 + */
  34 + public static <T extends StreamMessage> RecordId sendStreamMessage(RedisTemplate<String, ?> redisTemplate, T message) {
  35 + return redisTemplate.opsForStream().add(StreamRecords.newRecord()
  36 + .ofObject(JsonUtils.toJsonString(message)) // 设置内容
  37 + .withStreamKey(message.getStreamKey())); // 设置 stream key
  38 + }
  39 +
24 40 }
... ...
src/main/java/cn/iocoder/dashboard/framework/web/core/handler/GlobalExceptionHandler.java
... ... @@ -269,7 +269,7 @@ public class GlobalExceptionHandler {
269 269 private void initExceptionLog(ApiErrorLogCreateDTO errorLog, HttpServletRequest request, Throwable e) {
270 270 // 处理用户信息
271 271 errorLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
272   - errorLog.setUserType(WebFrameworkUtils.getUesrType(request));
  272 + errorLog.setUserType(WebFrameworkUtils.getUserType(request));
273 273 // 设置异常字段
274 274 errorLog.setExceptionName(e.getClass().getName());
275 275 errorLog.setExceptionMessage(ExceptionUtil.getMessage(e));
... ...
src/main/java/cn/iocoder/dashboard/framework/web/core/util/WebFrameworkUtils.java
... ... @@ -31,7 +31,7 @@ public class WebFrameworkUtils {
31 31 return (Long) request.getAttribute(REQUEST_ATTRIBUTE_LOGIN_USER_ID);
32 32 }
33 33  
34   - public static Integer getUesrType(HttpServletRequest request) {
  34 + public static Integer getUserType(HttpServletRequest request) {
35 35 return UserTypeEnum.ADMIN.getValue(); // TODO 芋艿:等后续优化
36 36 }
37 37  
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java
... ... @@ -19,6 +19,7 @@ import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
19 19 import cn.iocoder.dashboard.util.collection.SetUtils;
20 20 import io.swagger.annotations.Api;
21 21 import io.swagger.annotations.ApiOperation;
  22 +import org.springframework.validation.annotation.Validated;
22 23 import org.springframework.web.bind.annotation.*;
23 24  
24 25 import javax.annotation.Resource;
... ... @@ -34,6 +35,7 @@ import static cn.iocoder.dashboard.util.servlet.ServletUtils.getUserAgent;
34 35 @Api(tags = "认证")
35 36 @RestController
36 37 @RequestMapping("/")
  38 +@Validated
37 39 public class SysAuthController {
38 40  
39 41 @Resource
... ... @@ -45,8 +47,8 @@ public class SysAuthController {
45 47 @Resource
46 48 private SysPermissionService permissionService;
47 49  
48   - @ApiOperation("使用账号密码登录")
49 50 @PostMapping("/login")
  51 + @ApiOperation("使用账号密码登录")
50 52 @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
51 53 public CommonResult<SysAuthLoginRespVO> login(@RequestBody @Valid SysAuthLoginReqVO reqVO) {
52 54 String token = authService.login(reqVO, getClientIP(), getUserAgent());
... ... @@ -54,8 +56,8 @@ public class SysAuthController {
54 56 return success(SysAuthLoginRespVO.builder().token(token).build());
55 57 }
56 58  
57   - @ApiOperation("获取登陆用户的权限信息")
58 59 @GetMapping("/get-permission-info")
  60 + @ApiOperation("获取登陆用户的权限信息")
59 61 public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() {
60 62 // 获得用户信息
61 63 SysUserDO user = userService.getUser(getLoginUserId());
... ... @@ -63,9 +65,9 @@ public class SysAuthController {
63 65 return null;
64 66 }
65 67 // 获得角色列表
66   - List<SysRoleDO> roleList = roleService.listRolesFromCache(getLoginUserRoleIds());
  68 + List<SysRoleDO> roleList = roleService.getRolesFromCache(getLoginUserRoleIds());
67 69 // 获得菜单列表
68   - List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(
  70 + List<SysMenuDO> menuList = permissionService.getRoleMenusFromCache(
69 71 getLoginUserRoleIds(), // 注意,基于登陆的角色,因为后续的权限判断也是基于它
70 72 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()),
71 73 SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus()));
... ... @@ -73,11 +75,11 @@ public class SysAuthController {
73 75 return success(SysAuthConvert.INSTANCE.convert(user, roleList, menuList));
74 76 }
75 77  
76   - @ApiOperation("获得登陆用户的菜单列表")
77 78 @GetMapping("list-menus")
78   - public CommonResult<List<SysAuthMenuRespVO>> listMenus() {
  79 + @ApiOperation("获得登陆用户的菜单列表")
  80 + public CommonResult<List<SysAuthMenuRespVO>> getMenus() {
79 81 // 获得用户拥有的菜单列表
80   - List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(
  82 + List<SysMenuDO> menuList = permissionService.getRoleMenusFromCache(
81 83 getLoginUserRoleIds(), // 注意,基于登陆的角色,因为后续的权限判断也是基于它
82 84 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()), // 只要目录和菜单类型
83 85 SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysUserSessionController.java
... ... @@ -39,9 +39,9 @@ public class SysUserSessionController {
39 39 @Resource
40 40 private SysDeptService deptService;
41 41  
  42 + @GetMapping("/page")
42 43 @ApiOperation("获得 Session 分页列表")
43 44 @PreAuthorize("@ss.hasPermission('system:user-session:page')")
44   - @GetMapping("/page")
45 45 public CommonResult<PageResult<SysUserSessionPageItemRespVO>> getUserSessionPage(@Validated SysUserSessionPageReqVO reqVO) {
46 46 // 获得 Session 分页
47 47 PageResult<SysUserSessionDO> pageResult = userSessionService.getUserSessionPage(reqVO);
... ... @@ -66,12 +66,12 @@ public class SysUserSessionController {
66 66 return success(new PageResult<>(sessionList, pageResult.getTotal()));
67 67 }
68 68  
69   - @ApiOperation("删除 Session")
70   - @PreAuthorize("@ss.hasPermission('system:user-session:delete')")
71 69 @DeleteMapping("/delete")
  70 + @ApiOperation("删除 Session")
72 71 @ApiImplicitParam(name = "id", value = "Session 编号", required = true, dataTypeClass = String.class,
73 72 example = "fe50b9f6-d177-44b1-8da9-72ea34f63db7")
74   - public CommonResult<Boolean> delete(@RequestParam("id") String id) {
  73 + @PreAuthorize("@ss.hasPermission('system:user-session:delete')")
  74 + public CommonResult<Boolean> deleteUserSession(@RequestParam("id") String id) {
75 75 userSessionService.deleteUserSession(id);
76 76 return success(true);
77 77 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysDeptController.java
... ... @@ -9,10 +9,12 @@ import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
9 9 import io.swagger.annotations.Api;
10 10 import io.swagger.annotations.ApiImplicitParam;
11 11 import io.swagger.annotations.ApiOperation;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
12 13 import org.springframework.validation.annotation.Validated;
13 14 import org.springframework.web.bind.annotation.*;
14 15  
15 16 import javax.annotation.Resource;
  17 +import javax.validation.Valid;
16 18 import java.util.Comparator;
17 19 import java.util.List;
18 20  
... ... @@ -21,65 +23,64 @@ import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
21 23 @Api(tags = "部门")
22 24 @RestController
23 25 @RequestMapping("/system/dept")
  26 +@Validated
24 27 public class SysDeptController {
25 28  
26 29 @Resource
27 30 private SysDeptService deptService;
28 31  
29   - @ApiOperation("获取部门列表")
30   -// @PreAuthorize("@ss.hasPermi('system:dept:list')")
  32 + @PostMapping("create")
  33 + @ApiOperation("创建部门")
  34 + @PreAuthorize("@ss.hasPermission('system:dept:create')")
  35 + public CommonResult<Long> createDept(@Valid @RequestBody SysDeptCreateReqVO reqVO) {
  36 + Long deptId = deptService.createDept(reqVO);
  37 + return success(deptId);
  38 + }
  39 +
  40 + @PutMapping("update")
  41 + @ApiOperation("更新部门")
  42 + @PreAuthorize("@ss.hasPermission('system:dept:update')")
  43 + public CommonResult<Boolean> updateDept(@Valid @RequestBody SysDeptUpdateReqVO reqVO) {
  44 + deptService.updateDept(reqVO);
  45 + return success(true);
  46 + }
  47 +
  48 + @DeleteMapping("delete")
  49 + @ApiOperation("删除部门")
  50 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  51 + @PreAuthorize("@ss.hasPermission('system:dept:delete')")
  52 + public CommonResult<Boolean> deleteDept(@RequestParam("id") Long id) {
  53 + deptService.deleteDept(id);
  54 + return success(true);
  55 + }
  56 +
31 57 @GetMapping("/list")
  58 + @ApiOperation("获取部门列表")
  59 + @PreAuthorize("@ss.hasPermission('system:dept:query')")
32 60 public CommonResult<List<SysDeptRespVO>> listDepts(SysDeptListReqVO reqVO) {
33   - List<SysDeptDO> list = deptService.listDepts(reqVO);
  61 + List<SysDeptDO> list = deptService.getSimpleDepts(reqVO);
34 62 list.sort(Comparator.comparing(SysDeptDO::getSort));
35 63 return success(SysDeptConvert.INSTANCE.convertList(list));
36 64 }
37 65  
38   - @ApiOperation(value = "获取部门精简信息列表", notes = "只包含被开启的部门,主要用于前端的下拉选项")
39 66 @GetMapping("/list-all-simple")
40   - public CommonResult<List<SysDeptSimpleRespVO>> listSimpleDepts() {
  67 + @ApiOperation(value = "获取部门精简信息列表", notes = "只包含被开启的部门,主要用于前端的下拉选项")
  68 + public CommonResult<List<SysDeptSimpleRespVO>> getSimpleDepts() {
41 69 // 获得部门列表,只要开启状态的
42 70 SysDeptListReqVO reqVO = new SysDeptListReqVO();
43 71 reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
44   - List<SysDeptDO> list = deptService.listDepts(reqVO);
  72 + List<SysDeptDO> list = deptService.getSimpleDepts(reqVO);
45 73 // 排序后,返回给前端
46 74 list.sort(Comparator.comparing(SysDeptDO::getSort));
47 75 return success(SysDeptConvert.INSTANCE.convertList02(list));
48 76 }
49 77  
  78 + @GetMapping("/get")
50 79 @ApiOperation("获得部门信息")
51 80 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
52   -// @PreAuthorize("@ss.hasPermi('system:dept:query')")
53   - @GetMapping("/get")
  81 + @PreAuthorize("@ss.hasPermission('system:dept:query')")
54 82 public CommonResult<SysDeptRespVO> getDept(@RequestParam("id") Long id) {
55 83 return success(SysDeptConvert.INSTANCE.convert(deptService.getDept(id)));
56 84 }
57 85  
58   - @ApiOperation("新增部门")
59   - @PostMapping("create")
60   -// @PreAuthorize("@ss.hasPermi('system:dept:add')")
61   -// @Log(title = "部门管理", businessType = BusinessType.INSERT)
62   - public CommonResult<Long> createDept(@Validated @RequestBody SysDeptCreateReqVO reqVO) {
63   - Long deptId = deptService.createDept(reqVO);
64   - return success(deptId);
65   - }
66   -
67   - @ApiOperation("修改部门")
68   - @PostMapping("update")
69   -// @PreAuthorize("@ss.hasPermi('system:dept:edit')")
70   -// @Log(title = "部门管理", businessType = BusinessType.UPDATE)
71   - public CommonResult<Boolean> updateDept(@Validated @RequestBody SysDeptUpdateReqVO reqVO) {
72   - deptService.updateDept(reqVO);
73   - return success(true);
74   - }
75   -
76   - @ApiOperation("删除部门")
77   - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
78   - @PostMapping("delete")
79   -// @PreAuthorize("@ss.hasPermi('system:dept:remove')")
80   -// @Log(title = "部门管理", businessType = BusinessType.DELETE)
81   - public CommonResult<Boolean> deleteDept(@RequestParam("id") Long id) {
82   - deptService.deleteDept(id);
83   - return success(true);
84   - }
85 86 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysPostController.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.dashboard.common.pojo.CommonResult;
5 5 import cn.iocoder.dashboard.common.pojo.PageResult;
6 6 import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
  7 +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
7 8 import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.*;
8 9 import cn.iocoder.dashboard.modules.system.convert.dept.SysPostConvert;
9 10 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
... ... @@ -11,88 +12,88 @@ import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
11 12 import io.swagger.annotations.Api;
12 13 import io.swagger.annotations.ApiImplicitParam;
13 14 import io.swagger.annotations.ApiOperation;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
14 16 import org.springframework.validation.annotation.Validated;
15 17 import org.springframework.web.bind.annotation.*;
16 18  
17 19 import javax.annotation.Resource;
18 20 import javax.servlet.http.HttpServletResponse;
  21 +import javax.validation.Valid;
19 22 import java.io.IOException;
20 23 import java.util.Collections;
21 24 import java.util.Comparator;
22 25 import java.util.List;
23 26  
24 27 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
  28 +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
25 29  
26 30 @Api(tags = "岗位")
27 31 @RestController
28 32 @RequestMapping("/system/post")
  33 +@Valid
29 34 public class SysPostController {
30 35  
31 36 @Resource
32 37 private SysPostService postService;
33 38  
34   - @ApiOperation(value = "获取岗位精简信息列表", notes = "只包含被开启的岗位,主要用于前端的下拉选项")
35   - @GetMapping("/list-all-simple")
36   - public CommonResult<List<SysPostSimpleRespVO>> listSimplePosts() {
37   - // 获得岗位列表,只要开启状态的
38   - List<SysPostDO> list = postService.listPosts(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
39   - // 排序后,返回给前端
40   - list.sort(Comparator.comparing(SysPostDO::getSort));
41   - return success(SysPostConvert.INSTANCE.convertList02(list));
42   - }
43   -
44   - @ApiOperation("获得岗位分页列表")
45   - @GetMapping("/page")
46   -// @PreAuthorize("@ss.hasPermi('system:post:list')")
47   - public CommonResult<PageResult<SysPostRespVO>> pagePosts(@Validated SysPostPageReqVO reqVO) {
48   - return success(SysPostConvert.INSTANCE.convertPage(postService.pagePosts(reqVO)));
49   - }
50   -
51   - @ApiOperation("新增岗位")
52 39 @PostMapping("/create")
53   -// @PreAuthorize("@ss.hasPermi('system:post:add')")
54   -// @Log(title = "岗位管理", businessType = BusinessType.INSERT)
55   - public CommonResult<Long> createPost(@Validated @RequestBody SysPostCreateReqVO reqVO) {
  40 + @ApiOperation("创建岗位")
  41 + @PreAuthorize("@ss.hasPermission('system:post:create')")
  42 + public CommonResult<Long> createPost(@Valid @RequestBody SysPostCreateReqVO reqVO) {
56 43 Long postId = postService.createPost(reqVO);
57 44 return success(postId);
58 45 }
59 46  
  47 + @PutMapping("/update")
60 48 @ApiOperation("修改岗位")
61   - @PostMapping("/update")
62   -// @PreAuthorize("@ss.hasPermi('system:post:edit')")
63   -// @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
64   - public CommonResult<Boolean> updatePost(@Validated @RequestBody SysPostUpdateReqVO reqVO) {
  49 + @PreAuthorize("@ss.hasPermission('system:post:update')")
  50 + public CommonResult<Boolean> updatePost(@Valid @RequestBody SysPostUpdateReqVO reqVO) {
65 51 postService.updatePost(reqVO);
66 52 return success(true);
67 53 }
68 54  
  55 + @DeleteMapping("/delete")
69 56 @ApiOperation("删除岗位")
70   - @PostMapping("/delete")
71   -// @PreAuthorize("@ss.hasPermi('system:post:remove')")
72   -// @Log(title = "岗位管理", businessType = BusinessType.DELETE)
  57 + @PreAuthorize("@ss.hasPermission('system:post:delete')")
73 58 public CommonResult<Boolean> deletePost(@RequestParam("id") Long id) {
74 59 postService.deletePost(id);
75 60 return success(true);
76 61 }
77 62  
  63 + @GetMapping(value = "/get")
78 64 @ApiOperation("获得岗位信息")
79 65 @ApiImplicitParam(name = "id", value = "岗位编号", required = true, example = "1024", dataTypeClass = Long.class)
80   -// @PreAuthorize("@ss.hasPermi('system:post:query')")
81   - @GetMapping(value = "/get")
  66 + @PreAuthorize("@ss.hasPermission('system:post:query')")
82 67 public CommonResult<SysPostRespVO> getPost(@RequestParam("id") Long id) {
83 68 return success(SysPostConvert.INSTANCE.convert(postService.getPost(id)));
84 69 }
85 70  
  71 + @GetMapping("/list-all-simple")
  72 + @ApiOperation(value = "获取岗位精简信息列表", notes = "只包含被开启的岗位,主要用于前端的下拉选项")
  73 + public CommonResult<List<SysPostSimpleRespVO>> getSimplePosts() {
  74 + // 获得岗位列表,只要开启状态的
  75 + List<SysPostDO> list = postService.getPosts(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
  76 + // 排序后,返回给前端
  77 + list.sort(Comparator.comparing(SysPostDO::getSort));
  78 + return success(SysPostConvert.INSTANCE.convertList02(list));
  79 + }
  80 +
  81 + @GetMapping("/page")
  82 + @ApiOperation("获得岗位分页列表")
  83 + @PreAuthorize("@ss.hasPermission('system:post:query')")
  84 + public CommonResult<PageResult<SysPostRespVO>> getPostPage(@Validated SysPostPageReqVO reqVO) {
  85 + return success(SysPostConvert.INSTANCE.convertPage(postService.getPostPage(reqVO)));
  86 + }
  87 +
86 88 @GetMapping("/export")
87 89 @ApiOperation("岗位管理")
88   -// @Log(title = "岗位管理", businessType = BusinessType.EXPORT)
89   -// @PreAuthorize("@ss.hasPermi('system:post:export')")
  90 + @PreAuthorize("@ss.hasPermission('system:post:export')")
  91 + @OperateLog(type = EXPORT)
90 92 public void export(HttpServletResponse response, @Validated SysPostExportReqVO reqVO) throws IOException {
91   - List<SysPostDO> posts = postService.listPosts(reqVO);
92   - List<SysPostExcelVO> excelDataList = SysPostConvert.INSTANCE.convertList03(posts);
  93 + List<SysPostDO> posts = postService.getPosts(reqVO);
  94 + List<SysPostExcelVO> data = SysPostConvert.INSTANCE.convertList03(posts);
93 95 // 输出
94   - ExcelUtils.write(response, "岗位数据.xls", "岗位列表",
95   - SysPostExcelVO.class, excelDataList);
  96 + ExcelUtils.write(response, "岗位数据.xls", "岗位列表", SysPostExcelVO.class, data);
96 97 }
97 98  
98 99 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictDataController.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.dict;
3 3 import cn.iocoder.dashboard.common.pojo.CommonResult;
4 4 import cn.iocoder.dashboard.common.pojo.PageResult;
5 5 import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
  6 +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
6 7 import cn.iocoder.dashboard.modules.system.controller.dict.vo.data.*;
7 8 import cn.iocoder.dashboard.modules.system.convert.dict.SysDictDataConvert;
8 9 import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictDataDO;
... ... @@ -10,84 +11,85 @@ import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService;
10 11 import io.swagger.annotations.Api;
11 12 import io.swagger.annotations.ApiImplicitParam;
12 13 import io.swagger.annotations.ApiOperation;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
13 15 import org.springframework.validation.annotation.Validated;
14 16 import org.springframework.web.bind.annotation.*;
15 17  
16 18 import javax.annotation.Resource;
17 19 import javax.servlet.http.HttpServletResponse;
  20 +import javax.validation.Valid;
18 21 import java.io.IOException;
19 22 import java.util.List;
20 23  
21 24 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
  25 +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
22 26  
23 27 @Api(tags = "字典数据")
24 28 @RestController
25 29 @RequestMapping("/system/dict-data")
  30 +@Validated
26 31 public class SysDictDataController {
27 32  
28 33 @Resource
29 34 private SysDictDataService dictDataService;
30 35  
31   - @ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地")
32   - @GetMapping("/list-all-simple")
33   - // 无需添加权限认证,因为前端全局都需要
34   - public CommonResult<List<SysDictDataSimpleVO>> listSimpleDictDatas() {
35   - List<SysDictDataDO> list = dictDataService.getDictDataList();
36   - return success(SysDictDataConvert.INSTANCE.convertList(list));
37   - }
38   -
39   - @ApiOperation("/获得字典类型的分页列表")
40   - @GetMapping("/page")
41   -// @PreAuthorize("@ss.hasPermi('system:dict:list')")
42   - public CommonResult<PageResult<SysDictDataRespVO>> pageDictTypes(@Validated SysDictDataPageReqVO reqVO) {
43   - return success(SysDictDataConvert.INSTANCE.convertPage(dictDataService.getDictDataPage(reqVO)));
44   - }
45   -
46   - @ApiOperation("/查询字典数据详细")
47   - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
48   - @GetMapping(value = "/get")
49   -// @PreAuthorize("@ss.hasPermi('system:dict:query')")
50   - public CommonResult<SysDictDataRespVO> getDictData(@RequestParam("id") Long id) {
51   - return success(SysDictDataConvert.INSTANCE.convert(dictDataService.getDictData(id)));
52   - }
53   -
54   - @ApiOperation("新增字典数据")
55 36 @PostMapping("/create")
56   -// @PreAuthorize("@ss.hasPermi('system:dict:add')")
57   -// @Log(title = "字典数据", businessData = BusinessData.INSERT)
58   - public CommonResult<Long> createDictData(@Validated @RequestBody SysDictDataCreateReqVO reqVO) {
  37 + @ApiOperation("新增字典数据")
  38 + @PreAuthorize("@ss.hasPermission('system:dict:create')")
  39 + public CommonResult<Long> createDictData(@Valid @RequestBody SysDictDataCreateReqVO reqVO) {
59 40 Long dictDataId = dictDataService.createDictData(reqVO);
60 41 return success(dictDataId);
61 42 }
62 43  
  44 + @PutMapping("update")
63 45 @ApiOperation("修改字典数据")
64   - @PostMapping("update")
65   -// @PreAuthorize("@ss.hasPermi('system:dict:edit')")
66   -// @Log(title = "字典数据", businessData = BusinessData.UPDATE)
67   - public CommonResult<Boolean> updateDictData(@Validated @RequestBody SysDictDataUpdateReqVO reqVO) {
  46 + @PreAuthorize("@ss.hasPermission('system:dict:update')")
  47 + public CommonResult<Boolean> updateDictData(@Valid @RequestBody SysDictDataUpdateReqVO reqVO) {
68 48 dictDataService.updateDictData(reqVO);
69 49 return success(true);
70 50 }
71 51  
  52 + @DeleteMapping("/delete")
72 53 @ApiOperation("删除字典数据")
73 54 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
74   - @PostMapping("/delete")
75   -// @PreAuthorize("@ss.hasPermi('system:dict:remove')")
  55 + @PreAuthorize("@ss.hasPermission('system:dict:delete')")
76 56 public CommonResult<Boolean> deleteDictData(Long id) {
77 57 dictDataService.deleteDictData(id);
78 58 return success(true);
79 59 }
80 60  
81   - @ApiOperation("导出字典数据")
  61 + @GetMapping("/list-all-simple")
  62 + @ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地")
  63 + // 无需添加权限认证,因为前端全局都需要
  64 + public CommonResult<List<SysDictDataSimpleVO>> getSimpleDictDatas() {
  65 + List<SysDictDataDO> list = dictDataService.getDictDatas();
  66 + return success(SysDictDataConvert.INSTANCE.convertList(list));
  67 + }
  68 +
  69 + @GetMapping("/page")
  70 + @ApiOperation("/获得字典类型的分页列表")
  71 + @PreAuthorize("@ss.hasPermission('system:dict:query')")
  72 + public CommonResult<PageResult<SysDictDataRespVO>> getDictTypePage(@Valid SysDictDataPageReqVO reqVO) {
  73 + return success(SysDictDataConvert.INSTANCE.convertPage(dictDataService.getDictDataPage(reqVO)));
  74 + }
  75 +
  76 + @GetMapping(value = "/get")
  77 + @ApiOperation("/查询字典数据详细")
  78 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  79 + @PreAuthorize("@ss.hasPermission('system:dict:query')")
  80 + public CommonResult<SysDictDataRespVO> getDictData(@RequestParam("id") Long id) {
  81 + return success(SysDictDataConvert.INSTANCE.convert(dictDataService.getDictData(id)));
  82 + }
  83 +
82 84 @GetMapping("/export")
83   -// @Log(title = "字典类型", businessType = BusinessType.EXPORT)
84   -// @PreAuthorize("@ss.hasPermi('system:dict:export')")
85   - public void export(HttpServletResponse response, @Validated SysDictDataExportReqVO reqVO) throws IOException {
86   - List<SysDictDataDO> list = dictDataService.getDictDataList(reqVO);
87   - List<SysDictDataExcelVO> excelDataList = SysDictDataConvert.INSTANCE.convertList02(list);
  85 + @ApiOperation("导出字典数据")
  86 + @PreAuthorize("@ss.hasPermission('system:dict:export')")
  87 + @OperateLog(type = EXPORT)
  88 + public void export(HttpServletResponse response, @Valid SysDictDataExportReqVO reqVO) throws IOException {
  89 + List<SysDictDataDO> list = dictDataService.getDictDatas(reqVO);
  90 + List<SysDictDataExcelVO> data = SysDictDataConvert.INSTANCE.convertList02(list);
88 91 // 输出
89   - ExcelUtils.write(response, "字典数据.xls", "数据列表",
90   - SysDictDataExcelVO.class, excelDataList);
  92 + ExcelUtils.write(response, "字典数据.xls", "数据列表", SysDictDataExcelVO.class, data);
91 93 }
92 94  
93 95 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictTypeController.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.dict;
3 3 import cn.iocoder.dashboard.common.pojo.CommonResult;
4 4 import cn.iocoder.dashboard.common.pojo.PageResult;
5 5 import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
  6 +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
6 7 import cn.iocoder.dashboard.modules.system.controller.dict.vo.type.*;
7 8 import cn.iocoder.dashboard.modules.system.convert.dict.SysDictTypeConvert;
8 9 import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictTypeDO;
... ... @@ -10,66 +11,67 @@ import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService;
10 11 import io.swagger.annotations.Api;
11 12 import io.swagger.annotations.ApiImplicitParam;
12 13 import io.swagger.annotations.ApiOperation;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
13 15 import org.springframework.validation.annotation.Validated;
14 16 import org.springframework.web.bind.annotation.*;
15 17  
16 18 import javax.annotation.Resource;
17 19 import javax.servlet.http.HttpServletResponse;
  20 +import javax.validation.Valid;
18 21 import java.io.IOException;
19 22 import java.util.List;
20 23  
21 24 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
  25 +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
22 26  
23 27 @Api(tags = "字典类型")
24 28 @RestController
25 29 @RequestMapping("/system/dict-type")
  30 +@Validated
26 31 public class SysDictTypeController {
27 32  
28 33 @Resource
29 34 private SysDictTypeService dictTypeService;
30 35  
31   - @ApiOperation("/获得字典类型的分页列表")
32   - @GetMapping("/page")
33   -// @PreAuthorize("@ss.hasPermi('system:dict:list')")
34   - public CommonResult<PageResult<SysDictTypeRespVO>> pageDictTypes(@Validated SysDictTypePageReqVO reqVO) {
35   - return success(SysDictTypeConvert.INSTANCE.convertPage(dictTypeService.getDictTypePage(reqVO)));
36   - }
37   -
38   - @ApiOperation("/查询字典类型详细")
39   - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
40   - @GetMapping(value = "/get")
41   -// @PreAuthorize("@ss.hasPermi('system:dict:query')")
42   - public CommonResult<SysDictTypeRespVO> getDictType(@RequestParam("id") Long id) {
43   - return success(SysDictTypeConvert.INSTANCE.convert(dictTypeService.getDictType(id)));
44   - }
45   -
46   - @ApiOperation("新增字典类型")
47 36 @PostMapping("/create")
48   -// @PreAuthorize("@ss.hasPermi('system:dict:add')")
49   -// @Log(title = "字典类型", businessType = BusinessType.INSERT)
50   - public CommonResult<Long> createDictType(@Validated @RequestBody SysDictTypeCreateReqVO reqVO) {
  37 + @ApiOperation("创建字典类型")
  38 + @PreAuthorize("@ss.hasPermission('system:dict:create')")
  39 + public CommonResult<Long> createDictType(@Valid @RequestBody SysDictTypeCreateReqVO reqVO) {
51 40 Long dictTypeId = dictTypeService.createDictType(reqVO);
52 41 return success(dictTypeId);
53 42 }
54 43  
55   - @ApiOperation("修改字典类型")
56 44 @PostMapping("update")
57   -// @PreAuthorize("@ss.hasPermi('system:dict:edit')")
58   -// @Log(title = "字典类型", businessType = BusinessType.UPDATE)
59   - public CommonResult<Boolean> updateDictType(@Validated @RequestBody SysDictTypeUpdateReqVO reqVO) {
  45 + @ApiOperation("修改字典类型")
  46 + @PreAuthorize("@ss.hasPermission('system:dict:update')")
  47 + public CommonResult<Boolean> updateDictType(@Valid @RequestBody SysDictTypeUpdateReqVO reqVO) {
60 48 dictTypeService.updateDictType(reqVO);
61 49 return success(true);
62 50 }
63 51  
  52 + @DeleteMapping("/delete")
64 53 @ApiOperation("删除字典类型")
65 54 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
66   - @PostMapping("/delete")
67   -// @PreAuthorize("@ss.hasPermi('system:dict:remove')")
  55 + @PreAuthorize("@ss.hasPermission('system:dict:delete')")
68 56 public CommonResult<Boolean> deleteDictType(Long id) {
69 57 dictTypeService.deleteDictType(id);
70 58 return success(true);
71 59 }
72 60  
  61 + @ApiOperation("/获得字典类型的分页列表")
  62 + @GetMapping("/page")
  63 + @PreAuthorize("@ss.hasPermission('system:dict:quey')")
  64 + public CommonResult<PageResult<SysDictTypeRespVO>> pageDictTypes(@Valid SysDictTypePageReqVO reqVO) {
  65 + return success(SysDictTypeConvert.INSTANCE.convertPage(dictTypeService.getDictTypePage(reqVO)));
  66 + }
  67 +
  68 + @ApiOperation("/查询字典类型详细")
  69 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  70 + @GetMapping(value = "/get")
  71 + @PreAuthorize("@ss.hasPermission('system:dict:quey')")
  72 + public CommonResult<SysDictTypeRespVO> getDictType(@RequestParam("id") Long id) {
  73 + return success(SysDictTypeConvert.INSTANCE.convert(dictTypeService.getDictType(id)));
  74 + }
73 75  
74 76 @GetMapping("/list-all-simple")
75 77 @ApiOperation(value = "获得全部字典类型列表", notes = "包括开启 + 禁用的字典类型,主要用于前端的下拉选项")
... ... @@ -81,14 +83,13 @@ public class SysDictTypeController {
81 83  
82 84 @ApiOperation("导出数据类型")
83 85 @GetMapping("/export")
84   -// @Log(title = "字典类型", businessType = BusinessType.EXPORT)
85   -// @PreAuthorize("@ss.hasPermi('system:dict:export')")
86   - public void export(HttpServletResponse response, @Validated SysDictTypeExportReqVO reqVO) throws IOException {
  86 + @PreAuthorize("@ss.hasPermission('system:dict:quey')")
  87 + @OperateLog(type = EXPORT)
  88 + public void export(HttpServletResponse response, @Valid SysDictTypeExportReqVO reqVO) throws IOException {
87 89 List<SysDictTypeDO> list = dictTypeService.getDictTypeList(reqVO);
88   - List<SysDictTypeExcelVO> excelTypeList = SysDictTypeConvert.INSTANCE.convertList02(list);
  90 + List<SysDictTypeExcelVO> data = SysDictTypeConvert.INSTANCE.convertList02(list);
89 91 // 输出
90   - ExcelUtils.write(response, "字典类型.xls", "类型列表",
91   - SysDictTypeExcelVO.class, excelTypeList);
  92 + ExcelUtils.write(response, "字典类型.xls", "类型列表", SysDictTypeExcelVO.class, data);
92 93 }
93 94  
94 95 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysLoginLogController.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.logger;
3 3 import cn.iocoder.dashboard.common.pojo.CommonResult;
4 4 import cn.iocoder.dashboard.common.pojo.PageResult;
5 5 import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
  6 +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
6 7 import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogExcelVO;
7 8 import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogExportReqVO;
8 9 import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogPageReqVO;
... ... @@ -12,6 +13,7 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.logger.SysLoginLogDO;
12 13 import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService;
13 14 import io.swagger.annotations.Api;
14 15 import io.swagger.annotations.ApiOperation;
  16 +import org.springframework.security.access.prepost.PreAuthorize;
15 17 import org.springframework.validation.annotation.Validated;
16 18 import org.springframework.web.bind.annotation.GetMapping;
17 19 import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -19,36 +21,39 @@ import org.springframework.web.bind.annotation.RestController;
19 21  
20 22 import javax.annotation.Resource;
21 23 import javax.servlet.http.HttpServletResponse;
  24 +import javax.validation.Valid;
22 25 import java.io.IOException;
23 26 import java.util.List;
24 27  
  28 +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
  29 +
25 30 @Api(tags = "登陆日志")
26 31 @RestController
27 32 @RequestMapping("/system/login-log")
  33 +@Validated
28 34 public class SysLoginLogController {
29 35  
30 36 @Resource
31 37 private SysLoginLogService loginLogService;
32 38  
33   - @ApiOperation("获得登陆日志分页列表")
34 39 @GetMapping("/page")
35   -// @PreAuthorize("@ss.hasPermi('system:login-log:query')")
36   - public CommonResult<PageResult<SysLoginLogRespVO>> getLoginLogPage(@Validated SysLoginLogPageReqVO reqVO) {
  40 + @ApiOperation("获得登陆日志分页列表")
  41 + @PreAuthorize("@ss.hasPermission('system:login-log:query')")
  42 + public CommonResult<PageResult<SysLoginLogRespVO>> getLoginLogPage(@Valid SysLoginLogPageReqVO reqVO) {
37 43 PageResult<SysLoginLogDO> page = loginLogService.getLoginLogPage(reqVO);
38 44 return CommonResult.success(SysLoginLogConvert.INSTANCE.convertPage(page));
39 45 }
40 46  
41   - @ApiOperation("导出登陆日志 Excel")
42 47 @GetMapping("/export")
43   -// @Log(title = "登录日志", businessType = BusinessType.EXPORT)
44   -// @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
45   - public void exportLoginLog(HttpServletResponse response, @Validated SysLoginLogExportReqVO reqVO) throws IOException {
  48 + @ApiOperation("导出登陆日志 Excel")
  49 + @PreAuthorize("@ss.hasPermission('system:login-log:export')")
  50 + @OperateLog(type = EXPORT)
  51 + public void exportLoginLog(HttpServletResponse response, @Valid SysLoginLogExportReqVO reqVO) throws IOException {
46 52 List<SysLoginLogDO> list = loginLogService.getLoginLogList(reqVO);
47 53 // 拼接数据
48   - List<SysLoginLogExcelVO> excelDataList = SysLoginLogConvert.INSTANCE.convertList(list);
  54 + List<SysLoginLogExcelVO> data = SysLoginLogConvert.INSTANCE.convertList(list);
49 55 // 输出
50   - ExcelUtils.write(response, "登陆日志.xls", "数据列表",
51   - SysLoginLogExcelVO.class, excelDataList);
  56 + ExcelUtils.write(response, "登陆日志.xls", "数据列表", SysLoginLogExcelVO.class, data);
52 57 }
53 58  
54 59 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysOperateLogController.java
... ... @@ -4,8 +4,6 @@ import cn.iocoder.dashboard.common.pojo.CommonResult;
4 4 import cn.iocoder.dashboard.common.pojo.PageResult;
5 5 import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
6 6 import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
7   -import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum;
8   -import cn.iocoder.dashboard.framework.logger.operatelog.core.util.OperateLogUtils;
9 7 import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogExcelVO;
10 8 import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogExportReqVO;
11 9 import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogPageReqVO;
... ... @@ -19,6 +17,7 @@ import cn.iocoder.dashboard.util.collection.CollectionUtils;
19 17 import cn.iocoder.dashboard.util.collection.MapUtils;
20 18 import io.swagger.annotations.Api;
21 19 import io.swagger.annotations.ApiOperation;
  20 +import org.springframework.security.access.prepost.PreAuthorize;
22 21 import org.springframework.validation.annotation.Validated;
23 22 import org.springframework.web.bind.annotation.GetMapping;
24 23 import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -26,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
26 25  
27 26 import javax.annotation.Resource;
28 27 import javax.servlet.http.HttpServletResponse;
  28 +import javax.validation.Valid;
29 29 import java.io.IOException;
30 30 import java.util.ArrayList;
31 31 import java.util.Collection;
... ... @@ -38,33 +38,19 @@ import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.Operat
38 38 @Api(tags = "操作日志")
39 39 @RestController
40 40 @RequestMapping("/system/operate-log")
  41 +@Validated
41 42 public class SysOperateLogController {
42 43  
43 44 @Resource
44 45 private SysOperateLogService operateLogService;
45   -
46 46 @Resource
47 47 private SysUserService userService;
48 48  
49   - @ApiOperation("示例")
50   - @OperateLog(type = OperateTypeEnum.OTHER)
51   - @GetMapping("/demo")
52   - public CommonResult<Boolean> demo() {
53   - // 这里可以调用业务逻辑
54   -
55   - // 补全操作日志的明细
56   - OperateLogUtils.setContent("将编号 1 的数据,xxx 字段修改成了 yyyy");
57   - OperateLogUtils.addExt("orderId", 1);
58   -
59   - // 响应
60   - return success(true);
61   - }
62   -
63   - @ApiOperation("查看操作日志分页列表")
64 49 @GetMapping("/page")
65   -// @PreAuthorize("@ss.hasPermi('system:operate-log:query')")
66   - public CommonResult<PageResult<SysOperateLogRespVO>> pageOperateLog(@Validated SysOperateLogPageReqVO reqVO) {
67   - PageResult<SysOperateLogDO> pageResult = operateLogService.pageOperateLog(reqVO);
  50 + @ApiOperation("查看操作日志分页列表")
  51 + @PreAuthorize("@ss.hasPermission('system:operate-log:query')")
  52 + public CommonResult<PageResult<SysOperateLogRespVO>> pageOperateLog(@Valid SysOperateLogPageReqVO reqVO) {
  53 + PageResult<SysOperateLogDO> pageResult = operateLogService.getOperateLogPage(reqVO);
68 54  
69 55 // 获得拼接需要的数据
70 56 Collection<Long> userIds = CollectionUtils.convertList(pageResult.getList(), SysOperateLogDO::getUserId);
... ... @@ -82,11 +68,10 @@ public class SysOperateLogController {
82 68  
83 69 @ApiOperation("导出操作日志")
84 70 @GetMapping("/export")
  71 + @PreAuthorize("@ss.hasPermission('system:operate-log:export')")
85 72 @OperateLog(type = EXPORT)
86   -// @PreAuthorize("@ss.hasPermi('system:operate-log:export')")
87   - public void exportOperateLog(HttpServletResponse response, @Validated SysOperateLogExportReqVO reqVO)
88   - throws IOException {
89   - List<SysOperateLogDO> list = operateLogService.listOperateLogs(reqVO);
  73 + public void exportOperateLog(HttpServletResponse response, @Valid SysOperateLogExportReqVO reqVO) throws IOException {
  74 + List<SysOperateLogDO> list = operateLogService.getOperateLogs(reqVO);
90 75  
91 76 // 获得拼接需要的数据
92 77 Collection<Long> userIds = CollectionUtils.convertList(list, SysOperateLogDO::getUserId);
... ... @@ -94,8 +79,7 @@ public class SysOperateLogController {
94 79 // 拼接数据
95 80 List<SysOperateLogExcelVO> excelDataList = SysOperateLogConvert.INSTANCE.convertList(list, userMap);
96 81 // 输出
97   - ExcelUtils.write(response, "操作日志.xls", "数据列表",
98   - SysOperateLogExcelVO.class, excelDataList);
  82 + ExcelUtils.write(response, "操作日志.xls", "数据列表", SysOperateLogExcelVO.class, excelDataList);
99 83 }
100 84  
101 85 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/notice/SysNoticeController.java
... ... @@ -11,62 +11,62 @@ import cn.iocoder.dashboard.modules.system.service.notice.SysNoticeService;
11 11 import io.swagger.annotations.Api;
12 12 import io.swagger.annotations.ApiImplicitParam;
13 13 import io.swagger.annotations.ApiOperation;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
14 15 import org.springframework.validation.annotation.Validated;
15 16 import org.springframework.web.bind.annotation.*;
16 17  
17 18 import javax.annotation.Resource;
  19 +import javax.validation.Valid;
18 20  
19 21 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
20 22  
21 23 @Api(tags = "通知公告")
22 24 @RestController
23 25 @RequestMapping("/system/notice")
  26 +@Validated
24 27 public class SysNoticeController {
25 28  
26 29 @Resource
27 30 private SysNoticeService noticeService;
28 31  
29   - @ApiOperation("获取通知公告列表")
30   - @GetMapping("/page")
31   -// @PreAuthorize("@ss.hasPermi('system:notice:list')")
32   - public CommonResult<PageResult<SysNoticeRespVO>> pageNotices(@Validated SysNoticePageReqVO reqVO) {
33   - return success(SysNoticeConvert.INSTANCE.convertPage(noticeService.pageNotices(reqVO)));
34   - }
35   -
36   - @ApiOperation("获得通知公告")
37   - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
38   -// @PreAuthorize("@ss.hasPermi('system:notice:query')")
39   - @GetMapping(value = "/get")
40   - public CommonResult<SysNoticeRespVO> getNotice(@RequestParam("id") Long id) {
41   - return success(SysNoticeConvert.INSTANCE.convert(noticeService.getNotice(id)));
42   - }
43   -
44   - @ApiOperation("新增通知公告")
45   -// @PreAuthorize("@ss.hasPermi('system:notice:add')")
46   -// @Log(title = "通知公告", businessType = BusinessType.INSERT)
47 32 @PostMapping("/create")
48   - public CommonResult<Long> createNotice(@Validated @RequestBody SysNoticeCreateReqVO reqVO) {
  33 + @ApiOperation("创建通知公告")
  34 + @PreAuthorize("@ss.hasPermission('system:notice:create')")
  35 + public CommonResult<Long> createNotice(@Valid @RequestBody SysNoticeCreateReqVO reqVO) {
49 36 Long noticeId = noticeService.createNotice(reqVO);
50 37 return success(noticeId);
51 38 }
52 39  
  40 + @PutMapping("/update")
53 41 @ApiOperation("修改通知公告")
54   -// @PreAuthorize("@ss.hasPermi('system:notice:edit')")
55   -// @Log(title = "通知公告", businessType = BusinessType.UPDATE)
56   - @PostMapping("/update")
57   - public CommonResult<Boolean> updateNotice(@Validated @RequestBody SysNoticeUpdateReqVO reqVO) {
  42 + @PreAuthorize("@ss.hasPermission('system:notice:update')")
  43 + public CommonResult<Boolean> updateNotice(@Valid @RequestBody SysNoticeUpdateReqVO reqVO) {
58 44 noticeService.updateNotice(reqVO);
59 45 return success(true);
60 46 }
61 47  
  48 + @DeleteMapping("/delete")
62 49 @ApiOperation("删除通知公告")
63 50 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
64   -// @PreAuthorize("@ss.hasPermi('system:notice:remove')")
65   -// @Log(title = "通知公告", businessType = BusinessType.DELETE)
66   - @PostMapping("/delete")
  51 + @PreAuthorize("@ss.hasPermission('system:notice:delete')")
67 52 public CommonResult<Boolean> deleteNotice(@RequestParam("id") Long id) {
68 53 noticeService.deleteNotice(id);
69 54 return success(true);
70 55 }
71 56  
  57 + @GetMapping("/page")
  58 + @ApiOperation("获取通知公告列表")
  59 + @PreAuthorize("@ss.hasPermission('system:notice:quey')")
  60 + public CommonResult<PageResult<SysNoticeRespVO>> pageNotices(@Validated SysNoticePageReqVO reqVO) {
  61 + return success(SysNoticeConvert.INSTANCE.convertPage(noticeService.pageNotices(reqVO)));
  62 + }
  63 +
  64 + @GetMapping("/get")
  65 + @ApiOperation("获得通知公告")
  66 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  67 + @PreAuthorize("@ss.hasPermission('system:notice:quey')")
  68 + public CommonResult<SysNoticeRespVO> getNotice(@RequestParam("id") Long id) {
  69 + return success(SysNoticeConvert.INSTANCE.convert(noticeService.getNotice(id)));
  70 + }
  71 +
72 72 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/SysMenuController.java
... ... @@ -9,10 +9,12 @@ import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService;
9 9 import io.swagger.annotations.Api;
10 10 import io.swagger.annotations.ApiImplicitParam;
11 11 import io.swagger.annotations.ApiOperation;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
12 13 import org.springframework.validation.annotation.Validated;
13 14 import org.springframework.web.bind.annotation.*;
14 15  
15 16 import javax.annotation.Resource;
  17 +import javax.validation.Valid;
16 18 import java.util.Comparator;
17 19 import java.util.List;
18 20  
... ... @@ -21,78 +23,64 @@ import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
21 23 @Api(tags = "菜单")
22 24 @RestController
23 25 @RequestMapping("/system/menu")
  26 +@Validated
24 27 public class SysMenuController {
25 28  
26 29 @Resource
27 30 private SysMenuService menuService;
28 31  
29   - @ApiOperation("获取菜单列表")
30   -// @PreAuthorize("@ss.hasPermi('system:menu:list')")
  32 + @PostMapping("/create")
  33 + @ApiOperation("创建菜单")
  34 + @PreAuthorize("@ss.hasPermission('system:menu:create')")
  35 + public CommonResult<Long> createMenu(@Valid @RequestBody SysMenuCreateReqVO reqVO) {
  36 + Long menuId = menuService.createMenu(reqVO);
  37 + return success(menuId);
  38 + }
  39 +
  40 + @PutMapping("/update")
  41 + @ApiOperation("修改菜单")
  42 + @PreAuthorize("@ss.hasPermission('system:menu:update')")
  43 + public CommonResult<Boolean> updateMenu(@Valid @RequestBody SysMenuUpdateReqVO reqVO) {
  44 + menuService.updateMenu(reqVO);
  45 + return success(true);
  46 + }
  47 +
  48 + @DeleteMapping("/delete")
  49 + @ApiOperation("删除菜单")
  50 + @ApiImplicitParam(name = "id", value = "角色编号", required= true, example = "1024", dataTypeClass = Long.class)
  51 + @PreAuthorize("@ss.hasPermission('system:menu:delete')")
  52 + public CommonResult<Boolean> deleteMenu(@RequestParam("id") Long id) {
  53 + menuService.deleteMenu(id);
  54 + return success(true);
  55 + }
  56 +
31 57 @GetMapping("/list")
32   - public CommonResult<List<SysMenuRespVO>> listMenus(SysMenuListReqVO reqVO) {
33   - List<SysMenuDO> list = menuService.listMenus(reqVO);
  58 + @ApiOperation("获取菜单列表")
  59 + @PreAuthorize("@ss.hasPermission('system:menu:query')")
  60 + public CommonResult<List<SysMenuRespVO>> getMenus(SysMenuListReqVO reqVO) {
  61 + List<SysMenuDO> list = menuService.getMenus(reqVO);
34 62 list.sort(Comparator.comparing(SysMenuDO::getSort));
35 63 return success(SysMenuConvert.INSTANCE.convertList(list));
36 64 }
37 65  
38   - @ApiOperation(value = "获取菜单精简信息列表", notes = "只包含被开启的菜单,主要用于前端的下拉选项")
39 66 @GetMapping("/list-all-simple")
40   - public CommonResult<List<SysMenuSimpleRespVO>> listSimpleMenus() {
  67 + @ApiOperation(value = "获取菜单精简信息列表", notes = "只包含被开启的菜单,主要用于前端的下拉选项")
  68 + public CommonResult<List<SysMenuSimpleRespVO>> getSimpleMenus() {
41 69 // 获得菜单列表,只要开启状态的
42 70 SysMenuListReqVO reqVO = new SysMenuListReqVO();
43 71 reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
44   - List<SysMenuDO> list = menuService.listMenus(reqVO);
  72 + List<SysMenuDO> list = menuService.getMenus(reqVO);
45 73 // 排序后,返回个诶前端
46 74 list.sort(Comparator.comparing(SysMenuDO::getSort));
47 75 return success(SysMenuConvert.INSTANCE.convertList02(list));
48 76 }
49 77  
50   - @ApiOperation("获取菜单信息")
51 78 @GetMapping("/get")
52   -// @PreAuthorize("@ss.hasPermi('system:menu:query')")
  79 + @ApiOperation("获取菜单信息")
  80 + @PreAuthorize("@ss.hasPermission('system:menu:query')")
53 81 public CommonResult<SysMenuRespVO> getMenu(Long id) {
54 82 SysMenuDO menu = menuService.getMenu(id);
55 83 return success(SysMenuConvert.INSTANCE.convert(menu));
56 84 }
57 85  
58   -// /**
59   -// * 加载对应角色菜单列表树
60   -// */
61   -// @GetMapping(value = "/roleMenuTreeselect/{roleId}")
62   -// public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
63   -// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
64   -// List<SysMenu> menus = menuService.selectMenuList(loginUser.getUser().getUserId());
65   -// AjaxResult ajax = AjaxResult.success();
66   -// ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
67   -// ajax.put("menus", menuService.buildMenuTreeSelect(menus));
68   -// return ajax;
69   -// }
70   -
71   - @ApiOperation("创建菜单")
72   -// @PreAuthorize("@ss.hasPermi('system:menu:add')")
73   -// @Log(title = "菜单管理", businessType = BusinessType.INSERT)
74   - @PostMapping("/create")
75   - public CommonResult<Long> createMenu(@Validated @RequestBody SysMenuCreateReqVO reqVO) {
76   - Long menuId = menuService.createMenu(reqVO);
77   - return success(menuId);
78   - }
79   -
80   - @ApiOperation("修改菜单")
81   -// @PreAuthorize("@ss.hasPermi('system:menu:edit')")
82   -// @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
83   - @PostMapping("/update")
84   - public CommonResult<Boolean> updateMenu(@Validated @RequestBody SysMenuUpdateReqVO reqVO) {
85   - menuService.updateMenu(reqVO);
86   - return success(true);
87   - }
88   -
89   - @ApiOperation("删除菜单")
90   - @PostMapping("/delete")
91   - @ApiImplicitParam(name = "id", value = "角色编号", required= true, example = "1024", dataTypeClass = Long.class)
92   -// @Log(title = "菜单管理", businessType = BusinessType.DELETE)
93   - public CommonResult<Boolean> deleteMenu(@RequestParam("id") Long id) {
94   - menuService.deleteMenu(id);
95   - return success(true);
96   - }
97   -
98 86 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/permission/SysRoleController.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.dashboard.common.pojo.CommonResult;
5 5 import cn.iocoder.dashboard.common.pojo.PageResult;
6 6 import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
  7 +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
7 8 import cn.iocoder.dashboard.modules.system.controller.permission.vo.role.*;
8 9 import cn.iocoder.dashboard.modules.system.convert.permission.SysRoleConvert;
9 10 import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
... ... @@ -11,96 +12,95 @@ import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService;
11 12 import io.swagger.annotations.Api;
12 13 import io.swagger.annotations.ApiImplicitParam;
13 14 import io.swagger.annotations.ApiOperation;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
14 16 import org.springframework.validation.annotation.Validated;
15 17 import org.springframework.web.bind.annotation.*;
16 18  
17 19 import javax.annotation.Resource;
18 20 import javax.servlet.http.HttpServletResponse;
  21 +import javax.validation.Valid;
19 22 import java.io.IOException;
20 23 import java.util.Collections;
21 24 import java.util.Comparator;
22 25 import java.util.List;
23 26  
24 27 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
  28 +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
25 29  
26 30 @Api(tags = "角色")
27 31 @RestController
28 32 @RequestMapping("/system/role")
  33 +@Validated
29 34 public class SysRoleController {
30 35  
31 36 @Resource
32 37 private SysRoleService roleService;
33 38  
34   - @ApiOperation("获得角色分页")
35   - @GetMapping("/page")
36   -// @PreAuthorize("@ss.hasPermi('system:role:list')")
37   - public CommonResult<PageResult<SysRoleDO>> list(SysRolePageReqVO reqVO) {
38   - return success(roleService.pageRole(reqVO));
39   - }
40   -
41   - @ApiOperation(value = "获取角色精简信息列表", notes = "只包含被开启的角色,主要用于前端的下拉选项")
42   - @GetMapping("/list-all-simple")
43   - public CommonResult<List<SysRoleSimpleRespVO>> listSimpleRoles() {
44   - // 获得角色列表,只要开启状态的
45   - List<SysRoleDO> list = roleService.listRoles(Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
46   - // 排序后,返回个诶前端
47   - list.sort(Comparator.comparing(SysRoleDO::getSort));
48   - return success(SysRoleConvert.INSTANCE.convertList02(list));
49   - }
50   -
51   - @ApiOperation("创建角色")
52 39 @PostMapping("/create")
53   -// @PreAuthorize("@ss.hasPermi('system:role:add')")
54   -// @Log(title = "角色管理", businessType = BusinessType.INSERT)
55   - public CommonResult<Long> add(@Validated @RequestBody SysRoleCreateReqVO reqVO) {
  40 + @ApiOperation("创建角色")
  41 + @PreAuthorize("@ss.hasPermission('system:role:create')")
  42 + public CommonResult<Long> createRole(@Valid @RequestBody SysRoleCreateReqVO reqVO) {
56 43 return success(roleService.createRole(reqVO));
57 44 }
58 45  
  46 + @PutMapping("/update")
59 47 @ApiOperation("修改角色")
60   -// @PreAuthorize("@ss.hasPermi('system:role:edit')")
61   -// @Log(title = "角色管理", businessType = BusinessType.UPDATE)
62   - @PostMapping("/update")
63   - public CommonResult<Boolean> update(@Validated @RequestBody SysRoleUpdateReqVO reqVO) {
  48 + @PreAuthorize("@ss.hasPermission('system:role:update')")
  49 + public CommonResult<Boolean> updateRole(@Valid @RequestBody SysRoleUpdateReqVO reqVO) {
64 50 roleService.updateRole(reqVO);
65 51 return success(true);
66 52 }
67 53  
  54 + @PutMapping("/update-status")
  55 + @ApiOperation("修改角色状态")
  56 + @PreAuthorize("@ss.hasPermission('system:role:update')")
  57 + public CommonResult<Boolean> updateRoleStatus(@Valid @RequestBody SysRoleUpdateStatusReqVO reqVO) {
  58 + roleService.updateRoleStatus(reqVO.getId(), reqVO.getStatus());
  59 + return success(true);
  60 + }
  61 +
  62 + @DeleteMapping("/delete")
68 63 @ApiOperation("删除角色")
69   - @PostMapping("/delete")
70 64 @ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1024", dataTypeClass = Long.class)
71   -// @PreAuthorize("@ss.hasPermi('system:role:remove')")
72   -// @Log(title = "角色管理", businessType = BusinessType.DELETE)
  65 + @PreAuthorize("@ss.hasPermission('system:role:delete')")
73 66 public CommonResult<Boolean> deleteRole(@RequestParam("id") Long id) {
74 67 roleService.deleteRole(id);
75 68 return success(true);
76 69 }
77 70  
78   - @ApiOperation("获得角色信息")
79 71 @GetMapping("/get")
80   -// @PreAuthorize("@ss.hasPermi('system:role:query')")
  72 + @ApiOperation("获得角色信息")
  73 + @PreAuthorize("@ss.hasPermission('system:role:query')")
81 74 public CommonResult<SysRoleRespVO> getRole(@RequestParam("id") Long id) {
82 75 SysRoleDO role = roleService.getRole(id);
83 76 return success(SysRoleConvert.INSTANCE.convert(role));
84 77 }
85 78  
86   - @ApiOperation("修改角色状态")
87   - @PostMapping("/update-status")
88   -// @PreAuthorize("@ss.hasPermi('system:role:edit')")
89   -// @Log(title = "角色管理", businessType = BusinessType.UPDATE)
90   - public CommonResult<Boolean> updateRoleStatus(@Validated @RequestBody SysRoleUpdateStatusReqVO reqVO) {
91   - roleService.updateRoleStatus(reqVO.getId(), reqVO.getStatus());
92   - return success(true);
  79 + @GetMapping("/page")
  80 + @ApiOperation("获得角色分页")
  81 + @PreAuthorize("@ss.hasPermission('system:role:query')")
  82 + public CommonResult<PageResult<SysRoleDO>> getRolePage(SysRolePageReqVO reqVO) {
  83 + return success(roleService.getRolePage(reqVO));
  84 + }
  85 +
  86 + @GetMapping("/list-all-simple")
  87 + @ApiOperation(value = "获取角色精简信息列表", notes = "只包含被开启的角色,主要用于前端的下拉选项")
  88 + public CommonResult<List<SysRoleSimpleRespVO>> getSimpleRoles() {
  89 + // 获得角色列表,只要开启状态的
  90 + List<SysRoleDO> list = roleService.getRoles(Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
  91 + // 排序后,返回个诶前端
  92 + list.sort(Comparator.comparing(SysRoleDO::getSort));
  93 + return success(SysRoleConvert.INSTANCE.convertList02(list));
93 94 }
94 95  
95 96 @GetMapping("/export")
96   -// @Log(title = "角色管理", businessType = BusinessType.EXPORT)
97   -// @PreAuthorize("@ss.hasPermi('system:role:export')")
  97 + @OperateLog(type = EXPORT)
  98 + @PreAuthorize("@ss.hasPermission('system:role:export')")
98 99 public void export(HttpServletResponse response, @Validated SysRoleExportReqVO reqVO) throws IOException {
99   - List<SysRoleDO> list = roleService.listRoles(reqVO);
100   - List<SysRoleExcelVO> excelDataList = SysRoleConvert.INSTANCE.convertList03(list);
  100 + List<SysRoleDO> list = roleService.getRoles(reqVO);
  101 + List<SysRoleExcelVO> data = SysRoleConvert.INSTANCE.convertList03(list);
101 102 // 输出
102   - ExcelUtils.write(response, "角色数据.xls", "角色列表",
103   - SysRoleExcelVO.class, excelDataList);
  103 + ExcelUtils.write(response, "角色数据.xls", "角色列表", SysRoleExcelVO.class, data);
104 104 }
105 105  
106 106 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/SysUserController.java
... ... @@ -5,6 +5,7 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
5 5 import cn.iocoder.dashboard.common.pojo.CommonResult;
6 6 import cn.iocoder.dashboard.common.pojo.PageResult;
7 7 import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
  8 +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
8 9 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
9 10 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
10 11 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
... ... @@ -25,14 +26,17 @@ import org.springframework.web.multipart.MultipartFile;
25 26  
26 27 import javax.annotation.Resource;
27 28 import javax.servlet.http.HttpServletResponse;
  29 +import javax.validation.Valid;
28 30 import java.io.IOException;
29 31 import java.util.*;
30 32  
31 33 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
  34 +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
32 35  
33 36 @Api(tags = "用户")
34 37 @RestController
35 38 @RequestMapping("/system/user")
  39 +@Validated
36 40 public class SysUserController {
37 41  
38 42 @Resource
... ... @@ -40,12 +44,53 @@ public class SysUserController {
40 44 @Resource
41 45 private SysDeptService deptService;
42 46  
  47 + @PostMapping("/create")
  48 + @ApiOperation("新增用户")
  49 + @PreAuthorize("@ss.hasPermission('system:user:create')")
  50 + public CommonResult<Long> createUser(@Valid @RequestBody SysUserCreateReqVO reqVO) {
  51 + Long id = userService.createUser(reqVO);
  52 + return success(id);
  53 + }
  54 +
  55 + @PutMapping("update")
  56 + @ApiOperation("修改用户")
  57 + @PreAuthorize("@ss.hasPermission('system:user:update')")
  58 + public CommonResult<Boolean> updateUser(@Valid @RequestBody SysUserUpdateReqVO reqVO) {
  59 + userService.updateUser(reqVO);
  60 + return success(true);
  61 + }
  62 +
  63 + @DeleteMapping("/delete")
  64 + @ApiOperation("删除用户")
  65 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  66 + @PreAuthorize("@ss.hasPermission('system:user:delete')")
  67 + public CommonResult<Boolean> deleteUser(@RequestParam("id") Long id) {
  68 + userService.deleteUser(id);
  69 + return success(true);
  70 + }
  71 +
  72 + @PutMapping("/update-password")
  73 + @ApiOperation("重置用户密码")
  74 + @PreAuthorize("@ss.hasPermission('system:user:update-password')")
  75 + public CommonResult<Boolean> updateUserPassword(@Valid @RequestBody SysUserUpdatePasswordReqVO reqVO) {
  76 + userService.updateUserPassword(reqVO.getId(), reqVO.getPassword());
  77 + return success(true);
  78 + }
  79 +
  80 + @PutMapping("/update-status")
  81 + @ApiOperation("修改用户状态")
  82 + @PreAuthorize("@ss.hasPermission('system:user:update')")
  83 + public CommonResult<Boolean> updateUserStatus(@Valid @RequestBody SysUserUpdateStatusReqVO reqVO) {
  84 + userService.updateUserStatus(reqVO.getId(), reqVO.getStatus());
  85 + return success(true);
  86 + }
  87 +
43 88 @GetMapping("/page")
44 89 @ApiOperation("获得用户分页列表")
45 90 @PreAuthorize("@ss.hasPermission('system:user:list')")
46   - public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(@Validated SysUserPageReqVO reqVO) {
  91 + public CommonResult<PageResult<SysUserPageItemRespVO>> getUserPage(@Valid SysUserPageReqVO reqVO) {
47 92 // 获得用户分页列表
48   - PageResult<SysUserDO> pageResult = userService.pageUsers(reqVO);
  93 + PageResult<SysUserDO> pageResult = userService.getUserPage(reqVO);
49 94 if (CollUtil.isEmpty(pageResult.getList())) {
50 95 return success(new PageResult<>(pageResult.getTotal())); // 返回空
51 96 }
... ... @@ -63,71 +108,22 @@ public class SysUserController {
63 108 return success(new PageResult<>(userList, pageResult.getTotal()));
64 109 }
65 110  
66   - /**
67   - * 根据用户编号获取详细信息
68   - */
69 111 @GetMapping("/get")
70 112 @ApiOperation("获得用户详情")
71 113 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
72   -// @PreAuthorize("@ss.hasPermi('system:user:query')")
  114 + @PreAuthorize("@ss.hasPermission('system:user:query')")
73 115 public CommonResult<SysUserRespVO> getInfo(@RequestParam("id") Long id) {
74 116 return success(SysUserConvert.INSTANCE.convert(userService.getUser(id)));
75 117 }
76 118  
77   - @ApiOperation("新增用户")
78   - @PostMapping("/create")
79   -// @PreAuthorize("@ss.hasPermi('system:user:add')")
80   -// @Log(title = "用户管理", businessType = BusinessType.INSERT)
81   - public CommonResult<Long> createUser(@Validated @RequestBody SysUserCreateReqVO reqVO) {
82   - Long id = userService.createUser(reqVO);
83   - return success(id);
84   - }
85   -
86   - @ApiOperation("修改用户")
87   - @PostMapping("update")
88   -// @PreAuthorize("@ss.hasPermi('system:user:edit')")
89   -// @Log(title = "用户管理", businessType = BusinessType.UPDATE)
90   - public CommonResult<Boolean> updateUser(@Validated @RequestBody SysUserUpdateReqVO reqVO) {
91   - userService.updateUser(reqVO);
92   - return success(true);
93   - }
94   -
95   - @ApiOperation("删除用户")
96   - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
97   - @PostMapping("/delete")
98   -// @PreAuthorize("@ss.hasPermi('system:user:remove')")
99   -// @Log(title = "用户管理", businessType = BusinessType.DELETE)
100   - public CommonResult<Boolean> deleteUser(@RequestParam("id") Long id) {
101   - userService.deleteUser(id);
102   - return success(true);
103   - }
104   -
105   - @ApiOperation("重置用户密码")
106   - @PostMapping("/update-password")
107   -// @PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
108   -// @Log(title = "用户管理", businessType = BusinessType.UPDATE)
109   - public CommonResult<Boolean> updateUserPassword(@Validated @RequestBody SysUserUpdatePasswordReqVO reqVO) {
110   - userService.updateUserPassword(reqVO.getId(), reqVO.getPassword());
111   - return success(true);
112   - }
113   -
114   - @ApiOperation("修改用户状态")
115   - @PostMapping("/update-status")
116   -// @PreAuthorize("@ss.hasPermi('system:user:edit')")
117   -// @Log(title = "用户管理", businessType = BusinessType.UPDATE)
118   - public CommonResult<Boolean> updateUserStatus(@Validated @RequestBody SysUserUpdateStatusReqVO reqVO) {
119   - userService.updateUserStatus(reqVO.getId(), reqVO.getStatus());
120   - return success(true);
121   - }
122   -
123   - @ApiOperation("导出用户")
124 119 @GetMapping("/export")
125   -// @PreAuthorize("@ss.hasPermi('system:user:export')") , @Validated SysUserExportReqVO reqVO
126   -// @Log(title = "用户管理", businessType = BusinessType.EXPORT)
  120 + @ApiOperation("导出用户")
  121 + @PreAuthorize("@ss.hasPermission('system:user:export')")
  122 + @OperateLog(type = EXPORT)
127 123 public void exportUsers(@Validated SysUserExportReqVO reqVO,
128 124 HttpServletResponse response) throws IOException {
129 125 // 获得用户列表
130   - List<SysUserDO> users = userService.listUsers(reqVO);
  126 + List<SysUserDO> users = userService.getUsers(reqVO);
131 127  
132 128 // 获得拼接需要的数据
133 129 Collection<Long> deptIds = CollectionUtils.convertList(users, SysUserDO::getDeptId);
... ... @@ -147,8 +143,8 @@ public class SysUserController {
147 143 ExcelUtils.write(response, "用户数据.xls", "用户列表", SysUserExcelVO.class, excelUsers);
148 144 }
149 145  
150   - @ApiOperation("获得导入用户模板")
151 146 @GetMapping("/get-import-template")
  147 + @ApiOperation("获得导入用户模板")
152 148 public void importTemplate(HttpServletResponse response) throws IOException {
153 149 // 手动创建导出 demo
154 150 List<SysUserImportExcelVO> list = Arrays.asList(
... ... @@ -159,21 +155,18 @@ public class SysUserController {
159 155 );
160 156  
161 157 // 输出
162   - ExcelUtils.write(response, "用户导入模板.xls", "用户列表",
163   - SysUserImportExcelVO.class, list);
164   -
  158 + ExcelUtils.write(response, "用户导入模板.xls", "用户列表", SysUserImportExcelVO.class, list);
165 159 }
166 160  
  161 + @PostMapping("/import")
167 162 @ApiOperation("导入用户")
168 163 @ApiImplicitParams({
169 164 @ApiImplicitParam(name = "file", value = "Excel 文件", required = true, dataTypeClass = MultipartFile.class),
170 165 @ApiImplicitParam(name = "updateSupport", value = "是否支持更新,默认为 false", example = "true", dataTypeClass = Boolean.class)
171 166 })
172   - @PostMapping("/import")
173   -// @Log(title = "用户管理", businessType = BusinessType.IMPORT)
174   -// @PreAuthorize("@ss.hasPermi('system:user:import')")
  167 + @PreAuthorize("@ss.hasPermission('system:user:import')")
175 168 public CommonResult<SysUserImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
176   - @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
  169 + @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
177 170 List<SysUserImportExcelVO> list = ExcelUtils.raed(file, SysUserImportExcelVO.class);
178 171 return success(userService.importUsers(list, updateSupport));
179 172 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/SysUserProfileController.java
1 1 package cn.iocoder.dashboard.modules.system.controller.user;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
4 5 import cn.iocoder.dashboard.common.pojo.CommonResult;
5   -import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
6   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO;
7   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
8   -import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert;
  6 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileRespVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
  8 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
9 9 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
  10 +import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
  11 +import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
10 12 import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
11 13 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
  14 +import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
  15 +import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
12 16 import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
13 17 import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService;
14 18 import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
15   -import cn.iocoder.dashboard.util.collection.CollectionUtils;
16 19 import io.swagger.annotations.Api;
17 20 import io.swagger.annotations.ApiOperation;
18 21 import lombok.extern.slf4j.Slf4j;
19   -import org.springframework.web.bind.annotation.GetMapping;
20   -import org.springframework.web.bind.annotation.PostMapping;
21   -import org.springframework.web.bind.annotation.RequestBody;
22   -import org.springframework.web.bind.annotation.RequestMapping;
23   -import org.springframework.web.bind.annotation.RequestParam;
24   -import org.springframework.web.bind.annotation.RestController;
  22 +import org.springframework.validation.annotation.Validated;
  23 +import org.springframework.web.bind.annotation.*;
25 24 import org.springframework.web.multipart.MultipartFile;
26 25  
27 26 import javax.annotation.Resource;
28   -import javax.servlet.http.HttpServletRequest;
  27 +import javax.validation.Valid;
29 28 import java.io.IOException;
30 29 import java.util.List;
31 30  
32 31 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
  32 +import static cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
33 33 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.FILE_IS_EMPTY;
34 34  
35 35 /**
36 36 * @author niudehua
37 37 */
  38 +@Api(tags = "用户个人中心")
38 39 @RestController
39 40 @RequestMapping("/system/user/profile")
40   -@Api(tags = "用户个人中心")
  41 +@Validated
41 42 @Slf4j
42 43 public class SysUserProfileController {
43 44  
44 45 @Resource
45 46 private SysUserService userService;
46 47 @Resource
  48 + private SysDeptService deptService;
  49 + @Resource
  50 + private SysPostService postService;
  51 + @Resource
47 52 private SysPermissionService permissionService;
48 53 @Resource
49 54 private SysRoleService roleService;
... ... @@ -51,30 +56,47 @@ public class SysUserProfileController {
51 56 @GetMapping("/get")
52 57 @ApiOperation("获得登录用户信息")
53 58 public CommonResult<SysUserProfileRespVO> profile() {
54   - // 获取用户信息
55   - Long userId = SecurityFrameworkUtils.getLoginUserId();
56   - SysUserDO user = userService.getUser(userId);
57   - SysUserProfileRespVO userProfileRespVO = SysUserConvert.INSTANCE.convert03(user);
58   - List<SysRoleDO> userRoles = roleService.listRolesFromCache(permissionService.listUserRoleIs(userId));
59   - userProfileRespVO.setRoles(CollectionUtils.convertSet(userRoles, SysUserConvert.INSTANCE::convert));
60   - return success(userProfileRespVO);
  59 + // 获得用户基本信息
  60 + SysUserDO user = userService.getUser(getLoginUserId());
  61 + SysUserProfileRespVO resp = SysUserConvert.INSTANCE.convert03(user);
  62 + // 获得用户角色
  63 + List<SysRoleDO> userRoles = roleService.getRolesFromCache(permissionService.listUserRoleIs(user.getId()));
  64 + resp.setRoles(SysUserConvert.INSTANCE.convertList(userRoles));
  65 + // 获得部门信息
  66 + if (user.getDeptId() != null) {
  67 + SysDeptDO dept = deptService.getDept(user.getDeptId());
  68 + resp.setDept(SysUserConvert.INSTANCE.convert02(dept));
  69 + }
  70 + // 获得岗位信息
  71 + if (CollUtil.isNotEmpty(user.getPostIds())) {
  72 + List<SysPostDO> posts = postService.getPosts(user.getPostIds());
  73 + resp.setPosts(SysUserConvert.INSTANCE.convertList02(posts));
  74 + }
  75 + return success(resp);
61 76 }
62 77  
63   - @PostMapping("/update")
  78 + @PutMapping("/update")
64 79 @ApiOperation("修改用户个人信息")
65   - public CommonResult<Boolean> updateProfile(@RequestBody SysUserProfileUpdateReqVO reqVO, HttpServletRequest request) {
66   - userService.updateUserProfile(reqVO);
67   - SecurityFrameworkUtils.setLoginUser(SysAuthConvert.INSTANCE.convert(reqVO), request);
  80 + public CommonResult<Boolean> updateUserProfile(@Valid @RequestBody SysUserProfileUpdateReqVO reqVO) {
  81 + userService.updateUserProfile(getLoginUserId(), reqVO);
68 82 return success(true);
69 83 }
70 84  
71   - @PostMapping("/upload-avatar")
  85 + @PutMapping("/update-password")
  86 + @ApiOperation("修改用户个人密码")
  87 + public CommonResult<Boolean> updateUserProfilePassword(@Valid @RequestBody SysUserProfileUpdatePasswordReqVO reqVO) {
  88 + userService.updateUserPassword(getLoginUserId(), reqVO);
  89 + return success(true);
  90 + }
  91 +
  92 + @PutMapping("/upload-avatar")
72 93 @ApiOperation("上传用户个人头像")
73   - public CommonResult<Boolean> uploadAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException {
  94 + public CommonResult<Boolean> updateUserAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException {
74 95 if (file.isEmpty()) {
75 96 throw ServiceExceptionUtil.exception(FILE_IS_EMPTY);
76 97 }
77   - userService.updateAvatar(SecurityFrameworkUtils.getLoginUserId(), file.getInputStream());
  98 + userService.updateUserAvatar(getLoginUserId(), file.getInputStream());
78 99 return success(true);
79 100 }
  101 +
80 102 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/profile/SysUserProfileRespVO.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.controller.user.vo.profile;
  2 +
  3 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserBaseVO;
  4 +import io.swagger.annotations.ApiModel;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.AllArgsConstructor;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.NoArgsConstructor;
  10 +
  11 +import java.util.Date;
  12 +import java.util.List;
  13 +
  14 +
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@NoArgsConstructor
  18 +@AllArgsConstructor
  19 +@ApiModel("用户个人中心信息 Response VO")
  20 +public class SysUserProfileRespVO extends SysUserBaseVO {
  21 +
  22 + @ApiModelProperty(value = "用户编号", required = true, example = "1")
  23 + private Long id;
  24 +
  25 + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 SysCommonStatusEnum 枚举类")
  26 + private Integer status;
  27 +
  28 + @ApiModelProperty(value = "最后登陆 IP", required = true, example = "192.168.1.1")
  29 + private String loginIp;
  30 +
  31 + @ApiModelProperty(value = "最后登录时间", required = true, example = "时间戳格式")
  32 + private Date loginDate;
  33 +
  34 + @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
  35 + private Date createTime;
  36 +
  37 + /**
  38 + * 所属角色
  39 + */
  40 + private List<Role> roles;
  41 +
  42 + /**
  43 + * 所在部门
  44 + */
  45 + private Dept dept;
  46 +
  47 + /**
  48 + * 所属岗位数组
  49 + */
  50 + private List<Post> posts;
  51 +
  52 + @ApiModel("角色")
  53 + @Data
  54 + public static class Role {
  55 +
  56 + @ApiModelProperty(value = "角色编号", required = true, example = "1")
  57 + private Long id;
  58 +
  59 + @ApiModelProperty(value = "角色名称", required = true, example = "普通角色")
  60 + private String name;
  61 +
  62 + }
  63 +
  64 + @ApiModel("部门")
  65 + @Data
  66 + public static class Dept {
  67 +
  68 + @ApiModelProperty(value = "部门编号", required = true, example = "1")
  69 + private Long id;
  70 +
  71 + @ApiModelProperty(value = "部门名称", required = true, example = "研发部")
  72 + private String name;
  73 +
  74 + }
  75 +
  76 + @ApiModel("岗位")
  77 + @Data
  78 + public static class Post {
  79 +
  80 + @ApiModelProperty(value = "岗位编号", required = true, example = "1")
  81 + private Long id;
  82 +
  83 + @ApiModelProperty(value = "岗位名称", required = true, example = "开发")
  84 + private String name;
  85 +
  86 + }
  87 +
  88 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/profile/SysUserProfileUpdatePasswordReqVO.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.controller.user.vo.profile;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import org.hibernate.validator.constraints.Length;
  7 +
  8 +import javax.validation.constraints.NotEmpty;
  9 +
  10 +@ApiModel("用户个人中心更新密码 Request VO")
  11 +@Data
  12 +public class SysUserProfileUpdatePasswordReqVO {
  13 +
  14 + @ApiModelProperty(value = "旧密码", required = true, example = "123456")
  15 + @NotEmpty(message = "旧密码不能为空")
  16 + @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
  17 + private String oldPassword;
  18 +
  19 + @ApiModelProperty(value = "新密码", required = true, example = "654321")
  20 + @NotEmpty(message = "新密码不能为空")
  21 + @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
  22 + private String newPassword;
  23 +
  24 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserProfileUpdateReqVO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/profile/SysUserProfileUpdateReqVO.java
1   -package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
  1 +package cn.iocoder.dashboard.modules.system.controller.user.vo.profile;
2 2  
3 3 import io.swagger.annotations.ApiModel;
4 4 import io.swagger.annotations.ApiModelProperty;
5 5 import lombok.Data;
6 6  
7 7 import javax.validation.constraints.Email;
8   -import javax.validation.constraints.NotNull;
  8 +import javax.validation.constraints.Pattern;
9 9 import javax.validation.constraints.Size;
10 10  
11 11 @ApiModel("用户个人信息更新 Request VO")
12 12 @Data
13 13 public class SysUserProfileUpdateReqVO {
14 14  
15   - @ApiModelProperty(value = "用户编号", required = true, example = "1024")
16   - @NotNull(message = "用户编号不能为空")
17   - private Long id;
18   -
19 15 @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
20 16 @Size(max = 30, message = "用户昵称长度不能超过30个字符")
21 17 private String nickname;
22 18  
23 19 @ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn")
24 20 @Email(message = "邮箱格式不正确")
25   - @Size(max = 50, message = "邮箱长度不能超过50个字符")
  21 + @Size(max = 50, message = "邮箱长度不能超过 50 个字符")
26 22 private String email;
27 23  
28 24 @ApiModelProperty(value = "手机号码", example = "15601691300")
29   - @Size(max = 11, message = "手机号码长度不能超过11个字符")
  25 + @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
30 26 private String mobile;
31 27  
32 28 @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")
33 29 private Integer sex;
34 30  
35   - @ApiModelProperty(value = "用户头像", example = "http://www.iocoder.cn/xxx.png")
36   - private String avatar;
37   -
38   - @ApiModelProperty(value = "旧密码", required = true, example = "123456")
39   - private String oldPassword;
40   -
41   - @ApiModelProperty(value = "新密码", required = true, example = "654321")
42   - private String newPassword;
43   -
44 31 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserBaseVO.java
... ... @@ -5,6 +5,7 @@ import lombok.Data;
5 5  
6 6 import javax.validation.constraints.Email;
7 7 import javax.validation.constraints.NotBlank;
  8 +import javax.validation.constraints.Pattern;
8 9 import javax.validation.constraints.Size;
9 10 import java.util.Set;
10 11  
... ... @@ -35,11 +36,11 @@ public class SysUserBaseVO {
35 36  
36 37 @ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn")
37 38 @Email(message = "邮箱格式不正确")
38   - @Size(max = 50, message = "邮箱长度不能超过50个字符")
  39 + @Size(max = 50, message = "邮箱长度不能超过 50 个字符")
39 40 private String email;
40 41  
41 42 @ApiModelProperty(value = "手机号码", example = "15601691300")
42   - @Size(max = 11, message = "手机号码长度不能超过11个字符")
  43 + @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
43 44 private String mobile;
44 45  
45 46 @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")
... ... @@ -48,5 +49,4 @@ public class SysUserBaseVO {
48 49 @ApiModelProperty(value = "用户头像", example = "http://www.iocoder.cn/xxx.png")
49 50 private String avatar;
50 51  
51   -
52 52 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserPageItemRespVO.java
1 1 package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
2 2  
3   -import com.fasterxml.jackson.annotation.JsonIgnore;
4 3 import io.swagger.annotations.ApiModel;
5 4 import io.swagger.annotations.ApiModelProperty;
6 5 import lombok.AllArgsConstructor;
... ... @@ -18,7 +17,6 @@ public class SysUserPageItemRespVO extends SysUserRespVO {
18 17 /**
19 18 * 所在部门
20 19 */
21   - @JsonIgnore
22 20 private Dept dept;
23 21  
24 22 @ApiModel("部门")
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserProfileRespVO.java deleted
1   -package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
2   -
3   -import io.swagger.annotations.ApiModel;
4   -import io.swagger.annotations.ApiModelProperty;
5   -import lombok.AllArgsConstructor;
6   -import lombok.Data;
7   -import lombok.EqualsAndHashCode;
8   -import lombok.NoArgsConstructor;
9   -
10   -import java.util.Set;
11   -
12   -
13   -@ApiModel("用户个人中心信息 Response VO")
14   -@Data
15   -@NoArgsConstructor
16   -@AllArgsConstructor
17   -@EqualsAndHashCode(callSuper = true)
18   -public class SysUserProfileRespVO extends SysUserRespVO {
19   -
20   - /**
21   - * 所属角色
22   - */
23   - @ApiModelProperty(value = "所属角色", required = true, example = "123456")
24   - private Set<Role> roles;
25   -
26   - @ApiModel("角色")
27   - @Data
28   - public static class Role {
29   -
30   - @ApiModelProperty(value = "角色编号", required = true, example = "1")
31   - private Long id;
32   -
33   - @ApiModelProperty(value = "角色名称", required = true, example = "普通角色")
34   - private String name;
35   -
36   - }
37   -}
src/main/java/cn/iocoder/dashboard/modules/system/convert/auth/SysAuthConvert.java
... ... @@ -3,7 +3,8 @@ package cn.iocoder.dashboard.modules.system.convert.auth;
3 3 import cn.iocoder.dashboard.framework.security.core.LoginUser;
4 4 import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO;
5 5 import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO;
6   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
  6 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
7 8 import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysMenuDO;
8 9 import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
9 10 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
... ... @@ -41,6 +42,8 @@ public interface SysAuthConvert {
41 42  
42 43 LoginUser convert(SysUserProfileUpdateReqVO reqVO);
43 44  
  45 + LoginUser convert(SysUserProfileUpdatePasswordReqVO reqVO);
  46 +
44 47 /**
45 48 * 将菜单列表,构建成菜单树
46 49 *
... ...
src/main/java/cn/iocoder/dashboard/modules/system/convert/user/SysUserConvert.java
1 1 package cn.iocoder.dashboard.modules.system.convert.user;
2 2  
3   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
4   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExcelVO;
5   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
6   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
7   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO;
8   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
9   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
  3 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileRespVO;
  4 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
  5 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
  6 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
10 7 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
  8 +import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
11 9 import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
12 10 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
13 11 import org.mapstruct.Mapper;
14 12 import org.mapstruct.factory.Mappers;
15 13  
  14 +import java.util.List;
  15 +
16 16 @Mapper
17 17 public interface SysUserConvert {
18 18  
... ... @@ -32,10 +32,14 @@ public interface SysUserConvert {
32 32  
33 33 SysUserProfileRespVO convert03(SysUserDO bean);
34 34  
35   - SysUserProfileRespVO.Role convert(SysRoleDO bean);
  35 + List<SysUserProfileRespVO.Role> convertList(List<SysRoleDO> list);
  36 +
  37 + SysUserProfileRespVO.Dept convert02(SysDeptDO bean);
36 38  
37 39 SysUserDO convert(SysUserProfileUpdateReqVO bean);
38 40  
  41 + SysUserDO convert(SysUserProfileUpdatePasswordReqVO bean);
39 42  
  43 + List<SysUserProfileRespVO.Post> convertList02(List<SysPostDO> list);
40 44  
41 45 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/permission/SysRoleMenuMapper.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
4 4 import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleMenuDO;
5 5 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
6 6 import org.apache.ibatis.annotations.Mapper;
  7 +import org.apache.ibatis.annotations.Select;
7 8  
8 9 import java.util.Collection;
9 10 import java.util.Date;
... ... @@ -32,10 +33,16 @@ public interface SysRoleMenuMapper extends BaseMapperX&lt;SysRoleMenuDO&gt; {
32 33 delete(new QueryWrapper<SysRoleMenuDO>().eq("role_id", roleId)
33 34 .in("menu_id", menuIds));
34 35 }
  36 +
  37 + default void deleteListByMenuId(Long menuId) {
  38 + delete(new QueryWrapper<SysRoleMenuDO>().eq("menu_id", menuId));
  39 + }
35 40  
36   - default boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) {
37   - return selectOne(new QueryWrapper<SysRoleMenuDO>().select("id")
38   - .gt("update_time", maxUpdateTime).last("LIMIT 1")) != null;
  41 + default void deleteListByRoleId(Long roleId) {
  42 + delete(new QueryWrapper<SysRoleMenuDO>().eq("role_id", roleId));
39 43 }
40 44  
  45 + @Select("SELECT id FROM sys_role_menu WHERE update_time > #{maxUpdateTime} LIMIT 1")
  46 + Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
  47 +
41 48 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/permission/SysUserRoleMapper.java
1 1 package cn.iocoder.dashboard.modules.system.dal.mysql.permission;
2 2  
  3 +import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
3 4 import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysUserRoleDO;
4 5 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5   -import com.baomidou.mybatisplus.core.mapper.BaseMapper;
6 6 import org.apache.ibatis.annotations.Mapper;
7 7  
8 8 import java.util.Collection;
... ... @@ -10,7 +10,7 @@ import java.util.List;
10 10 import java.util.stream.Collectors;
11 11  
12 12 @Mapper
13   -public interface SysUserRoleMapper extends BaseMapper<SysUserRoleDO> {
  13 +public interface SysUserRoleMapper extends BaseMapperX<SysUserRoleDO> {
14 14  
15 15 default List<SysUserRoleDO> selectListByUserId(Long userId) {
16 16 return selectList(new QueryWrapper<SysUserRoleDO>().eq("user_id", userId));
... ... @@ -32,4 +32,12 @@ public interface SysUserRoleMapper extends BaseMapper&lt;SysUserRoleDO&gt; {
32 32 .in("role_id", roleIds));
33 33 }
34 34  
  35 + default void deleteListByUserId(Long userId) {
  36 + delete(new QueryWrapper<SysUserRoleDO>().eq("user_id", userId));
  37 + }
  38 +
  39 + default void deleteListByRoleId(Long roleId) {
  40 + delete(new QueryWrapper<SysUserRoleDO>().eq("role_id", roleId));
  41 + }
  42 +
35 43 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/mail/SysMailSendConsumer.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.mq.consumer.mail;
  2 +
  3 +import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener;
  4 +import cn.iocoder.dashboard.modules.system.mq.message.mail.SysMailSendMessage;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +@Component
  9 +@Slf4j
  10 +public class SysMailSendConsumer extends AbstractStreamMessageListener<SysMailSendMessage> {
  11 +
  12 + @Override
  13 + public void onMessage(SysMailSendMessage message) {
  14 + log.info("[onMessage][消息内容({})]", message);
  15 + }
  16 +
  17 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SysSmsSendConsumer.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.mq.consumer.sms;
  2 +
  3 +import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener;
  4 +import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +@Component
  9 +@Slf4j
  10 +public class SysSmsSendConsumer extends AbstractStreamMessageListener<SysSmsSendMessage> {
  11 +
  12 + @Override
  13 + public void onMessage(SysSmsSendMessage message) {
  14 + log.info("[onMessage][消息内容({})]", message);
  15 + }
  16 +
  17 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/mail/SysMailSendMessage.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.mq.message.mail;
  2 +
  3 +import cn.iocoder.dashboard.framework.redis.core.stream.StreamMessage;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +import java.util.Map;
  8 +
  9 +/**
  10 + * 邮箱发送消息
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Data
  15 +public class SysMailSendMessage implements StreamMessage {
  16 +
  17 + /**
  18 + * 邮箱地址
  19 + */
  20 + @NotNull(message = "邮箱地址不能为空")
  21 + private String address;
  22 + /**
  23 + * 短信模板编号
  24 + */
  25 + @NotNull(message = "短信模板编号不能为空")
  26 + private String templateCode;
  27 + /**
  28 + * 短信模板参数
  29 + */
  30 + private Map<String, Object> templateParams;
  31 +
  32 + /**
  33 + * 用户编号,允许空
  34 + */
  35 + private Integer userId;
  36 + /**
  37 + * 用户类型,允许空
  38 + */
  39 + private Integer userType;
  40 +
  41 + @Override
  42 + public String getStreamKey() {
  43 + return "system.mail.send";
  44 + }
  45 +
  46 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/sms/SysSmsSendMessage.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.mq.message.sms;
  2 +
  3 +import cn.iocoder.dashboard.framework.redis.core.stream.StreamMessage;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +import java.util.Map;
  8 +
  9 +/**
  10 + * 短信发送消息
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Data
  15 +public class SysSmsSendMessage implements StreamMessage {
  16 +
  17 + /**
  18 + * 手机号
  19 + */
  20 + @NotNull(message = "手机号不能为空")
  21 + private String mobile;
  22 + /**
  23 + * 短信模板编号
  24 + */
  25 + @NotNull(message = "短信模板编号不能为空")
  26 + private String templateCode;
  27 + /**
  28 + * 短信模板参数
  29 + */
  30 + private Map<String, Object> templateParams;
  31 +
  32 + /**
  33 + * 用户编号,允许空
  34 + */
  35 + private Integer userId;
  36 + /**
  37 + * 用户类型,允许空
  38 + */
  39 + private Integer userType;
  40 +
  41 + @Override
  42 + public String getStreamKey() {
  43 + return "system.sms.send";
  44 + }
  45 +
  46 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
... ... @@ -61,7 +61,7 @@ public class SysAuthServiceImpl implements SysAuthService {
61 61 @Override
62 62 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
63 63 // 获取 username 对应的 SysUserDO
64   - SysUserDO user = userService.getUserByUserName(username);
  64 + SysUserDO user = userService.getUserByUsername(username);
65 65 if (user == null) {
66 66 throw new UsernameNotFoundException(username);
67 67 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysUserSessionServiceImpl.java
... ... @@ -101,7 +101,7 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
101 101 // 处理基于用户昵称的查询
102 102 Collection<Long> userIds = null;
103 103 if (StrUtil.isNotEmpty(reqVO.getUsername())) {
104   - userIds = convertSet(userService.listUsersByUsername(reqVO.getUsername()), SysUserDO::getId);
  104 + userIds = convertSet(userService.getUsersByUsername(reqVO.getUsername()), SysUserDO::getId);
105 105 if (CollUtil.isEmpty(userIds)) {
106 106 return PageResult.empty();
107 107 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptService.java
... ... @@ -25,12 +25,34 @@ public interface SysDeptService {
25 25 void initLocalCache();
26 26  
27 27 /**
  28 + * 创建部门
  29 + *
  30 + * @param reqVO 部门信息
  31 + * @return 部门编号
  32 + */
  33 + Long createDept(SysDeptCreateReqVO reqVO);
  34 +
  35 + /**
  36 + * 更新部门
  37 + *
  38 + * @param reqVO 部门信息
  39 + */
  40 + void updateDept(SysDeptUpdateReqVO reqVO);
  41 +
  42 + /**
  43 + * 删除部门
  44 + *
  45 + * @param id 部门编号
  46 + */
  47 + void deleteDept(Long id);
  48 +
  49 + /**
28 50 * 获得指定编号的部门列表
29 51 *
30 52 * @param ids 部门编号数组
31 53 * @return 部门列表
32 54 */
33   - List<SysDeptDO> listDepts(Collection<Long> ids);
  55 + List<SysDeptDO> getSimpleDepts(Collection<Long> ids);
34 56  
35 57 /**
36 58 * 获得指定编号的部门 Map
... ... @@ -42,7 +64,7 @@ public interface SysDeptService {
42 64 if (CollUtil.isEmpty(ids)) {
43 65 return Collections.emptyMap();
44 66 }
45   - List<SysDeptDO> list = listDepts(ids);
  67 + List<SysDeptDO> list = getSimpleDepts(ids);
46 68 return CollectionUtils.convertMap(list, SysDeptDO::getId);
47 69 }
48 70  
... ... @@ -52,16 +74,7 @@ public interface SysDeptService {
52 74 * @param reqVO 筛选条件请求 VO
53 75 * @return 部门列表
54 76 */
55   - List<SysDeptDO> listDepts(SysDeptListReqVO reqVO);
56   -
57   - /**
58   - * 获得所有子部门,从缓存中
59   - *
60   - * @param parentId 部门编号
61   - * @param recursive 是否递归获取所有
62   - * @return 子部门列表
63   - */
64   - List<SysDeptDO> listDeptsByParentIdFromCache(Long parentId, boolean recursive);
  77 + List<SysDeptDO> getSimpleDepts(SysDeptListReqVO reqVO);
65 78  
66 79 /**
67 80 * 获得部门信息
... ... @@ -72,25 +85,12 @@ public interface SysDeptService {
72 85 SysDeptDO getDept(Long id);
73 86  
74 87 /**
75   - * 创建部门
76   - *
77   - * @param reqVO 部门信息
78   - * @return 部门编号
79   - */
80   - Long createDept(SysDeptCreateReqVO reqVO);
81   -
82   - /**
83   - * 更新部门
84   - *
85   - * @param reqVO 部门信息
86   - */
87   - void updateDept(SysDeptUpdateReqVO reqVO);
88   -
89   - /**
90   - * 删除部门
  88 + * 获得所有子部门,从缓存中
91 89 *
92   - * @param id 部门编号
  90 + * @param parentId 部门编号
  91 + * @param recursive 是否递归获取所有
  92 + * @return 子部门列表
93 93 */
94   - void deleteDept(Long id);
  94 + List<SysDeptDO> getDeptsByParentIdFromCache(Long parentId, boolean recursive);
95 95  
96 96 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostService.java
1 1 package cn.iocoder.dashboard.modules.system.service.dept;
2 2  
  3 +import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.dashboard.common.pojo.PageResult;
4 5 import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostCreateReqVO;
5 6 import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostExportReqVO;
... ... @@ -11,6 +12,8 @@ import org.springframework.lang.Nullable;
11 12 import java.util.Collection;
12 13 import java.util.List;
13 14  
  15 +import static cn.iocoder.dashboard.util.collection.SetUtils.asSet;
  16 +
14 17 /**
15 18 * 岗位 Service 接口
16 19 *
... ... @@ -19,58 +22,68 @@ import java.util.List;
19 22 public interface SysPostService {
20 23  
21 24 /**
22   - * 获得符合条件的岗位列表
  25 + * 创建岗位
23 26 *
24   - * @param ids 岗位编号数组。如果为空,不进行筛选
25   - * @param statuses 状态数组。如果为空,不进行筛选
26   - * @return 部门列表
  27 + * @param reqVO 岗位信息
  28 + * @return 岗位编号
27 29 */
28   - List<SysPostDO> listPosts(@Nullable Collection<Long> ids, @Nullable Collection<Integer> statuses);
  30 + Long createPost(SysPostCreateReqVO reqVO);
29 31  
30 32 /**
31   - * 获得岗位分页列表
  33 + * 更新岗位
32 34 *
33   - * @param reqVO 分页条件
34   - * @return 部门分页列表
  35 + * @param reqVO 岗位信息
  36 + */
  37 + void updatePost(SysPostUpdateReqVO reqVO);
  38 +
  39 + /**
  40 + * 删除岗位信息
  41 + *
  42 + * @param id 岗位编号
35 43 */
36   - PageResult<SysPostDO> pagePosts(SysPostPageReqVO reqVO);
  44 + void deletePost(Long id);
37 45  
38 46 /**
39 47 * 获得岗位列表
40 48 *
41   - * @param reqVO 查询条件
  49 + * @param ids 岗位编号数组。如果为空,不进行筛选
42 50 * @return 部门列表
43 51 */
44   - List<SysPostDO> listPosts(SysPostExportReqVO reqVO);
  52 + default List<SysPostDO> getPosts(@Nullable Collection<Long> ids) {
  53 + return getPosts(ids, asSet(CommonStatusEnum.ENABLE.getStatus(), CommonStatusEnum.DISABLE.getStatus()));
  54 + }
45 55  
46 56 /**
47   - * 获得岗位信息
  57 + * 获得符合条件的岗位列表
48 58 *
49   - * @param id 岗位编号
50   - * @return 岗位信息
  59 + * @param ids 岗位编号数组。如果为空,不进行筛选
  60 + * @param statuses 状态数组。如果为空,不进行筛选
  61 + * @return 部门列表
51 62 */
52   - SysPostDO getPost(Long id);
  63 + List<SysPostDO> getPosts(@Nullable Collection<Long> ids, @Nullable Collection<Integer> statuses);
53 64  
54 65 /**
55   - * 创建岗位
  66 + * 获得岗位分页列表
56 67 *
57   - * @param reqVO 岗位信息
58   - * @return 岗位编号
  68 + * @param reqVO 分页条件
  69 + * @return 部门分页列表
59 70 */
60   - Long createPost(SysPostCreateReqVO reqVO);
  71 + PageResult<SysPostDO> getPostPage(SysPostPageReqVO reqVO);
61 72  
62 73 /**
63   - * 更新岗位
  74 + * 获得岗位列表
64 75 *
65   - * @param reqVO 岗位信息
  76 + * @param reqVO 查询条件
  77 + * @return 部门列表
66 78 */
67   - void updatePost(SysPostUpdateReqVO reqVO);
  79 + List<SysPostDO> getPosts(SysPostExportReqVO reqVO);
68 80  
69 81 /**
70   - * 删除岗位信息
  82 + * 获得岗位信息
71 83 *
72 84 * @param id 岗位编号
  85 + * @return 岗位信息
73 86 */
74   - void deletePost(Long id);
  87 + SysPostDO getPost(Long id);
75 88  
76 89 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java
... ... @@ -19,6 +19,7 @@ import com.google.common.collect.Multimap;
19 19 import lombok.extern.slf4j.Slf4j;
20 20 import org.springframework.scheduling.annotation.Scheduled;
21 21 import org.springframework.stereotype.Service;
  22 +import org.springframework.validation.annotation.Validated;
22 23  
23 24 import javax.annotation.PostConstruct;
24 25 import javax.annotation.Resource;
... ... @@ -32,6 +33,7 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
32 33 * @author 芋道源码
33 34 */
34 35 @Service
  36 +@Validated
35 37 @Slf4j
36 38 public class SysDeptServiceImpl implements SysDeptService {
37 39  
... ... @@ -47,6 +49,7 @@ public class SysDeptServiceImpl implements SysDeptService {
47 49 *
48 50 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
49 51 */
  52 + @SuppressWarnings("FieldCanBeLocal")
50 53 private volatile Map<Long, SysDeptDO> deptCache;
51 54 /**
52 55 * 父部门缓存
... ... @@ -118,17 +121,54 @@ public class SysDeptServiceImpl implements SysDeptService {
118 121 }
119 122  
120 123 @Override
121   - public List<SysDeptDO> listDepts(Collection<Long> ids) {
  124 + public Long createDept(SysDeptCreateReqVO reqVO) {
  125 + // 校验正确性
  126 + checkCreateOrUpdate(null, reqVO.getParentId(), reqVO.getName());
  127 + // 插入部门
  128 + SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO);
  129 + deptMapper.insert(dept);
  130 + // 发送刷新消息
  131 + deptProducer.sendDeptRefreshMessage();
  132 + return dept.getId();
  133 + }
  134 +
  135 + @Override
  136 + public void updateDept(SysDeptUpdateReqVO reqVO) {
  137 + // 校验正确性
  138 + checkCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName());
  139 + // 更新部门
  140 + SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO);
  141 + deptMapper.updateById(updateObj);
  142 + // 发送刷新消息
  143 + deptProducer.sendDeptRefreshMessage();
  144 + }
  145 +
  146 + @Override
  147 + public void deleteDept(Long id) {
  148 + // 校验是否存在
  149 + checkDeptExists(id);
  150 + // 校验是否有子部门
  151 + if (deptMapper.selectCountByParentId(id) > 0) {
  152 + throw ServiceExceptionUtil.exception(DEPT_EXITS_CHILDREN);
  153 + }
  154 + // 删除部门
  155 + deptMapper.deleteById(id);
  156 + // 发送刷新消息
  157 + deptProducer.sendDeptRefreshMessage();
  158 + }
  159 +
  160 + @Override
  161 + public List<SysDeptDO> getSimpleDepts(Collection<Long> ids) {
122 162 return deptMapper.selectBatchIds(ids);
123 163 }
124 164  
125 165 @Override
126   - public List<SysDeptDO> listDepts(SysDeptListReqVO reqVO) {
  166 + public List<SysDeptDO> getSimpleDepts(SysDeptListReqVO reqVO) {
127 167 return deptMapper.selectList(reqVO);
128 168 }
129 169  
130 170 @Override
131   - public List<SysDeptDO> listDeptsByParentIdFromCache(Long parentId, boolean recursive) {
  171 + public List<SysDeptDO> getDeptsByParentIdFromCache(Long parentId, boolean recursive) {
132 172 List<SysDeptDO> result = new ArrayList<>();
133 173 // 递归,简单粗暴
134 174 this.listDeptsByParentIdFromCache(result, parentId,
... ... @@ -167,44 +207,6 @@ public class SysDeptServiceImpl implements SysDeptService {
167 207 return deptMapper.selectById(id);
168 208 }
169 209  
170   - @Override
171   - public Long createDept(SysDeptCreateReqVO reqVO) {
172   - // 校验正确性
173   - checkCreateOrUpdate(null, reqVO.getParentId(), reqVO.getName());
174   - // 插入部门
175   - SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO);
176   - deptMapper.insert(dept);
177   - // 发送刷新消息
178   - deptProducer.sendDeptRefreshMessage();
179   - return dept.getId();
180   - }
181   -
182   - @Override
183   - public void updateDept(SysDeptUpdateReqVO reqVO) {
184   - // 校验正确性
185   - checkCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName());
186   - // 更新部门
187   - SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO);
188   - deptMapper.updateById(updateObj);
189   - // 发送刷新消息
190   - deptProducer.sendDeptRefreshMessage();
191   - }
192   -
193   - @Override
194   - public void deleteDept(Long id) {
195   - // 校验是否存在
196   - checkDeptExists(id);
197   - // 校验是否有子部门
198   - if (deptMapper.selectCountByParentId(id) > 0) {
199   - throw ServiceExceptionUtil.exception(DEPT_EXITS_CHILDREN);
200   - }
201   - // 删除部门
202   - deptMapper.deleteById(id);
203   - // TODO 需要处理下与角色的数据权限关联,等做数据权限一起处理下
204   - // 发送刷新消息
205   - deptProducer.sendDeptRefreshMessage();
206   - }
207   -
208 210 private void checkCreateOrUpdate(Long id, Long parentId, String name) {
209 211 // 校验自己存在
210 212 checkDeptExists(id);
... ... @@ -232,7 +234,7 @@ public class SysDeptServiceImpl implements SysDeptService {
232 234 throw ServiceExceptionUtil.exception(DEPT_NOT_ENABLE);
233 235 }
234 236 // 父部门不能是原来的子部门
235   - List<SysDeptDO> children = this.listDeptsByParentIdFromCache(id, true);
  237 + List<SysDeptDO> children = this.getDeptsByParentIdFromCache(id, true);
236 238 if (children.stream().anyMatch(dept1 -> dept1.getId().equals(parentId))) {
237 239 throw ServiceExceptionUtil.exception(DEPT_PARENT_IS_CHILD);
238 240 }
... ... @@ -262,12 +264,6 @@ public class SysDeptServiceImpl implements SysDeptService {
262 264 }
263 265 }
264 266  
265   -// /**
266   -// * 查询部门管理数据
267   -// *
268   -// * @param dept 部门信息
269   -// * @return 部门信息集合
270   -// */
271 267 // @Override
272 268 // @DataScope(deptAlias = "d")
273 269 // public List<SysDept> selectDeptList(SysDept dept)
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysPostServiceImpl.java
... ... @@ -11,6 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dept.SysPostMapper;
11 11 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
12 12 import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
13 13 import org.springframework.stereotype.Service;
  14 +import org.springframework.validation.annotation.Validated;
14 15  
15 16 import javax.annotation.Resource;
16 17 import java.util.Collection;
... ... @@ -24,32 +25,13 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
24 25 * @author 芋道源码
25 26 */
26 27 @Service
  28 +@Validated
27 29 public class SysPostServiceImpl implements SysPostService {
28 30  
29 31 @Resource
30 32 private SysPostMapper postMapper;
31 33  
32 34 @Override
33   - public List<SysPostDO> listPosts(Collection<Long> ids, Collection<Integer> statuses) {
34   - return postMapper.selectList(ids, statuses);
35   - }
36   -
37   - @Override
38   - public PageResult<SysPostDO> pagePosts(SysPostPageReqVO reqVO) {
39   - return postMapper.selectPage(reqVO);
40   - }
41   -
42   - @Override
43   - public List<SysPostDO> listPosts(SysPostExportReqVO reqVO) {
44   - return postMapper.selectList(reqVO);
45   - }
46   -
47   - @Override
48   - public SysPostDO getPost(Long id) {
49   - return postMapper.selectById(id);
50   - }
51   -
52   - @Override
53 35 public Long createPost(SysPostCreateReqVO reqVO) {
54 36 // 校验正确性
55 37 this.checkCreateOrUpdate(null, reqVO.getName(), reqVO.getCode());
... ... @@ -68,6 +50,34 @@ public class SysPostServiceImpl implements SysPostService {
68 50 postMapper.updateById(updateObj);
69 51 }
70 52  
  53 + @Override
  54 + public void deletePost(Long id) {
  55 + // 校验是否存在
  56 + this.checkPostExists(id);
  57 + // 删除部门
  58 + postMapper.deleteById(id);
  59 + }
  60 +
  61 + @Override
  62 + public List<SysPostDO> getPosts(Collection<Long> ids, Collection<Integer> statuses) {
  63 + return postMapper.selectList(ids, statuses);
  64 + }
  65 +
  66 + @Override
  67 + public PageResult<SysPostDO> getPostPage(SysPostPageReqVO reqVO) {
  68 + return postMapper.selectPage(reqVO);
  69 + }
  70 +
  71 + @Override
  72 + public List<SysPostDO> getPosts(SysPostExportReqVO reqVO) {
  73 + return postMapper.selectList(reqVO);
  74 + }
  75 +
  76 + @Override
  77 + public SysPostDO getPost(Long id) {
  78 + return postMapper.selectById(id);
  79 + }
  80 +
71 81 private void checkCreateOrUpdate(Long id, String name, String code) {
72 82 // 校验自己存在
73 83 checkPostExists(id);
... ... @@ -105,14 +115,6 @@ public class SysPostServiceImpl implements SysPostService {
105 115 }
106 116 }
107 117  
108   - @Override
109   - public void deletePost(Long id) {
110   - // 校验是否存在
111   - this.checkPostExists(id);
112   - // 删除部门
113   - postMapper.deleteById(id);
114   - }
115   -
116 118 private void checkPostExists(Long id) {
117 119 if (id == null) {
118 120 return;
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataService.java
... ... @@ -23,57 +23,57 @@ public interface SysDictDataService extends DictDataFrameworkService {
23 23 void initLocalCache();
24 24  
25 25 /**
26   - * 获得字典数据列表
  26 + * 创建字典数据
27 27 *
28   - * @return 字典数据全列表
  28 + * @param reqVO 字典数据信息
  29 + * @return 字典数据编号
29 30 */
30   - List<SysDictDataDO> getDictDataList();
  31 + Long createDictData(SysDictDataCreateReqVO reqVO);
31 32  
32 33 /**
33   - * 获得字典数据分页列表
  34 + * 更新字典数据
34 35 *
35   - * @param reqVO 分页请求
36   - * @return 字典数据分页列表
  36 + * @param reqVO 字典数据信息
37 37 */
38   - PageResult<SysDictDataDO> getDictDataPage(SysDictDataPageReqVO reqVO);
  38 + void updateDictData(SysDictDataUpdateReqVO reqVO);
39 39  
40 40 /**
41   - * 获得字典数据列表
  41 + * 删除字典数据
42 42 *
43   - * @param reqVO 列表请求
44   - * @return 字典数据列表
  43 + * @param id 字典数据编号
45 44 */
46   - List<SysDictDataDO> getDictDataList(SysDictDataExportReqVO reqVO);
  45 + void deleteDictData(Long id);
47 46  
48 47 /**
49   - * 获得字典数据详情
  48 + * 获得字典数据列表
50 49 *
51   - * @param id 字典数据编号
52   - * @return 字典数据
  50 + * @return 字典数据全列表
53 51 */
54   - SysDictDataDO getDictData(Long id);
  52 + List<SysDictDataDO> getDictDatas();
55 53  
56 54 /**
57   - * 创建字典数据
  55 + * 获得字典数据分页列表
58 56 *
59   - * @param reqVO 字典数据信息
60   - * @return 字典数据编号
  57 + * @param reqVO 分页请求
  58 + * @return 字典数据分页列表
61 59 */
62   - Long createDictData(SysDictDataCreateReqVO reqVO);
  60 + PageResult<SysDictDataDO> getDictDataPage(SysDictDataPageReqVO reqVO);
63 61  
64 62 /**
65   - * 更新字典数据
  63 + * 获得字典数据列表
66 64 *
67   - * @param reqVO 字典数据信息
  65 + * @param reqVO 列表请求
  66 + * @return 字典数据列表
68 67 */
69   - void updateDictData(SysDictDataUpdateReqVO reqVO);
  68 + List<SysDictDataDO> getDictDatas(SysDictDataExportReqVO reqVO);
70 69  
71 70 /**
72   - * 删除字典数据
  71 + * 获得字典数据详情
73 72 *
74 73 * @param id 字典数据编号
  74 + * @return 字典数据
75 75 */
76   - void deleteDictData(Long id);
  76 + SysDictDataDO getDictData(Long id);
77 77  
78 78 /**
79 79 * 获得指定字典类型的数据数量
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeService.java
... ... @@ -17,6 +17,28 @@ import java.util.List;
17 17 public interface SysDictTypeService {
18 18  
19 19 /**
  20 + * 创建字典类型
  21 + *
  22 + * @param reqVO 字典类型信息
  23 + * @return 字典类型编号
  24 + */
  25 + Long createDictType(SysDictTypeCreateReqVO reqVO);
  26 +
  27 + /**
  28 + * 更新字典类型
  29 + *
  30 + * @param reqVO 字典类型信息
  31 + */
  32 + void updateDictType(SysDictTypeUpdateReqVO reqVO);
  33 +
  34 + /**
  35 + * 删除字典类型
  36 + *
  37 + * @param id 字典类型编号
  38 + */
  39 + void deleteDictType(Long id);
  40 +
  41 + /**
20 42 * 获得字典类型分页列表
21 43 *
22 44 * @param reqVO 分页请求
... ... @@ -49,28 +71,6 @@ public interface SysDictTypeService {
49 71 SysDictTypeDO getDictType(String type);
50 72  
51 73 /**
52   - * 创建字典类型
53   - *
54   - * @param reqVO 字典类型信息
55   - * @return 字典类型编号
56   - */
57   - Long createDictType(SysDictTypeCreateReqVO reqVO);
58   -
59   - /**
60   - * 更新字典类型
61   - *
62   - * @param reqVO 字典类型信息
63   - */
64   - void updateDictType(SysDictTypeUpdateReqVO reqVO);
65   -
66   - /**
67   - * 删除字典类型
68   - *
69   - * @param id 字典类型编号
70   - */
71   - void deleteDictType(Long id);
72   -
73   - /**
74 74 * 获得全部字典类型列表
75 75 *
76 76 * @return 字典类型列表
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
... ... @@ -131,7 +131,7 @@ public class SysDictDataServiceImpl implements SysDictDataService {
131 131 }
132 132  
133 133 @Override
134   - public List<SysDictDataDO> getDictDataList() {
  134 + public List<SysDictDataDO> getDictDatas() {
135 135 List<SysDictDataDO> list = dictDataMapper.selectList();
136 136 list.sort(COMPARATOR_TYPE_AND_SORT);
137 137 return list;
... ... @@ -143,7 +143,7 @@ public class SysDictDataServiceImpl implements SysDictDataService {
143 143 }
144 144  
145 145 @Override
146   - public List<SysDictDataDO> getDictDataList(SysDictDataExportReqVO reqVO) {
  146 + public List<SysDictDataDO> getDictDatas(SysDictDataExportReqVO reqVO) {
147 147 List<SysDictDataDO> list = dictDataMapper.selectList(reqVO);
148 148 list.sort(COMPARATOR_TYPE_AND_SORT);
149 149 return list;
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysOperateLogService.java
... ... @@ -19,7 +19,7 @@ public interface SysOperateLogService extends OperateLogFrameworkService {
19 19 * @param reqVO 分页条件
20 20 * @return 操作日志分页列表
21 21 */
22   - PageResult<SysOperateLogDO> pageOperateLog(SysOperateLogPageReqVO reqVO);
  22 + PageResult<SysOperateLogDO> getOperateLogPage(SysOperateLogPageReqVO reqVO);
23 23  
24 24 /**
25 25 * 获得操作日志列表
... ... @@ -27,6 +27,6 @@ public interface SysOperateLogService extends OperateLogFrameworkService {
27 27 * @param reqVO 列表条件
28 28 * @return 日志列表
29 29 */
30   - List<SysOperateLogDO> listOperateLogs(SysOperateLogExportReqVO reqVO);
  30 + List<SysOperateLogDO> getOperateLogs(SysOperateLogExportReqVO reqVO);
31 31  
32 32 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysOperateLogServiceImpl.java
... ... @@ -55,11 +55,11 @@ public class SysOperateLogServiceImpl implements SysOperateLogService {
55 55 }
56 56  
57 57 @Override
58   - public PageResult<SysOperateLogDO> pageOperateLog(SysOperateLogPageReqVO reqVO) {
  58 + public PageResult<SysOperateLogDO> getOperateLogPage(SysOperateLogPageReqVO reqVO) {
59 59 // 处理基于用户昵称的查询
60 60 Collection<Long> userIds = null;
61 61 if (StrUtil.isNotEmpty(reqVO.getUserNickname())) {
62   - userIds = convertSet(userService.listUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId);
  62 + userIds = convertSet(userService.getUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId);
63 63 if (CollUtil.isEmpty(userIds)) {
64 64 return PageResult.empty();
65 65 }
... ... @@ -69,11 +69,11 @@ public class SysOperateLogServiceImpl implements SysOperateLogService {
69 69 }
70 70  
71 71 @Override
72   - public List<SysOperateLogDO> listOperateLogs(SysOperateLogExportReqVO reqVO) {
  72 + public List<SysOperateLogDO> getOperateLogs(SysOperateLogExportReqVO reqVO) {
73 73 // 处理基于用户昵称的查询
74 74 Collection<Long> userIds = null;
75 75 if (StrUtil.isNotEmpty(reqVO.getUserNickname())) {
76   - userIds = convertSet(userService.listUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId);
  76 + userIds = convertSet(userService.getUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId);
77 77 if (CollUtil.isEmpty(userIds)) {
78 78 return Collections.emptyList();
79 79 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/notice/SysNoticeService.java
... ... @@ -12,22 +12,6 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.notice.SysNoticeDO;
12 12 public interface SysNoticeService {
13 13  
14 14 /**
15   - * 获得岗位公告公告分页列表
16   - *
17   - * @param reqVO 分页条件
18   - * @return 部门分页列表
19   - */
20   - PageResult<SysNoticeDO> pageNotices(SysNoticePageReqVO reqVO);
21   -
22   - /**
23   - * 获得岗位公告公告信息
24   - *
25   - * @param id 岗位公告公告编号
26   - * @return 岗位公告公告信息
27   - */
28   - SysNoticeDO getNotice(Long id);
29   -
30   - /**
31 15 * 创建岗位公告公告
32 16 *
33 17 * @param reqVO 岗位公告公告信息
... ... @@ -48,4 +32,21 @@ public interface SysNoticeService {
48 32 * @param id 岗位公告公告编号
49 33 */
50 34 void deleteNotice(Long id);
  35 +
  36 + /**
  37 + * 获得岗位公告公告分页列表
  38 + *
  39 + * @param reqVO 分页条件
  40 + * @return 部门分页列表
  41 + */
  42 + PageResult<SysNoticeDO> pageNotices(SysNoticePageReqVO reqVO);
  43 +
  44 + /**
  45 + * 获得岗位公告公告信息
  46 + *
  47 + * @param id 岗位公告公告编号
  48 + * @return 岗位公告公告信息
  49 + */
  50 + SysNoticeDO getNotice(Long id);
  51 +
51 52 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/notice/impl/SysNoticeServiceImpl.java
... ... @@ -28,16 +28,6 @@ public class SysNoticeServiceImpl implements SysNoticeService {
28 28 private SysNoticeMapper noticeMapper;
29 29  
30 30 @Override
31   - public PageResult<SysNoticeDO> pageNotices(SysNoticePageReqVO reqVO) {
32   - return noticeMapper.selectPage(reqVO);
33   - }
34   -
35   - @Override
36   - public SysNoticeDO getNotice(Long id) {
37   - return noticeMapper.selectById(id);
38   - }
39   -
40   - @Override
41 31 public Long createNotice(SysNoticeCreateReqVO reqVO) {
42 32 SysNoticeDO notice = SysNoticeConvert.INSTANCE.convert(reqVO);
43 33 noticeMapper.insert(notice);
... ... @@ -61,6 +51,16 @@ public class SysNoticeServiceImpl implements SysNoticeService {
61 51 noticeMapper.deleteById(id);
62 52 }
63 53  
  54 + @Override
  55 + public PageResult<SysNoticeDO> pageNotices(SysNoticePageReqVO reqVO) {
  56 + return noticeMapper.selectPage(reqVO);
  57 + }
  58 +
  59 + @Override
  60 + public SysNoticeDO getNotice(Long id) {
  61 + return noticeMapper.selectById(id);
  62 + }
  63 +
64 64 @VisibleForTesting
65 65 public void checkNoticeExists(Long id) {
66 66 if (id == null) {
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysMenuService.java
... ... @@ -21,11 +21,33 @@ public interface SysMenuService {
21 21 void initLocalCache();
22 22  
23 23 /**
  24 + * 创建菜单
  25 + *
  26 + * @param reqVO 菜单信息
  27 + * @return 创建出来的菜单编号
  28 + */
  29 + Long createMenu(SysMenuCreateReqVO reqVO);
  30 +
  31 + /**
  32 + * 更新菜单
  33 + *
  34 + * @param reqVO 菜单信息
  35 + */
  36 + void updateMenu(SysMenuUpdateReqVO reqVO);
  37 +
  38 + /**
  39 + * 删除菜单
  40 + *
  41 + * @param id 菜单编号
  42 + */
  43 + void deleteMenu(Long id);
  44 +
  45 + /**
24 46 * 获得所有菜单列表
25 47 *
26 48 * @return 菜单列表
27 49 */
28   - List<SysMenuDO> listMenus();
  50 + List<SysMenuDO> getMenus();
29 51  
30 52 /**
31 53 * 筛选菜单列表
... ... @@ -33,7 +55,7 @@ public interface SysMenuService {
33 55 * @param reqVO 筛选条件请求 VO
34 56 * @return 菜单列表
35 57 */
36   - List<SysMenuDO> listMenus(SysMenuListReqVO reqVO);
  58 + List<SysMenuDO> getMenus(SysMenuListReqVO reqVO);
37 59  
38 60 /**
39 61 * 获得所有菜单,从缓存中
... ... @@ -67,28 +89,6 @@ public interface SysMenuService {
67 89 */
68 90 List<SysMenuDO> getMenuListByPermissionFromCache(String permission);
69 91  
70   - /*
71   - * 创建菜单
72   - *
73   - * @param reqVO 菜单信息
74   - * @return 创建出来的菜单编号
75   - */
76   - Long createMenu(SysMenuCreateReqVO reqVO);
77   -
78   - /**
79   - * 更新菜单
80   - *
81   - * @param reqVO 菜单信息
82   - */
83   - void updateMenu(SysMenuUpdateReqVO reqVO);
84   -
85   - /**
86   - * 删除菜单
87   - *
88   - * @param id 菜单编号
89   - */
90   - void deleteMenu(Long id);
91   -
92 92 /**
93 93 * 获得菜单
94 94 *
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionService.java
... ... @@ -32,8 +32,8 @@ public interface SysPermissionService extends SecurityPermissionFrameworkService
32 32 * @param menusStatuses 菜单状态数组
33 33 * @return 菜单列表
34 34 */
35   - List<SysMenuDO> listRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes,
36   - Collection<Integer> menusStatuses);
  35 + List<SysMenuDO> getRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes,
  36 + Collection<Integer> menusStatuses);
37 37  
38 38 /**
39 39 * 获得用户拥有的角色编号集合
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleService.java
... ... @@ -25,6 +25,45 @@ public interface SysRoleService {
25 25 void initLocalCache();
26 26  
27 27 /**
  28 + * 创建角色
  29 + *
  30 + * @param reqVO 创建角色信息
  31 + * @return 角色编号
  32 + */
  33 + Long createRole(SysRoleCreateReqVO reqVO);
  34 +
  35 + /**
  36 + * 更新角色
  37 + *
  38 + * @param reqVO 更新角色信息
  39 + */
  40 + void updateRole(SysRoleUpdateReqVO reqVO);
  41 +
  42 + /**
  43 + * 删除角色
  44 + *
  45 + * @param id 角色编号
  46 + */
  47 + void deleteRole(Long id);
  48 +
  49 + /**
  50 + * 更新角色状态
  51 + *
  52 + * @param id 角色编号
  53 + * @param status 状态
  54 + */
  55 + void updateRoleStatus(Long id, Integer status);
  56 +
  57 + /**
  58 + * 设置角色的数据权限
  59 + *
  60 + * @param id 角色编号
  61 + * @param dataScope 数据范围
  62 + * @param dataScopeDeptIds 部门编号数组
  63 + */
  64 + void updateRoleDataScope(Long id, Integer dataScope, Set<Long> dataScopeDeptIds);
  65 +
  66 + /**
28 67 * 获得角色,从缓存中
29 68 *
30 69 * @param id 角色编号
... ... @@ -38,7 +77,7 @@ public interface SysRoleService {
38 77 * @param statuses 筛选的状态。允许空,空时不筛选
39 78 * @return 角色列表
40 79 */
41   - List<SysRoleDO> listRoles(@Nullable Collection<Integer> statuses);
  80 + List<SysRoleDO> getRoles(@Nullable Collection<Integer> statuses);
42 81  
43 82 /**
44 83 * 获得角色数组,从缓存中
... ... @@ -46,7 +85,7 @@ public interface SysRoleService {
46 85 * @param ids 角色编号数组
47 86 * @return 角色数组
48 87 */
49   - List<SysRoleDO> listRolesFromCache(Collection<Long> ids);
  88 + List<SysRoleDO> getRolesFromCache(Collection<Long> ids);
50 89  
51 90 /**
52 91 * 判断角色数组中,是否有管理员
... ... @@ -63,32 +102,10 @@ public interface SysRoleService {
63 102 * @return 是否有管理员
64 103 */
65 104 default boolean hasAnyAdmin(Set<Long> ids) {
66   - return hasAnyAdmin(listRolesFromCache(ids));
  105 + return hasAnyAdmin(getRolesFromCache(ids));
67 106 }
68 107  
69 108 /**
70   - * 创建角色
71   - *
72   - * @param reqVO 创建角色信息
73   - * @return 角色编号
74   - */
75   - Long createRole(SysRoleCreateReqVO reqVO);
76   -
77   - /**
78   - * 更新角色
79   - *
80   - * @param reqVO 更新角色信息
81   - */
82   - void updateRole(SysRoleUpdateReqVO reqVO);
83   -
84   - /**
85   - * 删除角色
86   - *
87   - * @param id 角色编号
88   - */
89   - void deleteRole(Long id);
90   -
91   - /**
92 109 * 获得角色
93 110 *
94 111 * @param id 角色编号
... ... @@ -102,7 +119,7 @@ public interface SysRoleService {
102 119 * @param reqVO 角色分页查询
103 120 * @return 角色分页结果
104 121 */
105   - PageResult<SysRoleDO> pageRole(SysRolePageReqVO reqVO);
  122 + PageResult<SysRoleDO> getRolePage(SysRolePageReqVO reqVO);
106 123  
107 124 /**
108 125 * 获得角色列表
... ... @@ -110,23 +127,6 @@ public interface SysRoleService {
110 127 * @param reqVO 列表查询
111 128 * @return 角色列表
112 129 */
113   - List<SysRoleDO> listRoles(SysRoleExportReqVO reqVO);
114   -
115   - /**
116   - * 更新角色状态
117   - *
118   - * @param id 角色编号
119   - * @param status 状态
120   - */
121   - void updateRoleStatus(Long id, Integer status);
122   -
123   - /**
124   - * 设置角色的数据权限
125   - *
126   - * @param id 角色编号
127   - * @param dataScope 数据范围
128   - * @param dataScopeDeptIds 部门编号数组
129   - */
130   - void updateRoleDataScope(Long id, Integer dataScope, Set<Long> dataScopeDeptIds);
  130 + List<SysRoleDO> getRoles(SysRoleExportReqVO reqVO);
131 131  
132 132 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysMenuServiceImpl.java
... ... @@ -15,6 +15,7 @@ import cn.iocoder.dashboard.modules.system.redis.mq.producer.permission.SysMenuP
15 15 import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService;
16 16 import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
17 17 import cn.iocoder.dashboard.util.collection.CollectionUtils;
  18 +import com.google.common.annotations.VisibleForTesting;
18 19 import com.google.common.collect.ImmutableMap;
19 20 import com.google.common.collect.ImmutableMultimap;
20 21 import com.google.common.collect.Multimap;
... ... @@ -128,46 +129,6 @@ public class SysMenuServiceImpl implements SysMenuService {
128 129 }
129 130  
130 131 @Override
131   - public List<SysMenuDO> listMenus() {
132   - return menuMapper.selectList();
133   - }
134   -
135   - @Override
136   - public List<SysMenuDO> listMenus(SysMenuListReqVO reqVO) {
137   - return menuMapper.selectList(reqVO);
138   - }
139   -
140   - @Override
141   - public List<SysMenuDO> listMenusFromCache(Collection<Integer> menuTypes, Collection<Integer> menusStatuses) {
142   - // 任一一个参数为空,则返回空
143   - if (CollectionUtils.isAnyEmpty(menuTypes, menusStatuses)) {
144   - return Collections.emptyList();
145   - }
146   - // 创建新数组,避免缓存被修改
147   - return menuCache.values().stream().filter(menu -> menuTypes.contains(menu.getType())
148   - && menusStatuses.contains(menu.getStatus()))
149   - .collect(Collectors.toList());
150   - }
151   -
152   - @Override
153   - public List<SysMenuDO> listMenusFromCache(Collection<Long> menuIds, Collection<Integer> menuTypes,
154   - Collection<Integer> menusStatuses) {
155   - // 任一一个参数为空,则返回空
156   - if (CollectionUtils.isAnyEmpty(menuIds, menuTypes, menusStatuses)) {
157   - return Collections.emptyList();
158   - }
159   - return menuCache.values().stream().filter(menu -> menuIds.contains(menu.getId())
160   - && menuTypes.contains(menu.getType())
161   - && menusStatuses.contains(menu.getStatus()))
162   - .collect(Collectors.toList());
163   - }
164   -
165   - @Override
166   - public List<SysMenuDO> getMenuListByPermissionFromCache(String permission) {
167   - return new ArrayList<>(permissionMenuCache.get(permission));
168   - }
169   -
170   - @Override
171 132 public Long createMenu(SysMenuCreateReqVO reqVO) {
172 133 // 校验父菜单存在
173 134 checkParentResource(reqVO.getParentId(), null);
... ... @@ -208,10 +169,6 @@ public class SysMenuServiceImpl implements SysMenuService {
208 169 */
209 170 @Transactional(rollbackFor = Exception.class)
210 171 public void deleteMenu(Long menuId) {
211   - // 校验更新的菜单是否存在
212   - if (menuMapper.selectById(menuId) == null) {
213   - throw ServiceExceptionUtil.exception(MENU_NOT_EXISTS);
214   - }
215 172 // 校验是否还有子菜单
216 173 if (menuMapper.selectCountByParentId(menuId) > 0) {
217 174 throw ServiceExceptionUtil.exception(MENU_EXISTS_CHILDREN);
... ... @@ -236,6 +193,46 @@ public class SysMenuServiceImpl implements SysMenuService {
236 193 }
237 194  
238 195 @Override
  196 + public List<SysMenuDO> getMenus() {
  197 + return menuMapper.selectList();
  198 + }
  199 +
  200 + @Override
  201 + public List<SysMenuDO> getMenus(SysMenuListReqVO reqVO) {
  202 + return menuMapper.selectList(reqVO);
  203 + }
  204 +
  205 + @Override
  206 + public List<SysMenuDO> listMenusFromCache(Collection<Integer> menuTypes, Collection<Integer> menusStatuses) {
  207 + // 任一一个参数为空,则返回空
  208 + if (CollectionUtils.isAnyEmpty(menuTypes, menusStatuses)) {
  209 + return Collections.emptyList();
  210 + }
  211 + // 创建新数组,避免缓存被修改
  212 + return menuCache.values().stream().filter(menu -> menuTypes.contains(menu.getType())
  213 + && menusStatuses.contains(menu.getStatus()))
  214 + .collect(Collectors.toList());
  215 + }
  216 +
  217 + @Override
  218 + public List<SysMenuDO> listMenusFromCache(Collection<Long> menuIds, Collection<Integer> menuTypes,
  219 + Collection<Integer> menusStatuses) {
  220 + // 任一一个参数为空,则返回空
  221 + if (CollectionUtils.isAnyEmpty(menuIds, menuTypes, menusStatuses)) {
  222 + return Collections.emptyList();
  223 + }
  224 + return menuCache.values().stream().filter(menu -> menuIds.contains(menu.getId())
  225 + && menuTypes.contains(menu.getType())
  226 + && menusStatuses.contains(menu.getStatus()))
  227 + .collect(Collectors.toList());
  228 + }
  229 +
  230 + @Override
  231 + public List<SysMenuDO> getMenuListByPermissionFromCache(String permission) {
  232 + return new ArrayList<>(permissionMenuCache.get(permission));
  233 + }
  234 +
  235 + @Override
239 236 public SysMenuDO getMenu(Long id) {
240 237 return menuMapper.selectById(id);
241 238 }
... ... @@ -250,7 +247,8 @@ public class SysMenuServiceImpl implements SysMenuService {
250 247 * @param parentId 父菜单编号
251 248 * @param childId 当前菜单编号
252 249 */
253   - private void checkParentResource(Long parentId, Long childId) {
  250 + @VisibleForTesting
  251 + public void checkParentResource(Long parentId, Long childId) {
254 252 if (parentId == null || MenuIdEnum.ROOT.getId().equals(parentId)) {
255 253 return;
256 254 }
... ... @@ -279,7 +277,8 @@ public class SysMenuServiceImpl implements SysMenuService {
279 277 * @param parentId 父菜单编号
280 278 * @param id 菜单编号
281 279 */
282   - private void checkResource(Long parentId, String name, Long id) {
  280 + @VisibleForTesting
  281 + public void checkResource(Long parentId, String name, Long id) {
283 282 SysMenuDO menu = menuMapper.selectByParentIdAndName(parentId, name);
284 283 if (menu == null) {
285 284 return;
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java
... ... @@ -86,6 +86,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
86 86 @Override
87 87 @PostConstruct
88 88 public void initLocalCache() {
  89 + Date now = new Date();
89 90 // 获取角色与菜单的关联列表,如果有更新
90 91 List<SysRoleMenuDO> roleMenuList = this.loadRoleMenuIfUpdate(maxUpdateTime);
91 92 if (CollUtil.isEmpty(roleMenuList)) {
... ... @@ -102,7 +103,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
102 103 roleMenuCache = roleMenuCacheBuilder.build();
103 104 menuRoleCache = menuRoleCacheBuilder.build();
104 105 assert roleMenuList.size() > 0; // 断言,避免告警
105   - maxUpdateTime = roleMenuList.stream().max(Comparator.comparing(BaseDO::getUpdateTime)).get().getUpdateTime();
  106 + maxUpdateTime = now;
106 107 log.info("[initLocalCache][初始化角色与菜单的关联数量为 {}]", roleMenuList.size());
107 108 }
108 109  
... ... @@ -123,7 +124,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
123 124 if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
124 125 log.info("[loadRoleMenuIfUpdate][首次加载全量角色与菜单的关联]");
125 126 } else { // 判断数据库中是否有更新的角色与菜单的关联
126   - if (!roleMenuMapper.selectExistsByUpdateTimeAfter(maxUpdateTime)) {
  127 + if (Objects.isNull(roleMenuMapper.selectExistsByUpdateTimeAfter(maxUpdateTime))) {
127 128 return null;
128 129 }
129 130 log.info("[loadRoleMenuIfUpdate][增量加载全量角色与菜单的关联]");
... ... @@ -133,14 +134,14 @@ public class SysPermissionServiceImpl implements SysPermissionService {
133 134 }
134 135  
135 136 @Override
136   - public List<SysMenuDO> listRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes,
137   - Collection<Integer> menusStatuses) {
  137 + public List<SysMenuDO> getRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes,
  138 + Collection<Integer> menusStatuses) {
138 139 // 任一一个参数为空时,不返回任何菜单
139 140 if (CollectionUtils.isAnyEmpty(roleIds, menusStatuses, menusStatuses)) {
140 141 return Collections.emptyList();
141 142 }
142 143 // 判断角色是否包含管理员
143   - List<SysRoleDO> roleList = roleService.listRolesFromCache(roleIds);
  144 + List<SysRoleDO> roleList = roleService.getRolesFromCache(roleIds);
144 145 boolean hasAdmin = roleService.hasAnyAdmin(roleList);
145 146 // 获得角色拥有的菜单关联
146 147 if (hasAdmin) { // 管理员,获取到全部
... ... @@ -168,7 +169,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
168 169 // 如果是管理员的情况下,获取全部菜单编号
169 170 SysRoleDO role = roleService.getRole(roleId);
170 171 if (roleService.hasAnyAdmin(Collections.singletonList(role))) {
171   - return CollectionUtils.convertSet(menuService.listMenus(), SysMenuDO::getId);
  172 + return CollectionUtils.convertSet(menuService.getMenus(), SysMenuDO::getId);
172 173 }
173 174 // 如果是非管理员的情况下,获得拥有的菜单编号
174 175 return CollectionUtils.convertSet(roleMenuMapper.selectListByRoleId(roleId),
... ... @@ -231,22 +232,41 @@ public class SysPermissionServiceImpl implements SysPermissionService {
231 232 }
232 233  
233 234 @Override
  235 + @Transactional(rollbackFor = Exception.class)
234 236 public void processRoleDeleted(Long roleId) {
235   - // TODO 实现我
236   -// // 标记删除 RoleResource
237   -// roleResourceMapper.deleteByRoleId(roleId);
238   -// // 标记删除 AdminRole
239   -// adminRoleMapper.deleteByRoleId(roleId);
  237 + // 标记删除 UserRole
  238 + userRoleMapper.deleteListByRoleId(roleId);
  239 + // 标记删除 RoleMenu
  240 + roleMenuMapper.deleteListByRoleId(roleId);
  241 + // 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了
  242 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
  243 +
  244 + @Override
  245 + public void afterCommit() {
  246 + permissionProducer.sendRoleMenuRefreshMessage();
  247 + }
  248 +
  249 + });
240 250 }
241 251  
242 252 @Override
  253 + @Transactional(rollbackFor = Exception.class)
243 254 public void processMenuDeleted(Long menuId) {
244   - // TODO 实现我
  255 + roleMenuMapper.deleteListByMenuId(menuId);
  256 + // 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了
  257 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
  258 +
  259 + @Override
  260 + public void afterCommit() {
  261 + permissionProducer.sendRoleMenuRefreshMessage();
  262 + }
  263 +
  264 + });
245 265 }
246 266  
247 267 @Override
248 268 public void processUserDeleted(Long userId) {
249   - // TODO 实现我
  269 + userRoleMapper.deleteListByUserId(userId);
250 270 }
251 271  
252 272 @Override
... ... @@ -305,7 +325,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
305 325 if (roleService.hasAnyAdmin(roleIds)) {
306 326 return true;
307 327 }
308   - Set<String> userRoles = CollectionUtils.convertSet(roleService.listRolesFromCache(roleIds),
  328 + Set<String> userRoles = CollectionUtils.convertSet(roleService.getRolesFromCache(roleIds),
309 329 SysRoleDO::getCode);
310 330 return CollUtil.containsAny(userRoles, Sets.newHashSet(roles));
311 331 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java
... ... @@ -119,33 +119,6 @@ public class SysRoleServiceImpl implements SysRoleService {
119 119 }
120 120  
121 121 @Override
122   - public SysRoleDO getRoleFromCache(Long id) {
123   - return roleCache.get(id);
124   - }
125   -
126   - @Override
127   - public List<SysRoleDO> listRoles(@Nullable Collection<Integer> statuses) {
128   - return roleMapper.selectListByStatus(statuses);
129   - }
130   -
131   - @Override
132   - public List<SysRoleDO> listRolesFromCache(Collection<Long> ids) {
133   - if (CollectionUtil.isEmpty(ids)) {
134   - return Collections.emptyList();
135   - }
136   - return roleCache.values().stream().filter(roleDO -> ids.contains(roleDO.getId()))
137   - .collect(Collectors.toList());
138   - }
139   -
140   - @Override
141   - public boolean hasAnyAdmin(Collection<SysRoleDO> roleList) {
142   - if (CollectionUtil.isEmpty(roleList)) {
143   - return false;
144   - }
145   - return roleList.stream().anyMatch(roleDO -> RoleCodeEnum.ADMIN.getKey().equals(roleDO.getCode()));
146   - }
147   -
148   - @Override
149 122 public Long createRole(SysRoleCreateReqVO reqVO) {
150 123 // 校验角色
151 124 checkDuplicateRole(reqVO.getName(), reqVO.getCode(), null);
... ... @@ -174,6 +147,33 @@ public class SysRoleServiceImpl implements SysRoleService {
174 147 }
175 148  
176 149 @Override
  150 + public void updateRoleStatus(Long id, Integer status) {
  151 + // 校验是否可以更新
  152 + this.checkUpdateRole(id);
  153 + // 更新状态
  154 + SysRoleDO updateObject = new SysRoleDO();
  155 + updateObject.setId(id);
  156 + updateObject.setStatus(status);
  157 + roleMapper.updateById(updateObject);
  158 + // 发送刷新消息
  159 + roleProducer.sendRoleRefreshMessage();
  160 + }
  161 +
  162 + @Override
  163 + public void updateRoleDataScope(Long id, Integer dataScope, Set<Long> dataScopeDeptIds) {
  164 + // 校验是否可以更新
  165 + checkUpdateRole(id);
  166 + // 更新数据范围
  167 + SysRoleDO updateObject = new SysRoleDO();
  168 + updateObject.setId(id);
  169 + updateObject.setDataScope(dataScope);
  170 + updateObject.setDataScopeDeptIds(dataScopeDeptIds);
  171 + roleMapper.updateById(updateObject);
  172 + // 发送刷新消息
  173 + roleProducer.sendRoleRefreshMessage();
  174 + }
  175 +
  176 + @Override
177 177 @Transactional(rollbackFor = Exception.class)
178 178 public void deleteRole(Long id) {
179 179 // 校验是否可以更新
... ... @@ -194,45 +194,45 @@ public class SysRoleServiceImpl implements SysRoleService {
194 194 }
195 195  
196 196 @Override
197   - public SysRoleDO getRole(Long id) {
198   - return roleMapper.selectById(id);
  197 + public SysRoleDO getRoleFromCache(Long id) {
  198 + return roleCache.get(id);
199 199 }
200 200  
201 201 @Override
202   - public PageResult<SysRoleDO> pageRole(SysRolePageReqVO reqVO) {
203   - return roleMapper.selectPage(reqVO);
  202 + public List<SysRoleDO> getRoles(@Nullable Collection<Integer> statuses) {
  203 + return roleMapper.selectListByStatus(statuses);
204 204 }
205 205  
206 206 @Override
207   - public List<SysRoleDO> listRoles(SysRoleExportReqVO reqVO) {
208   - return roleMapper.listRoles(reqVO);
  207 + public List<SysRoleDO> getRolesFromCache(Collection<Long> ids) {
  208 + if (CollectionUtil.isEmpty(ids)) {
  209 + return Collections.emptyList();
  210 + }
  211 + return roleCache.values().stream().filter(roleDO -> ids.contains(roleDO.getId()))
  212 + .collect(Collectors.toList());
209 213 }
210 214  
211 215 @Override
212   - public void updateRoleStatus(Long id, Integer status) {
213   - // 校验是否可以更新
214   - this.checkUpdateRole(id);
215   - // 更新状态
216   - SysRoleDO updateObject = new SysRoleDO();
217   - updateObject.setId(id);
218   - updateObject.setStatus(status);
219   - roleMapper.updateById(updateObject);
220   - // 发送刷新消息
221   - roleProducer.sendRoleRefreshMessage();
  216 + public boolean hasAnyAdmin(Collection<SysRoleDO> roleList) {
  217 + if (CollectionUtil.isEmpty(roleList)) {
  218 + return false;
  219 + }
  220 + return roleList.stream().anyMatch(roleDO -> RoleCodeEnum.ADMIN.getKey().equals(roleDO.getCode()));
222 221 }
223 222  
224 223 @Override
225   - public void updateRoleDataScope(Long id, Integer dataScope, Set<Long> dataScopeDeptIds) {
226   - // 校验是否可以更新
227   - checkUpdateRole(id);
228   - // 更新数据范围
229   - SysRoleDO updateObject = new SysRoleDO();
230   - updateObject.setId(id);
231   - updateObject.setDataScope(dataScope);
232   - updateObject.setDataScopeDeptIds(dataScopeDeptIds);
233   - roleMapper.updateById(updateObject);
234   - // 发送刷新消息
235   - roleProducer.sendRoleRefreshMessage();
  224 + public SysRoleDO getRole(Long id) {
  225 + return roleMapper.selectById(id);
  226 + }
  227 +
  228 + @Override
  229 + public PageResult<SysRoleDO> getRolePage(SysRolePageReqVO reqVO) {
  230 + return roleMapper.selectPage(reqVO);
  231 + }
  232 +
  233 + @Override
  234 + public List<SysRoleDO> getRoles(SysRoleExportReqVO reqVO) {
  235 + return roleMapper.listRoles(reqVO);
236 236 }
237 237  
238 238 /**
... ... @@ -278,16 +278,10 @@ public class SysRoleServiceImpl implements SysRoleService {
278 278 }
279 279 }
280 280  
281   -
282   -// /**
283   -// * 根据条件分页查询角色数据
284   -// *
285   -// * @param role 角色信息
286   -// * @return 角色数据集合信息
287   -// */
288 281 // @Override
289 282 // @DataScope(deptAlias = "d")
290 283 // public List<SysRole> selectRoleList(SysRole role) {
291 284 // return roleMapper.selectRoleList(role);
292 285 // }
  286 +
293 287 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserService.java
... ... @@ -2,12 +2,13 @@ package cn.iocoder.dashboard.modules.system.service.user;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.dashboard.common.pojo.PageResult;
  5 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
  6 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
5 7 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
6 8 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
7 9 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
8 10 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;
9 11 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
10   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
11 12 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
12 13 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
13 14 import cn.iocoder.dashboard.util.collection.CollectionUtils;
... ... @@ -26,12 +27,74 @@ import java.util.Map;
26 27 public interface SysUserService {
27 28  
28 29 /**
  30 + * 创建用户
  31 + *
  32 + * @param reqVO 用户信息
  33 + * @return 用户编号
  34 + */
  35 + Long createUser(SysUserCreateReqVO reqVO);
  36 +
  37 + /**
  38 + * 修改用户
  39 + *
  40 + * @param reqVO 用户信息
  41 + */
  42 + void updateUser(SysUserUpdateReqVO reqVO);
  43 +
  44 + /**
  45 + * 修改用户个人信息
  46 + *
  47 + * @param id 用户编号
  48 + * @param reqVO 用户个人信息
  49 + */
  50 + void updateUserProfile(Long id, SysUserProfileUpdateReqVO reqVO);
  51 +
  52 + /**
  53 + * 修改用户个人密码
  54 + *
  55 + * @param id 用户编号
  56 + * @param reqVO 更新用户个人密码
  57 + */
  58 + void updateUserPassword(Long id, SysUserProfileUpdatePasswordReqVO reqVO);
  59 +
  60 + /**
  61 + * 更新用户头像
  62 + *
  63 + * @param id 用户 id
  64 + * @param avatarFile 头像文件
  65 + */
  66 + void updateUserAvatar(Long id, InputStream avatarFile);
  67 +
  68 + /**
  69 + * 修改密码
  70 + *
  71 + * @param id 用户编号
  72 + * @param password 密码
  73 + */
  74 + void updateUserPassword(Long id, String password);
  75 +
  76 + /**
  77 + * 修改密码
  78 + *
  79 + * @param id 用户编号
  80 + * @param status 状态
  81 + */
  82 + void updateUserStatus(Long id, Integer status);
  83 +
  84 + /**
  85 + * 删除用户
  86 + *
  87 + * @param id 用户编号
  88 + */
  89 + void deleteUser(Long id);
  90 +
  91 + /**
29 92 * 通过用户名查询用户
30 93 *
31 94 * @param username 用户名
32 95 * @return 用户对象信息
33 96 */
34   - SysUserDO getUserByUserName(String username);
  97 + SysUserDO getUserByUsername(String username);
35 98  
36 99 /**
37 100 * 通过用户 ID 查询用户
... ... @@ -47,7 +110,7 @@ public interface SysUserService {
47 110 * @param reqVO 分页条件
48 111 * @return 分页列表
49 112 */
50   - PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO);
  113 + PageResult<SysUserDO> getUserPage(SysUserPageReqVO reqVO);
51 114  
52 115 /**
53 116 * 获得用户列表
... ... @@ -55,7 +118,7 @@ public interface SysUserService {
55 118 * @param reqVO 列表请求
56 119 * @return 用户列表
57 120 */
58   - List<SysUserDO> listUsers(SysUserExportReqVO reqVO);
  121 + List<SysUserDO> getUsers(SysUserExportReqVO reqVO);
59 122  
60 123 /**
61 124 * 获得用户列表
... ... @@ -63,7 +126,7 @@ public interface SysUserService {
63 126 * @param ids 用户编号数组
64 127 * @return 用户列表
65 128 */
66   - List<SysUserDO> listUsers(Collection<Long> ids);
  129 + List<SysUserDO> getUsers(Collection<Long> ids);
67 130  
68 131 /**
69 132 * 获得用户 Map
... ... @@ -75,7 +138,7 @@ public interface SysUserService {
75 138 if (CollUtil.isEmpty(ids)) {
76 139 return new HashMap<>();
77 140 }
78   - return CollectionUtils.convertMap(listUsers(ids), SysUserDO::getId);
  141 + return CollectionUtils.convertMap(getUsers(ids), SysUserDO::getId);
79 142 }
80 143  
81 144 /**
... ... @@ -84,7 +147,7 @@ public interface SysUserService {
84 147 * @param nickname 昵称
85 148 * @return 用户列表
86 149 */
87   - List<SysUserDO> listUsersByNickname(String nickname);
  150 + List<SysUserDO> getUsersByNickname(String nickname);
88 151  
89 152 /**
90 153 * 获得用户列表,基于用户账号模糊匹配
... ... @@ -92,53 +155,7 @@ public interface SysUserService {
92 155 * @param username 用户账号
93 156 * @return 用户列表
94 157 */
95   - List<SysUserDO> listUsersByUsername(String username);
96   -
97   - /**
98   - * 创建用户
99   - *
100   - * @param reqVO 用户信息
101   - * @return 用户编号
102   - */
103   - Long createUser(SysUserCreateReqVO reqVO);
104   -
105   - /**
106   - * 修改用户
107   - *
108   - * @param reqVO 用户信息
109   - */
110   - void updateUser(SysUserUpdateReqVO reqVO);
111   -
112   - /**
113   - * 修改用户个人信息
114   - *
115   - * @param reqVO 用户个人信息
116   - * @return 修改结果
117   - */
118   - void updateUserProfile(SysUserProfileUpdateReqVO reqVO);
119   -
120   - /**
121   - * 删除用户
122   - *
123   - * @param id 用户编号
124   - */
125   - void deleteUser(Long id);
126   -
127   - /**
128   - * 修改密码
129   - *
130   - * @param id 用户编号
131   - * @param password 密码
132   - */
133   - void updateUserPassword(Long id, String password);
134   -
135   - /**
136   - * 修改密码
137   - *
138   - * @param id 用户编号
139   - * @param status 状态
140   - */
141   - void updateUserStatus(Long id, Integer status);
  158 + List<SysUserDO> getUsersByUsername(String username);
142 159  
143 160 /**
144 161 * 批量导入用户
... ... @@ -149,47 +166,4 @@ public interface SysUserService {
149 166 */
150 167 SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport);
151 168  
152   - /**
153   - * 更新用户头像
154   - *
155   - * @param id 用户 id
156   - * @param avatarFile 头像文件
157   - */
158   - void updateAvatar(Long id, InputStream avatarFile);
159   -
160   -//
161   -// /**
162   -// * 修改用户基本信息
163   -// *
164   -// * @param user 用户信息
165   -// * @return 结果
166   -// */
167   -// public int updateUserProfile(SysUser user);
168   -//
169   -// /**
170   -// * 修改用户头像
171   -// *
172   -// * @param userName 用户名
173   -// * @param avatar 头像地址
174   -// * @return 结果
175   -// */
176   -// public boolean updateUserAvatar(String userName, String avatar);
177   -//
178   -// /**
179   -// * 重置用户密码
180   -// *
181   -// * @param user 用户信息
182   -// * @return 结果
183   -// */
184   -// public int resetPwd(SysUser user);
185   -//
186   -// /**
187   -// * 重置用户密码
188   -// *
189   -// * @param userName 用户名
190   -// * @param password 密码
191   -// * @return 结果
192   -// */
193   -// public int resetUserPwd(String userName, String password);
194   -
195 169 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java
... ... @@ -9,12 +9,13 @@ import cn.iocoder.dashboard.common.exception.ServiceException;
9 9 import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
10 10 import cn.iocoder.dashboard.common.pojo.PageResult;
11 11 import cn.iocoder.dashboard.modules.infra.service.file.InfFileService;
  12 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
  13 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
12 14 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
13 15 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
14 16 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
15 17 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;
16 18 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
17   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
18 19 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
19 20 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
20 21 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
... ... @@ -61,65 +62,12 @@ public class SysUserServiceImpl implements SysUserService {
61 62 private SysPostService postService;
62 63 @Resource
63 64 private SysPermissionService permissionService;
64   -
65 65 @Resource
66 66 private PasswordEncoder passwordEncoder;
67   -
68 67 @Resource
69 68 private InfFileService fileService;
70 69  
71 70 @Override
72   - public SysUserDO getUserByUserName(String username) {
73   - return userMapper.selectByUsername(username);
74   - }
75   -
76   - @Override
77   - public SysUserDO getUser(Long id) {
78   - return userMapper.selectById(id);
79   - }
80   -
81   - @Override
82   - public PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO) {
83   - return userMapper.selectPage(reqVO, this.getDeptCondition(reqVO.getDeptId()));
84   - }
85   -
86   - @Override
87   - public List<SysUserDO> listUsers(SysUserExportReqVO reqVO) {
88   - return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId()));
89   - }
90   -
91   - @Override
92   - public List<SysUserDO> listUsers(Collection<Long> ids) {
93   - return userMapper.selectBatchIds(ids);
94   - }
95   -
96   - @Override
97   - public List<SysUserDO> listUsersByNickname(String nickname) {
98   - return userMapper.selectListByNickname(nickname);
99   - }
100   -
101   - @Override
102   - public List<SysUserDO> listUsersByUsername(String username) {
103   - return userMapper.selectListByUsername(username);
104   - }
105   -
106   - /**
107   - * 获得部门条件:查询指定部门的子部门编号们,包括自身
108   - *
109   - * @param deptId 部门编号
110   - * @return 部门编号集合
111   - */
112   - private Set<Long> getDeptCondition(Long deptId) {
113   - if (deptId == null) {
114   - return Collections.emptySet();
115   - }
116   - Set<Long> deptIds = CollectionUtils.convertSet(deptService.listDeptsByParentIdFromCache(
117   - deptId, true), SysDeptDO::getId);
118   - deptIds.add(deptId); // 包括自身
119   - return deptIds;
120   - }
121   -
122   - @Override
123 71 public Long createUser(SysUserCreateReqVO reqVO) {
124 72 // 校验正确性
125 73 this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
... ... @@ -143,30 +91,35 @@ public class SysUserServiceImpl implements SysUserService {
143 91 }
144 92  
145 93 @Override
146   - public void updateUserProfile(SysUserProfileUpdateReqVO reqVO) {
  94 + public void updateUserProfile(Long id, SysUserProfileUpdateReqVO reqVO) {
147 95 // 校验正确性
148   - this.checkUserExists(reqVO.getId());
149   - this.checkEmailUnique(reqVO.getId(), reqVO.getEmail());
150   - this.checkMobileUnique(reqVO.getId(), reqVO.getMobile());
151   - // 校验填写密码
152   - String encode = null;
153   - if (this.checkOldPassword(reqVO.getId(), reqVO.getOldPassword(), reqVO.getNewPassword())) {
154   - // 更新密码
155   - encode = passwordEncoder.encode(reqVO.getNewPassword());
156   - }
157   - SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO);
158   - if (StrUtil.isNotBlank(encode)) {
159   - updateObj.setPassword(encode);
160   - }
  96 + this.checkUserExists(id);
  97 + this.checkEmailUnique(id, reqVO.getEmail());
  98 + this.checkMobileUnique(id, reqVO.getMobile());
  99 + // 执行更新
  100 + userMapper.updateById(SysUserConvert.INSTANCE.convert(reqVO).setId(id));
  101 + }
  102 +
  103 + @Override
  104 + public void updateUserPassword(Long id, SysUserProfileUpdatePasswordReqVO reqVO) {
  105 + // 校验旧密码密码
  106 + this.checkOldPassword(id, reqVO.getOldPassword());
  107 + // 执行更新
  108 + SysUserDO updateObj = new SysUserDO().setId(id);
  109 + updateObj.setPassword(passwordEncoder.encode(reqVO.getNewPassword())); // 加密密码
161 110 userMapper.updateById(updateObj);
162 111 }
163 112  
164 113 @Override
165   - public void deleteUser(Long id) {
166   - // 校验用户存在
  114 + public void updateUserAvatar(Long id, InputStream avatarFile) {
167 115 this.checkUserExists(id);
168   - // 删除用户
169   - userMapper.deleteById(id);
  116 + // 存储文件
  117 + String avatar = fileService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile));
  118 + // 更新路径
  119 + SysUserDO sysUserDO = new SysUserDO();
  120 + sysUserDO.setId(id);
  121 + sysUserDO.setAvatar(avatar);
  122 + userMapper.updateById(sysUserDO);
170 123 }
171 124  
172 125 @Override
... ... @@ -193,6 +146,65 @@ public class SysUserServiceImpl implements SysUserService {
193 146 permissionService.processUserDeleted(id);
194 147 }
195 148  
  149 + @Override
  150 + public void deleteUser(Long id) {
  151 + // 校验用户存在
  152 + this.checkUserExists(id);
  153 + // 删除用户
  154 + userMapper.deleteById(id);
  155 + }
  156 +
  157 + @Override
  158 + public SysUserDO getUserByUsername(String username) {
  159 + return userMapper.selectByUsername(username);
  160 + }
  161 +
  162 + @Override
  163 + public SysUserDO getUser(Long id) {
  164 + return userMapper.selectById(id);
  165 + }
  166 +
  167 + @Override
  168 + public PageResult<SysUserDO> getUserPage(SysUserPageReqVO reqVO) {
  169 + return userMapper.selectPage(reqVO, this.getDeptCondition(reqVO.getDeptId()));
  170 + }
  171 +
  172 + @Override
  173 + public List<SysUserDO> getUsers(SysUserExportReqVO reqVO) {
  174 + return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId()));
  175 + }
  176 +
  177 + @Override
  178 + public List<SysUserDO> getUsers(Collection<Long> ids) {
  179 + return userMapper.selectBatchIds(ids);
  180 + }
  181 +
  182 + @Override
  183 + public List<SysUserDO> getUsersByNickname(String nickname) {
  184 + return userMapper.selectListByNickname(nickname);
  185 + }
  186 +
  187 + @Override
  188 + public List<SysUserDO> getUsersByUsername(String username) {
  189 + return userMapper.selectListByUsername(username);
  190 + }
  191 +
  192 + /**
  193 + * 获得部门条件:查询指定部门的子部门编号们,包括自身
  194 + *
  195 + * @param deptId 部门编号
  196 + * @return 部门编号集合
  197 + */
  198 + private Set<Long> getDeptCondition(Long deptId) {
  199 + if (deptId == null) {
  200 + return Collections.emptySet();
  201 + }
  202 + Set<Long> deptIds = CollectionUtils.convertSet(deptService.getDeptsByParentIdFromCache(
  203 + deptId, true), SysDeptDO::getId);
  204 + deptIds.add(deptId); // 包括自身
  205 + return deptIds;
  206 + }
  207 +
196 208 private void checkCreateOrUpdate(Long id, String username, String mobile, String email,
197 209 Long deptId, Set<Long> postIds) {
198 210 // 校验用户存在
... ... @@ -287,7 +299,7 @@ public class SysUserServiceImpl implements SysUserService {
287 299 if (CollUtil.isEmpty(postIds)) { // 允许不选择
288 300 return;
289 301 }
290   - List<SysPostDO> posts = postService.listPosts(postIds, null);
  302 + List<SysPostDO> posts = postService.getPosts(postIds, null);
291 303 if (CollUtil.isEmpty(posts)) {
292 304 throw ServiceExceptionUtil.exception(POST_NOT_FOUND);
293 305 }
... ... @@ -304,26 +316,19 @@ public class SysUserServiceImpl implements SysUserService {
304 316 }
305 317  
306 318 /**
307   - * 校验旧密码、新密码
  319 + * 校验旧密码
308 320 *
309 321 * @param id 用户 id
310 322 * @param oldPassword 旧密码
311   - * @param newPassword 新密码
312   - * @return 校验结果
313 323 */
314   - private boolean checkOldPassword(Long id, String oldPassword, String newPassword) {
315   - if (id == null || StrUtil.isBlank(oldPassword) || StrUtil.isBlank(newPassword)) {
316   - return false;
317   - }
  324 + private void checkOldPassword(Long id, String oldPassword) {
318 325 SysUserDO user = userMapper.selectById(id);
319 326 if (user == null) {
320 327 throw ServiceExceptionUtil.exception(USER_NOT_EXISTS);
321 328 }
322   -
323 329 if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
324 330 throw ServiceExceptionUtil.exception(USER_PASSWORD_FAILED);
325 331 }
326   - return true;
327 332 }
328 333  
329 334 @Override
... ... @@ -364,16 +369,4 @@ public class SysUserServiceImpl implements SysUserService {
364 369 return respVO;
365 370 }
366 371  
367   - @Override
368   - public void updateAvatar(Long id, InputStream avatarFile) {
369   - this.checkUserExists(id);
370   - // 存储文件
371   - String avatar = fileService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile));
372   - // 更新路径
373   - SysUserDO sysUserDO = new SysUserDO();
374   - sysUserDO.setId(id);
375   - sysUserDO.setAvatar(avatar);
376   - userMapper.updateById(sysUserDO);
377   - }
378   -
379 372 }
... ...
src/test-integration/java/cn/iocoder/dashboard/BaseRedisIntegrationTest.java 0 → 100644
  1 +package cn.iocoder.dashboard;
  2 +
  3 +import cn.iocoder.dashboard.framework.redis.config.RedisConfig;
  4 +import org.redisson.spring.starter.RedissonAutoConfiguration;
  5 +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
  6 +import org.springframework.boot.test.context.SpringBootTest;
  7 +import org.springframework.context.annotation.Import;
  8 +import org.springframework.test.context.ActiveProfiles;
  9 +
  10 +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseRedisIntegrationTest.Application.class)
  11 +@ActiveProfiles("integration-test") // 设置使用 application-integration-test 配置文件
  12 +public class BaseRedisIntegrationTest {
  13 +
  14 + @Import({
  15 + // Redis 配置类
  16 + RedisAutoConfiguration.class, // Spring Redis 自动配置类
  17 + RedisConfig.class, // 自己的 Redis 配置类
  18 + RedissonAutoConfiguration.class, // Redisson 自动高配置类
  19 + })
  20 + public static class Application {
  21 + }
  22 +
  23 +}
... ...
src/test/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManagerTest.java renamed to src/test-integration/java/cn/iocoder/dashboard/framework/quartz/core/SchedulerManagerTest.java
1   -package cn.iocoder.dashboard.framework.quartz.core.scheduler;
  1 +package cn.iocoder.dashboard.framework.quartz.core;
2 2  
3 3 import cn.hutool.core.util.StrUtil;
4 4 import cn.iocoder.dashboard.BaseDbUnitTest;
  5 +import cn.iocoder.dashboard.framework.quartz.core.scheduler.SchedulerManager;
5 6 import cn.iocoder.dashboard.modules.system.job.auth.SysUserSessionTimeoutJob;
6 7 import org.junit.jupiter.api.Test;
7 8 import org.quartz.SchedulerException;
... ...
src/test-integration/java/cn/iocoder/dashboard/framework/redis/core/stream/RedisStreamTest.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.redis.core.stream;
  2 +
  3 +import cn.hutool.core.thread.ThreadUtil;
  4 +import cn.iocoder.dashboard.BaseRedisIntegrationTest;
  5 +import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils;
  6 +import cn.iocoder.dashboard.modules.system.mq.consumer.mail.SysMailSendConsumer;
  7 +import cn.iocoder.dashboard.modules.system.mq.consumer.sms.SysSmsSendConsumer;
  8 +import cn.iocoder.dashboard.modules.system.mq.message.mail.SysMailSendMessage;
  9 +import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage;
  10 +import org.junit.jupiter.api.Disabled;
  11 +import org.junit.jupiter.api.Test;
  12 +import org.springframework.context.annotation.Import;
  13 +import org.springframework.data.redis.core.RedisTemplate;
  14 +import org.springframework.data.redis.core.StringRedisTemplate;
  15 +
  16 +import javax.annotation.Resource;
  17 +import java.util.concurrent.TimeUnit;
  18 +
  19 +public class RedisStreamTest {
  20 +
  21 + @Import({SysSmsSendConsumer.class, SysMailSendConsumer.class})
  22 + @Disabled
  23 + public static class ConsumerTest extends BaseRedisIntegrationTest {
  24 +
  25 + @Test
  26 + public void testConsumer() {
  27 + ThreadUtil.sleep(1, TimeUnit.DAYS);
  28 + }
  29 +
  30 + }
  31 +
  32 + @Disabled
  33 + public static class ProducerTest extends BaseRedisIntegrationTest {
  34 +
  35 + @Resource
  36 + private StringRedisTemplate stringRedisTemplate;
  37 +
  38 + @Resource
  39 + private RedisTemplate<String, Object> redisTemplate;
  40 +
  41 + @Test
  42 + public void testProducer01() {
  43 + for (int i = 0; i < 100; i++) {
  44 + // 创建消息
  45 + SysSmsSendMessage message = new SysSmsSendMessage();
  46 + message.setMobile("15601691300").setTemplateCode("test:" + i);
  47 + // 发送消息
  48 + RedisMessageUtils.sendStreamMessage(stringRedisTemplate, message);
  49 + }
  50 + }
  51 +
  52 + @Test
  53 + public void testProducer02() {
  54 + // 创建消息
  55 + SysMailSendMessage message = new SysMailSendMessage();
  56 + message.setAddress("fangfang@mihayou.com").setTemplateCode("test");
  57 + // 发送消息
  58 + RedisMessageUtils.sendStreamMessage(stringRedisTemplate, message);
  59 + }
  60 +
  61 + }
  62 +
  63 +}
... ...
src/test/java/cn/iocoder/dashboard/modules/tool/dal/mysql/codegen/ToolInformationSchemaColumnMapperTest.java renamed to src/test-integration/java/cn/iocoder/dashboard/modules/tool/dal/mysql/codegen/ToolInformationSchemaColumnMapperTest.java
src/test/java/cn/iocoder/dashboard/modules/tool/dal/mysql/codegen/ToolInformationSchemaTableMapperTest.java renamed to src/test-integration/java/cn/iocoder/dashboard/modules/tool/dal/mysql/codegen/ToolInformationSchemaTableMapperTest.java
src/test/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenEngineTest.java renamed to src/test-integration/java/cn/iocoder/dashboard/modules/tool/service/codegen/ToolCodegenEngineTest.java
1   -package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
  1 +package cn.iocoder.dashboard.modules.tool.service.codegen;
2 2  
3 3 import cn.iocoder.dashboard.BaseDbUnitTest;
4 4 import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenColumnDO;
5 5 import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenTableDO;
6 6 import cn.iocoder.dashboard.modules.tool.dal.mysql.codegen.ToolCodegenColumnMapper;
7 7 import cn.iocoder.dashboard.modules.tool.dal.mysql.codegen.ToolCodegenTableMapper;
  8 +import cn.iocoder.dashboard.modules.tool.service.codegen.impl.ToolCodegenEngine;
8 9 import org.junit.jupiter.api.Test;
9 10  
10 11 import javax.annotation.Resource;
... ...
src/test/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenSQLParserTest.java renamed to src/test-integration/java/cn/iocoder/dashboard/modules/tool/service/codegen/ToolCodegenSQLParserTest.java
1   -package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
  1 +package cn.iocoder.dashboard.modules.tool.service.codegen;
2 2  
3 3 import cn.iocoder.dashboard.BaseDbUnitTest;
  4 +import cn.iocoder.dashboard.modules.tool.service.codegen.impl.ToolCodegenSQLParser;
4 5 import org.junit.jupiter.api.Test;
5 6  
6 7 public class ToolCodegenSQLParserTest extends BaseDbUnitTest {
... ...
src/test/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenServiceImplTest.java renamed to src/test-integration/java/cn/iocoder/dashboard/modules/tool/service/codegen/ToolCodegenServiceImplTest.java
1   -package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
  1 +package cn.iocoder.dashboard.modules.tool.service.codegen;
2 2  
3 3 import cn.iocoder.dashboard.BaseDbUnitTest;
  4 +import cn.iocoder.dashboard.modules.tool.service.codegen.impl.ToolCodegenServiceImpl;
4 5 import org.junit.jupiter.api.Test;
5 6  
6 7 import javax.annotation.Resource;
... ...
src/test-integration/resources/application-integration-test.yaml 0 → 100644
  1 +spring:
  2 + main:
  3 + lazy-initialization: true # 开启懒加载,加快速度
  4 + banner-mode: off # 单元测试,禁用 Banner
  5 +
  6 +--- #################### 数据库相关配置 ####################
  7 +
  8 +spring:
  9 + # 数据源配置项
  10 + datasource:
  11 + name: ruoyi-vue-pro
  12 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写
  13 + driver-class-name: org.h2.Driver
  14 + username: sa
  15 + password:
  16 + schema: classpath:sql/create_tables.sql # MySQL 转 H2 的语句,使用 https://www.jooq.org/translate/ 工具
  17 + druid:
  18 + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
  19 + initial-size: 1 # 单元测试,配置为 1,提升启动速度
  20 +
  21 + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
  22 + redis:
  23 + host: 127.0.0.1 # 地址
  24 + port: 6379 # 端口(单元测试,使用 16379 端口)
  25 + database: 0 # 数据库索引
  26 +
  27 +mybatis:
  28 + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
  29 +
  30 +--- #################### 定时任务相关配置 ####################
  31 +
  32 +--- #################### 配置中心相关配置 ####################
  33 +
  34 +--- #################### 服务保障相关配置 ####################
  35 +
  36 +# Lock4j 配置项(单元测试,禁用 Lock4j)
  37 +
  38 +# Resilience4j 配置项
  39 +resilience4j:
  40 + ratelimiter:
  41 + instances:
  42 + backendA:
  43 + limit-for-period: 1 # 每个周期内,允许的请求数。默认为 50
  44 + limit-refresh-period: 60s # 每个周期的时长,单位:微秒。默认为 500
  45 + timeout-duration: 1s # 被限流时,阻塞等待的时长,单位:微秒。默认为 5s
  46 + register-health-indicator: true # 是否注册到健康监测
  47 +
  48 +--- #################### 监控相关配置 ####################
  49 +
  50 +--- #################### 芋道相关配置 ####################
  51 +
  52 +# 芋道配置项,设置当前项目所有自定义的配置
  53 +yudao:
  54 + info:
  55 + version: 1.0.0
  56 + base-package: cn.iocoder.dashboard
  57 + web:
  58 + api-prefix: /api
  59 + controller-package: ${yudao.info.base-package}
  60 + security:
  61 + token-header: Authorization
  62 + token-secret: abcdefghijklmnopqrstuvwxyz
  63 + token-timeout: 1d
  64 + session-timeout: 30m
  65 + mock-enable: true
  66 + mock-secret: test
  67 + swagger:
  68 + enable: false # 单元测试,禁用 Swagger
  69 + captcha:
  70 + timeout: 5m
  71 + width: 160
  72 + height: 60
  73 + file:
  74 + base-path: http://127.0.0.1:${server.port}/${yudao.web.api-prefix}/file/get/
  75 + codegen:
  76 + base-package: ${yudao.info.base-package}.modules
  77 + db-schemas: ${spring.datasource.name}
  78 + xss:
  79 + enable: false
  80 + exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
  81 + - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
  82 + - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
... ...
src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java
... ... @@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
9 9 import org.redisson.spring.starter.RedissonAutoConfiguration;
10 10 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
11 11 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  12 +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
12 13 import org.springframework.boot.test.context.SpringBootTest;
13 14 import org.springframework.context.annotation.Import;
14 15 import org.springframework.test.context.ActiveProfiles;
... ... @@ -30,6 +31,7 @@ public class BaseDbAndRedisUnitTest {
30 31 // DB 配置类
31 32 DataSourceConfiguration.class, // 自己的 DB 配置类
32 33 DataSourceAutoConfiguration.class, // Spring DB 自动配置类
  34 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
33 35 DruidDataSourceAutoConfigure.class, // Druid 自动配置类
34 36 // MyBatis 配置类
35 37 MybatisConfiguration.class, // 自己的 MyBatis 配置类
... ...
src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java
... ... @@ -5,6 +5,7 @@ import cn.iocoder.dashboard.framework.mybatis.config.MybatisConfiguration;
5 5 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
6 6 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
7 7 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  8 +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
8 9 import org.springframework.boot.test.context.SpringBootTest;
9 10 import org.springframework.context.annotation.Import;
10 11 import org.springframework.test.context.ActiveProfiles;
... ... @@ -26,6 +27,7 @@ public class BaseDbUnitTest {
26 27 // DB 配置类
27 28 DataSourceConfiguration.class, // 自己的 DB 配置类
28 29 DataSourceAutoConfiguration.class, // Spring DB 自动配置类
  30 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
29 31 DruidDataSourceAutoConfigure.class, // Druid 自动配置类
30 32 // MyBatis 配置类
31 33 MybatisConfiguration.class, // 自己的 MyBatis 配置类
... ...
src/test/java/cn/iocoder/dashboard/config/RedisTestConfiguration.java
... ... @@ -17,7 +17,7 @@ public class RedisTestConfiguration {
17 17 /**
18 18 * 创建模拟的 Redis Server 服务器
19 19 */
20   - @Bean(destroyMethod = "stop")
  20 + @Bean
21 21 public RedisServer redisServer(RedisProperties properties) throws IOException {
22 22 RedisServer redisServer = new RedisServer(properties.getPort());
23 23 // TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。
... ...
src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobLogServiceTest.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.infra.service.job;
  2 +
  3 +import static cn.hutool.core.util.RandomUtil.randomEle;
  4 +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  5 +import static cn.iocoder.dashboard.util.RandomUtils.randomLongId;
  6 +import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
  7 +import static cn.iocoder.dashboard.util.RandomUtils.randomString;
  8 +import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
  9 +import static org.junit.jupiter.api.Assertions.assertEquals;
  10 +import static org.junit.jupiter.api.Assertions.assertNotNull;
  11 +
  12 +import java.util.ArrayList;
  13 +import java.util.List;
  14 +
  15 +import javax.annotation.Resource;
  16 +
  17 +import org.junit.jupiter.api.Test;
  18 +import org.springframework.context.annotation.Import;
  19 +
  20 +import cn.iocoder.dashboard.BaseDbUnitTest;
  21 +import cn.iocoder.dashboard.common.pojo.PageResult;
  22 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.log.InfJobLogExportReqVO;
  23 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.log.InfJobLogPageReqVO;
  24 +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobLogDO;
  25 +import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobLogMapper;
  26 +import cn.iocoder.dashboard.modules.infra.enums.job.InfJobLogStatusEnum;
  27 +import cn.iocoder.dashboard.modules.infra.service.job.impl.InfJobLogServiceImpl;
  28 +import cn.iocoder.dashboard.util.object.ObjectUtils;
  29 +
  30 +/**
  31 + * {@link InfJobLogServiceImpl} 的单元测试
  32 + *
  33 + * @author neilz
  34 + */
  35 +@Import(InfJobLogServiceImpl.class)
  36 +public class InfJobLogServiceTest extends BaseDbUnitTest {
  37 +
  38 + @Resource
  39 + private InfJobLogServiceImpl jobLogService;
  40 + @Resource
  41 + private InfJobLogMapper jobLogMapper;
  42 +
  43 + @Test
  44 + public void testCreateJobLog_success() {
  45 + // 准备参数
  46 + InfJobLogDO reqVO = randomPojo(InfJobLogDO.class, o -> {
  47 + o.setExecuteIndex(1);
  48 + });
  49 + // 调用
  50 + Long jobLogId = jobLogService.createJobLog(reqVO.getJobId(), reqVO.getBeginTime(), reqVO.getHandlerName(), reqVO.getHandlerParam(), reqVO.getExecuteIndex());
  51 + // 断言
  52 + assertNotNull(jobLogId);
  53 + // 校验记录的属性是否正确
  54 + InfJobLogDO job = jobLogMapper.selectById(jobLogId);
  55 + assertEquals(InfJobLogStatusEnum.RUNNING.getStatus(), job.getStatus());
  56 + }
  57 +
  58 + @Test
  59 + public void testUpdateJobLogResultAsync_success() {
  60 + // 准备参数
  61 + InfJobLogDO reqVO = randomPojo(InfJobLogDO.class, o -> {
  62 + o.setExecuteIndex(1);
  63 + });
  64 + InfJobLogDO log = InfJobLogDO.builder().jobId(reqVO.getJobId()).handlerName(reqVO.getHandlerName()).handlerParam(reqVO.getHandlerParam()).executeIndex(reqVO.getExecuteIndex())
  65 + .beginTime(reqVO.getBeginTime()).status(InfJobLogStatusEnum.RUNNING.getStatus()).build();
  66 + jobLogMapper.insert(log);
  67 + // 调用
  68 + jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), true,reqVO.getResult());
  69 + // 校验记录的属性是否正确
  70 + InfJobLogDO job = jobLogMapper.selectById(log.getId());
  71 + assertEquals(InfJobLogStatusEnum.SUCCESS.getStatus(), job.getStatus());
  72 +
  73 + // 调用
  74 + jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), false,reqVO.getResult());
  75 + // 校验记录的属性是否正确
  76 + InfJobLogDO job2 = jobLogMapper.selectById(log.getId());
  77 + assertEquals(InfJobLogStatusEnum.FAILURE.getStatus(), job2.getStatus());
  78 + }
  79 +
  80 + @Test
  81 + public void testGetJobLogListByIds_success() {
  82 + // mock 数据
  83 + InfJobLogDO dbJobLog = randomPojo(InfJobLogDO.class, o -> {
  84 + o.setExecuteIndex(1);
  85 + o.setStatus(randomEle(InfJobLogStatusEnum.values()).getStatus()); // 保证 status 的范围
  86 + });
  87 + InfJobLogDO cloneJobLog = ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString()));
  88 + jobLogMapper.insert(dbJobLog);
  89 + // 测试 handlerName 不匹配
  90 + jobLogMapper.insert(cloneJobLog);
  91 + // 准备参数
  92 + ArrayList ids = new ArrayList<>();
  93 + ids.add(dbJobLog.getId());
  94 + ids.add(cloneJobLog.getId());
  95 + // 调用
  96 + List<InfJobLogDO> list = jobLogService.getJobLogList(ids);
  97 + // 断言
  98 + assertEquals(2, list.size());
  99 + assertPojoEquals(dbJobLog, list.get(0));
  100 + }
  101 +
  102 + @Test
  103 + public void testGetJobPage_success() {
  104 + // mock 数据
  105 + InfJobLogDO dbJobLog = randomPojo(InfJobLogDO.class, o -> {
  106 + o.setExecuteIndex(1);
  107 + o.setHandlerName("handlerName 单元测试");
  108 + o.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus());
  109 + o.setBeginTime(buildTime(2021, 1, 8));
  110 + o.setEndTime(buildTime(2021, 1, 8));
  111 + });
  112 + jobLogMapper.insert(dbJobLog);
  113 + // 测试 jobId 不匹配
  114 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setJobId(randomLongId())));
  115 + // 测试 handlerName 不匹配
  116 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString())));
  117 + // 测试 beginTime 不匹配
  118 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
  119 + // 测试 endTime 不匹配
  120 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
  121 + // 测试 status 不匹配
  122 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus())));
  123 + // 准备参数
  124 + InfJobLogPageReqVO reqVo = new InfJobLogPageReqVO();
  125 + reqVo.setJobId(dbJobLog.getJobId());
  126 + reqVo.setHandlerName("单元");
  127 + reqVo.setBeginTime(dbJobLog.getBeginTime());
  128 + reqVo.setEndTime(dbJobLog.getEndTime());
  129 + reqVo.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus());
  130 + // 调用
  131 + PageResult<InfJobLogDO> pageResult = jobLogService.getJobLogPage(reqVo);
  132 + // 断言
  133 + assertEquals(1, pageResult.getTotal());
  134 + assertEquals(1, pageResult.getList().size());
  135 + assertPojoEquals(dbJobLog, pageResult.getList().get(0));
  136 + }
  137 +
  138 + @Test
  139 + public void testGetJobListForExport_success() {
  140 + // mock 数据
  141 + InfJobLogDO dbJobLog = randomPojo(InfJobLogDO.class, o -> {
  142 + o.setExecuteIndex(1);
  143 + o.setHandlerName("handlerName 单元测试");
  144 + o.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus());
  145 + o.setBeginTime(buildTime(2021, 1, 8));
  146 + o.setEndTime(buildTime(2021, 1, 8));
  147 + });
  148 + jobLogMapper.insert(dbJobLog);
  149 + // 测试 jobId 不匹配
  150 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setJobId(randomLongId())));
  151 + // 测试 handlerName 不匹配
  152 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString())));
  153 + // 测试 beginTime 不匹配
  154 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
  155 + // 测试 endTime 不匹配
  156 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
  157 + // 测试 status 不匹配
  158 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus())));
  159 + // 准备参数
  160 + InfJobLogExportReqVO reqVo = new InfJobLogExportReqVO();
  161 + reqVo.setJobId(dbJobLog.getJobId());
  162 + reqVo.setHandlerName("单元");
  163 + reqVo.setBeginTime(dbJobLog.getBeginTime());
  164 + reqVo.setEndTime(dbJobLog.getEndTime());
  165 + reqVo.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus());
  166 + // 调用
  167 + List<InfJobLogDO> list = jobLogService.getJobLogList(reqVo);
  168 + // 断言
  169 + assertEquals(1, list.size());
  170 + assertPojoEquals(dbJobLog, list.get(0));
  171 + }
  172 +
  173 +}
... ...
src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.infra.service.job;
  2 +
  3 +import static cn.hutool.core.util.RandomUtil.randomEle;
  4 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_CHANGE_STATUS_EQUALS;
  5 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_CHANGE_STATUS_INVALID;
  6 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_CRON_EXPRESSION_VALID;
  7 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_HANDLER_EXISTS;
  8 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_NOT_EXISTS;
  9 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_UPDATE_ONLY_NORMAL_STATUS;
  10 +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  11 +import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
  12 +import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
  13 +import static cn.iocoder.dashboard.util.RandomUtils.randomString;
  14 +import static org.junit.jupiter.api.Assertions.assertEquals;
  15 +import static org.junit.jupiter.api.Assertions.assertNotNull;
  16 +import static org.junit.jupiter.api.Assertions.assertNull;
  17 +import static org.mockito.ArgumentMatchers.eq;
  18 +import static org.mockito.Mockito.times;
  19 +import static org.mockito.Mockito.verify;
  20 +
  21 +import java.util.ArrayList;
  22 +import java.util.List;
  23 +
  24 +import javax.annotation.Resource;
  25 +
  26 +import org.junit.jupiter.api.Test;
  27 +import org.quartz.SchedulerException;
  28 +import org.springframework.boot.test.mock.mockito.MockBean;
  29 +import org.springframework.context.annotation.Import;
  30 +
  31 +import cn.iocoder.dashboard.BaseDbUnitTest;
  32 +import cn.iocoder.dashboard.common.pojo.PageResult;
  33 +import cn.iocoder.dashboard.framework.quartz.core.scheduler.SchedulerManager;
  34 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobCreateReqVO;
  35 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobExportReqVO;
  36 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobPageReqVO;
  37 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobUpdateReqVO;
  38 +import cn.iocoder.dashboard.modules.infra.convert.job.InfJobConvert;
  39 +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO;
  40 +import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobMapper;
  41 +import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum;
  42 +import cn.iocoder.dashboard.modules.infra.service.job.impl.InfJobServiceImpl;
  43 +import cn.iocoder.dashboard.util.object.ObjectUtils;
  44 +
  45 +/**
  46 + * {@link InfJobServiceImpl} 的单元测试
  47 + *
  48 + * @author neilz
  49 + */
  50 +@Import(InfJobServiceImpl.class)
  51 +public class InfJobServiceTest extends BaseDbUnitTest {
  52 +
  53 + @Resource
  54 + private InfJobServiceImpl jobService;
  55 + @Resource
  56 + private InfJobMapper jobMapper;
  57 + @MockBean
  58 + private SchedulerManager schedulerManager;
  59 +
  60 + @Test
  61 + public void testCreateJob_cronExpressionValid() {
  62 + // 准备参数。Cron 表达式为 String 类型,默认随机字符串。
  63 + InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class);
  64 + // 调用,并断言异常
  65 + assertServiceException(() -> jobService.createJob(reqVO), JOB_CRON_EXPRESSION_VALID);
  66 + }
  67 +
  68 + @Test
  69 + public void testCreateJob_jobHandlerExists() throws SchedulerException {
  70 + // 准备参数 指定 Cron 表达式
  71 + InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  72 + // 调用
  73 + jobService.createJob(reqVO);
  74 + // 调用,并断言异常
  75 + assertServiceException(() -> jobService.createJob(reqVO), JOB_HANDLER_EXISTS);
  76 + }
  77 +
  78 + @Test
  79 + public void testCreateJob_success() throws SchedulerException {
  80 + // 准备参数 指定 Cron 表达式
  81 + InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  82 + // 调用
  83 + Long jobId = jobService.createJob(reqVO);
  84 + // 断言
  85 + assertNotNull(jobId);
  86 + // 校验记录的属性是否正确
  87 + InfJobDO job = jobMapper.selectById(jobId);
  88 + assertPojoEquals(reqVO, job);
  89 + assertEquals(InfJobStatusEnum.NORMAL.getStatus(), job.getStatus());
  90 + // 校验调用
  91 + verify(schedulerManager, times(1)).addJob(eq(job.getId()), eq(job.getHandlerName()), eq(job.getHandlerParam()), eq(job.getCronExpression()),
  92 + eq(reqVO.getRetryCount()), eq(reqVO.getRetryInterval()));
  93 + }
  94 +
  95 + @Test
  96 + public void testUpdateJob_jobNotExists(){
  97 + // 准备参数
  98 + InfJobUpdateReqVO reqVO = randomPojo(InfJobUpdateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  99 + // 调用,并断言异常
  100 + assertServiceException(() -> jobService.updateJob(reqVO), JOB_NOT_EXISTS);
  101 + }
  102 +
  103 + @Test
  104 + public void testUpdateJob_onlyNormalStatus(){
  105 + // mock 数据
  106 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  107 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  108 + job.setStatus(InfJobStatusEnum.INIT.getStatus());
  109 + fillJobMonitorTimeoutEmpty(job);
  110 + jobMapper.insert(job);
  111 + // 准备参数
  112 + InfJobUpdateReqVO updateReqVO = randomPojo(InfJobUpdateReqVO.class, o -> {
  113 + o.setId(job.getId());
  114 + o.setName(createReqVO.getName());
  115 + o.setCronExpression(createReqVO.getCronExpression());
  116 + });
  117 + // 调用,并断言异常
  118 + assertServiceException(() -> jobService.updateJob(updateReqVO), JOB_UPDATE_ONLY_NORMAL_STATUS);
  119 + }
  120 +
  121 + @Test
  122 + public void testUpdateJob_success() throws SchedulerException {
  123 + // mock 数据
  124 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  125 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  126 + job.setStatus(InfJobStatusEnum.NORMAL.getStatus());
  127 + fillJobMonitorTimeoutEmpty(job);
  128 + jobMapper.insert(job);
  129 + // 准备参数
  130 + InfJobUpdateReqVO updateReqVO = randomPojo(InfJobUpdateReqVO.class, o -> {
  131 + o.setId(job.getId());
  132 + o.setName(createReqVO.getName());
  133 + o.setCronExpression(createReqVO.getCronExpression());
  134 + });
  135 + // 调用
  136 + jobService.updateJob(updateReqVO);
  137 + // 校验记录的属性是否正确
  138 + InfJobDO updateJob = jobMapper.selectById(updateReqVO.getId());
  139 + assertPojoEquals(updateReqVO, updateJob);
  140 + // 校验调用
  141 + verify(schedulerManager, times(1)).updateJob(eq(job.getHandlerName()), eq(updateReqVO.getHandlerParam()), eq(updateReqVO.getCronExpression()),
  142 + eq(updateReqVO.getRetryCount()), eq(updateReqVO.getRetryInterval()));
  143 + }
  144 +
  145 + @Test
  146 + public void testUpdateJobStatus_changeStatusInvalid() {
  147 + // 调用,并断言异常
  148 + assertServiceException(() -> jobService.updateJobStatus(1l, InfJobStatusEnum.INIT.getStatus()), JOB_CHANGE_STATUS_INVALID);
  149 + }
  150 +
  151 + @Test
  152 + public void testUpdateJobStatus_changeStatusEquals() {
  153 + // mock 数据
  154 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  155 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  156 + job.setStatus(InfJobStatusEnum.NORMAL.getStatus());
  157 + fillJobMonitorTimeoutEmpty(job);
  158 + jobMapper.insert(job);
  159 + // 调用,并断言异常
  160 + assertServiceException(() -> jobService.updateJobStatus(job.getId(), job.getStatus()), JOB_CHANGE_STATUS_EQUALS);
  161 + }
  162 +
  163 + @Test
  164 + public void testUpdateJobStatus_NormalToStop_success() throws SchedulerException {
  165 + // mock 数据
  166 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  167 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  168 + job.setStatus(InfJobStatusEnum.NORMAL.getStatus());
  169 + fillJobMonitorTimeoutEmpty(job);
  170 + jobMapper.insert(job);
  171 + // 调用
  172 + jobService.updateJobStatus(job.getId(), InfJobStatusEnum.STOP.getStatus());
  173 + // 校验记录的属性是否正确
  174 + InfJobDO updateJob = jobMapper.selectById(job.getId());
  175 + assertEquals(InfJobStatusEnum.STOP.getStatus(), updateJob.getStatus());
  176 + // 校验调用
  177 + verify(schedulerManager, times(1)).pauseJob(eq(job.getHandlerName()));
  178 + }
  179 +
  180 + @Test
  181 + public void testUpdateJobStatus_StopToNormal_success() throws SchedulerException {
  182 + // mock 数据
  183 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  184 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  185 + job.setStatus(InfJobStatusEnum.STOP.getStatus());
  186 + fillJobMonitorTimeoutEmpty(job);
  187 + jobMapper.insert(job);
  188 + // 调用
  189 + jobService.updateJobStatus(job.getId(), InfJobStatusEnum.NORMAL.getStatus());
  190 + // 校验记录的属性是否正确
  191 + InfJobDO updateJob = jobMapper.selectById(job.getId());
  192 + assertEquals(InfJobStatusEnum.NORMAL.getStatus(), updateJob.getStatus());
  193 + // 校验调用
  194 + verify(schedulerManager, times(1)).resumeJob(eq(job.getHandlerName()));
  195 + }
  196 +
  197 + @Test
  198 + public void testTriggerJob_success() throws SchedulerException {
  199 + // mock 数据
  200 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  201 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  202 + job.setStatus(InfJobStatusEnum.NORMAL.getStatus());
  203 + fillJobMonitorTimeoutEmpty(job);
  204 + jobMapper.insert(job);
  205 + // 调用
  206 + jobService.triggerJob(job.getId());
  207 + // 校验调用
  208 + verify(schedulerManager, times(1)).triggerJob(eq(job.getId()), eq(job.getHandlerName()), eq(job.getHandlerParam()));
  209 + }
  210 +
  211 + @Test
  212 + public void testDeleteJob_success() throws SchedulerException {
  213 + // mock 数据
  214 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  215 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  216 + job.setStatus(InfJobStatusEnum.NORMAL.getStatus());
  217 + fillJobMonitorTimeoutEmpty(job);
  218 + jobMapper.insert(job);
  219 + // 调用 UPDATE inf_job SET deleted=1 WHERE id=? AND deleted=0
  220 + jobService.deleteJob(job.getId());
  221 + // 校验数据不存在了 WHERE id=? AND deleted=0 查询为空正常
  222 + assertNull(jobMapper.selectById(job.getId()));
  223 + // 校验调用
  224 + verify(schedulerManager, times(1)).deleteJob(eq(job.getHandlerName()));
  225 + }
  226 +
  227 + @Test
  228 + public void testGetJobListByIds_success() {
  229 + // mock 数据
  230 + InfJobDO dbJob = randomPojo(InfJobDO.class, o -> {
  231 + o.setStatus(randomEle(InfJobStatusEnum.values()).getStatus()); // 保证 status 的范围
  232 + });
  233 + InfJobDO cloneJob = ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString()));
  234 + jobMapper.insert(dbJob);
  235 + // 测试 handlerName 不匹配
  236 + jobMapper.insert(cloneJob);
  237 + // 准备参数
  238 + ArrayList ids = new ArrayList<>();
  239 + ids.add(dbJob.getId());
  240 + ids.add(cloneJob.getId());
  241 + // 调用
  242 + List<InfJobDO> list = jobService.getJobList(ids);
  243 + // 断言
  244 + assertEquals(2, list.size());
  245 + assertPojoEquals(dbJob, list.get(0));
  246 + }
  247 +
  248 + @Test
  249 + public void testGetJobPage_success() {
  250 + // mock 数据
  251 + InfJobDO dbJob = randomPojo(InfJobDO.class, o -> {
  252 + o.setName("定时任务测试");
  253 + o.setHandlerName("handlerName 单元测试");
  254 + o.setStatus(InfJobStatusEnum.INIT.getStatus());
  255 + });
  256 + jobMapper.insert(dbJob);
  257 + // 测试 name 不匹配
  258 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setName("土豆")));
  259 + // 测试 status 不匹配
  260 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus())));
  261 + // 测试 handlerName 不匹配
  262 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString())));
  263 + // 准备参数
  264 + InfJobPageReqVO reqVo = new InfJobPageReqVO();
  265 + reqVo.setName("定时");
  266 + reqVo.setStatus(InfJobStatusEnum.INIT.getStatus());
  267 + reqVo.setHandlerName("单元");
  268 + // 调用
  269 + PageResult<InfJobDO> pageResult = jobService.getJobPage(reqVo);
  270 + // 断言
  271 + assertEquals(1, pageResult.getTotal());
  272 + assertEquals(1, pageResult.getList().size());
  273 + assertPojoEquals(dbJob, pageResult.getList().get(0));
  274 + }
  275 +
  276 + @Test
  277 + public void testGetJobListForExport_success() {
  278 + // mock 数据
  279 + InfJobDO dbJob = randomPojo(InfJobDO.class, o -> {
  280 + o.setName("定时任务测试");
  281 + o.setHandlerName("handlerName 单元测试");
  282 + o.setStatus(InfJobStatusEnum.INIT.getStatus());
  283 + });
  284 + jobMapper.insert(dbJob);
  285 + // 测试 name 不匹配
  286 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setName("土豆")));
  287 + // 测试 status 不匹配
  288 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus())));
  289 + // 测试 handlerName 不匹配
  290 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString())));
  291 + // 准备参数
  292 + InfJobExportReqVO reqVo = new InfJobExportReqVO();
  293 + reqVo.setName("定时");
  294 + reqVo.setStatus(InfJobStatusEnum.INIT.getStatus());
  295 + reqVo.setHandlerName("单元");
  296 + // 调用
  297 + List<InfJobDO> list = jobService.getJobList(reqVo);
  298 + // 断言
  299 + assertEquals(1, list.size());
  300 + assertPojoEquals(dbJob, list.get(0));
  301 + }
  302 +
  303 + private static void fillJobMonitorTimeoutEmpty(InfJobDO job) {
  304 + if (job.getMonitorTimeout() == null) {
  305 + job.setMonitorTimeout(0);
  306 + }
  307 + }
  308 +
  309 +}
... ...
src/test/java/cn/iocoder/dashboard/modules/infra/service/logger/InfApiAccessLogServiceImplTest.java
... ... @@ -38,7 +38,6 @@ public class InfApiAccessLogServiceImplTest extends BaseDbUnitTest {
38 38 @Resource
39 39 private InfApiAccessLogMapper infApiAccessLogMapper;
40 40  
41   -
42 41 @Test
43 42 public void testCreateApiAccessLogAsync() throws Exception {
44 43 ApiAccessLogCreateDTO createDTO = RandomUtils.randomPojo(
... ... @@ -59,13 +58,12 @@ public class InfApiAccessLogServiceImplTest extends BaseDbUnitTest {
59 58 assertPojoEquals(createDTO, infApiAccessLogDO);
60 59 }
61 60  
62   -
63 61 @Test
64 62 public void testGetApiAccessLogPage() {
65 63 // 构造测试数据
66 64 long userId = 2233L;
67 65 int userType = UserTypeEnum.ADMIN.getValue();
68   - String applicationName = "ruoyi-test";
  66 + String applicationName = "yudao-test";
69 67 String requestUrl = "foo";
70 68 Date beginTime = buildTime(2021, 3, 13);
71 69 int duration = 1000;
... ... @@ -123,7 +121,7 @@ public class InfApiAccessLogServiceImplTest extends BaseDbUnitTest {
123 121 // 构造测试数据
124 122 long userId = 2233L;
125 123 int userType = UserTypeEnum.ADMIN.getValue();
126   - String applicationName = "ruoyi-test";
  124 + String applicationName = "yudao-test";
127 125 String requestUrl = "foo";
128 126 Date beginTime = buildTime(2021, 3, 13);
129 127 int duration = 1000;
... ... @@ -174,4 +172,5 @@ public class InfApiAccessLogServiceImplTest extends BaseDbUnitTest {
174 172 assertEquals(1, list.size());
175 173 assertPojoEquals(infApiAccessLogDO, list.get(0));
176 174 }
  175 +
177 176 }
... ...
src/test/java/cn/iocoder/dashboard/modules/infra/service/logger/InfApiErrorLogServiceImplTest.java
... ... @@ -68,7 +68,7 @@ public class InfApiErrorLogServiceImplTest extends BaseDbUnitTest {
68 68 // 构造测试数据
69 69 long userId = 2233L;
70 70 int userType = UserTypeEnum.ADMIN.getValue();
71   - String applicationName = "ruoyi-test";
  71 + String applicationName = "yudao-test";
72 72 String requestUrl = "foo";
73 73 Date beginTime = buildTime(2021, 3, 13);
74 74 int progressStatus = InfApiErrorLogProcessStatusEnum.INIT.getStatus();
... ... @@ -121,7 +121,7 @@ public class InfApiErrorLogServiceImplTest extends BaseDbUnitTest {
121 121 // 构造测试数据
122 122 long userId = 2233L;
123 123 int userType = UserTypeEnum.ADMIN.getValue();
124   - String applicationName = "ruoyi-test";
  124 + String applicationName = "yudao-test";
125 125 String requestUrl = "foo";
126 126 Date beginTime = buildTime(2021, 3, 13);
127 127 int progressStatus = InfApiErrorLogProcessStatusEnum.INIT.getStatus();
... ...
src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java
1   -package cn.iocoder.dashboard.modules.system.service.auth;
2   -
3   -import cn.iocoder.dashboard.BaseDbUnitTest;
4   -import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
5   -import cn.iocoder.dashboard.framework.security.core.LoginUser;
6   -import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
7   -import cn.iocoder.dashboard.modules.system.service.auth.impl.SysAuthServiceImpl;
8   -import cn.iocoder.dashboard.modules.system.service.common.SysCaptchaService;
9   -import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService;
10   -import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
11   -import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
12   -import cn.iocoder.dashboard.util.AssertUtils;
13   -import org.junit.jupiter.api.Test;
14   -import org.springframework.boot.test.mock.mockito.MockBean;
15   -import org.springframework.context.annotation.Import;
16   -import org.springframework.security.authentication.AuthenticationManager;
17   -import org.springframework.security.core.userdetails.UsernameNotFoundException;
18   -
19   -import javax.annotation.Resource;
20   -import java.util.Set;
21   -
22   -import static cn.iocoder.dashboard.util.RandomUtils.*;
23   -import static java.util.Collections.singleton;
24   -import static org.junit.jupiter.api.Assertions.*;
25   -import static org.mockito.ArgumentMatchers.eq;
26   -import static org.mockito.Mockito.when;
27   -
28   -/**
29   - * {@link SysAuthServiceImpl} 的单元测试
30   - *
31   - * @author 芋道源码
32   - */
33   -@Import(SysAuthServiceImpl.class)
34   -public class SysAuthServiceImplTest extends BaseDbUnitTest {
35   -
36   - @Resource
37   - private SysAuthServiceImpl authService;
38   -
39   - @MockBean
40   - private SysUserService userService;
41   - @MockBean
42   - private SysPermissionService permissionService;
43   - @MockBean
44   - private AuthenticationManager authenticationManager;
45   - @MockBean
46   - private SysCaptchaService captchaService;
47   - @MockBean
48   - private SysLoginLogService loginLogService;
49   - @MockBean
50   - private SysUserSessionService userSessionService;
51   -
52   - @Test
53   - public void testLoadUserByUsername_success() {
54   - // 准备参数
55   - String username = randomString();
56   - // mock 方法
57   - SysUserDO user = randomUserDO(o -> o.setUsername(username));
58   - when(userService.getUserByUserName(eq(username))).thenReturn(user);
59   -
60   - // 调用
61   - LoginUser loginUser = (LoginUser) authService.loadUserByUsername(username);
62   - // 校验
63   - AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
64   - assertNull(loginUser.getRoleIds()); // 此时不会加载角色,所以是空的
65   - }
66   -
67   - @Test
68   - public void testLoadUserByUsername_userNotFound() {
69   - // 准备参数
70   - String username = randomString();
71   - // mock 方法
72   -
73   - // 调用, 并断言异常
74   - assertThrows(UsernameNotFoundException.class, // 抛出 UsernameNotFoundException 异常
75   - () -> authService.loadUserByUsername(username),
76   - username); // 异常提示为 username
77   - }
78   -
79   - @Test
80   - public void testMockLogin_success() {
81   - // 准备参数
82   - Long userId = randomLongId();
83   - // mock 方法 01
84   - SysUserDO user = randomUserDO(o -> o.setId(userId));
85   - when(userService.getUser(eq(userId))).thenReturn(user);
86   - // mock 方法 02
87   - Set<Long> roleIds = randomSet(Long.class);
88   - when(permissionService.getUserRoleIds(eq(userId), eq(singleton(CommonStatusEnum.ENABLE.getStatus()))))
89   - .thenReturn(roleIds);
90   -
91   - // 调用
92   - LoginUser loginUser = authService.mockLogin(userId);
93   - // 断言
94   - AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
95   - assertEquals(roleIds, loginUser.getRoleIds());
96   - }
97   -
98   - @Test
99   - public void testMockLogin_userNotFound() {
100   - // 准备参数
101   - Long userId = randomLongId();
102   - // mock 方法
103   -
104   - // 调用, 并断言异常
105   - assertThrows(UsernameNotFoundException.class, // 抛出 UsernameNotFoundException 异常
106   - () -> authService.mockLogin(userId),
107   - String.valueOf(userId)); // 异常提示为 userId
108   - }
109   -
110   -}
  1 +package cn.iocoder.dashboard.modules.system.service.auth;
  2 +
  3 +import cn.iocoder.dashboard.BaseDbUnitTest;
  4 +import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.dashboard.framework.security.core.LoginUser;
  6 +import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO;
  7 +import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
  8 +import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginLogTypeEnum;
  9 +import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginResultEnum;
  10 +import cn.iocoder.dashboard.modules.system.service.auth.impl.SysAuthServiceImpl;
  11 +import cn.iocoder.dashboard.modules.system.service.common.SysCaptchaService;
  12 +import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService;
  13 +import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
  14 +import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
  15 +import cn.iocoder.dashboard.util.AssertUtils;
  16 +import org.junit.jupiter.api.Test;
  17 +import org.springframework.boot.test.mock.mockito.MockBean;
  18 +import org.springframework.context.annotation.Import;
  19 +import org.springframework.security.authentication.AuthenticationManager;
  20 +import org.springframework.security.authentication.BadCredentialsException;
  21 +import org.springframework.security.authentication.DisabledException;
  22 +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  23 +import org.springframework.security.core.Authentication;
  24 +import org.springframework.security.core.AuthenticationException;
  25 +import org.springframework.security.core.userdetails.UsernameNotFoundException;
  26 +
  27 +import javax.annotation.Resource;
  28 +import java.util.Set;
  29 +
  30 +import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
  31 +import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
  32 +import static cn.iocoder.dashboard.util.RandomUtils.*;
  33 +import static java.util.Collections.singleton;
  34 +import static org.junit.jupiter.api.Assertions.*;
  35 +import static org.mockito.ArgumentMatchers.eq;
  36 +import static org.mockito.Mockito.*;
  37 +
  38 +/**
  39 + * {@link SysAuthServiceImpl} 的单元测试
  40 + *
  41 + * @author 芋道源码
  42 + */
  43 +@Import(SysAuthServiceImpl.class)
  44 +public class SysAuthServiceImplTest extends BaseDbUnitTest {
  45 +
  46 + @Resource
  47 + private SysAuthServiceImpl authService;
  48 +
  49 + @MockBean
  50 + private SysUserService userService;
  51 + @MockBean
  52 + private SysPermissionService permissionService;
  53 + @MockBean
  54 + private AuthenticationManager authenticationManager;
  55 + @MockBean
  56 + private Authentication authentication;
  57 + @MockBean
  58 + private SysCaptchaService captchaService;
  59 + @MockBean
  60 + private SysLoginLogService loginLogService;
  61 + @MockBean
  62 + private SysUserSessionService userSessionService;
  63 +
  64 + @Test
  65 + public void testLoadUserByUsername_success() {
  66 + // 准备参数
  67 + String username = randomString();
  68 + // mock 方法
  69 + SysUserDO user = randomUserDO(o -> o.setUsername(username));
  70 + when(userService.getUserByUsername(eq(username))).thenReturn(user);
  71 +
  72 + // 调用
  73 + LoginUser loginUser = (LoginUser) authService.loadUserByUsername(username);
  74 + // 校验
  75 + AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
  76 + assertNull(loginUser.getRoleIds()); // 此时不会加载角色,所以是空的
  77 + }
  78 +
  79 + @Test
  80 + public void testLoadUserByUsername_userNotFound() {
  81 + // 准备参数
  82 + String username = randomString();
  83 + // mock 方法
  84 +
  85 + // 调用, 并断言异常
  86 + assertThrows(UsernameNotFoundException.class, // 抛出 UsernameNotFoundException 异常
  87 + () -> authService.loadUserByUsername(username),
  88 + username); // 异常提示为 username
  89 + }
  90 +
  91 + @Test
  92 + public void testMockLogin_success() {
  93 + // 准备参数
  94 + Long userId = randomLongId();
  95 + // mock 方法 01
  96 + SysUserDO user = randomUserDO(o -> o.setId(userId));
  97 + when(userService.getUser(eq(userId))).thenReturn(user);
  98 + // mock 方法 02
  99 + Set<Long> roleIds = randomSet(Long.class);
  100 + when(permissionService.getUserRoleIds(eq(userId), eq(singleton(CommonStatusEnum.ENABLE.getStatus()))))
  101 + .thenReturn(roleIds);
  102 +
  103 + // 调用
  104 + LoginUser loginUser = authService.mockLogin(userId);
  105 + // 断言
  106 + AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
  107 + assertEquals(roleIds, loginUser.getRoleIds());
  108 + }
  109 +
  110 + @Test
  111 + public void testMockLogin_userNotFound() {
  112 + // 准备参数
  113 + Long userId = randomLongId();
  114 + // mock 方法
  115 +
  116 + // 调用, 并断言异常
  117 + assertThrows(UsernameNotFoundException.class, // 抛出 UsernameNotFoundException 异常
  118 + () -> authService.mockLogin(userId),
  119 + String.valueOf(userId)); // 异常提示为 userId
  120 + }
  121 +
  122 + @Test
  123 + public void testLogin_captchaNotFound() {
  124 + // 准备参数
  125 + SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
  126 + String userIp = randomString();
  127 + String userAgent = randomString();
  128 + // 调用, 并断言异常
  129 + assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_CAPTCHA_NOT_FOUND);
  130 + // 校验调用参数
  131 + verify(loginLogService, times(1)).createLoginLog(
  132 + argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
  133 + && o.getResult().equals(SysLoginResultEnum.CAPTCHA_NOT_FOUND.getResult()))
  134 + );
  135 + }
  136 +
  137 + @Test
  138 + public void testLogin_captchaCodeError() {
  139 + // 准备参数
  140 + String userIp = randomString();
  141 + String userAgent = randomString();
  142 + String code = randomString();
  143 + SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
  144 + // mock 验证码不正确
  145 + when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(code);
  146 + // 调用, 并断言异常
  147 + assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_CAPTCHA_CODE_ERROR);
  148 + // 校验调用参数
  149 + verify(loginLogService, times(1)).createLoginLog(
  150 + argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
  151 + && o.getResult().equals(SysLoginResultEnum.CAPTCHA_CODE_ERROR.getResult()))
  152 + );
  153 + }
  154 +
  155 + @Test
  156 + public void testLogin_badCredentials() {
  157 + // 准备参数
  158 + String userIp = randomString();
  159 + String userAgent = randomString();
  160 + SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
  161 + // mock 验证码正确
  162 + when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
  163 + // mock 抛出异常
  164 + when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
  165 + .thenThrow(new BadCredentialsException("测试账号或密码不正确"));
  166 + // 调用, 并断言异常
  167 + assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_BAD_CREDENTIALS);
  168 + // 校验调用参数
  169 + verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
  170 + verify(loginLogService, times(1)).createLoginLog(
  171 + argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
  172 + && o.getResult().equals(SysLoginResultEnum.BAD_CREDENTIALS.getResult()))
  173 + );
  174 + }
  175 +
  176 + @Test
  177 + public void testLogin_userDisabled() {
  178 + // 准备参数
  179 + String userIp = randomString();
  180 + String userAgent = randomString();
  181 + SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
  182 + // mock 验证码正确
  183 + when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
  184 + // mock 抛出异常
  185 + when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
  186 + .thenThrow(new DisabledException("测试用户被禁用"));
  187 + // 调用, 并断言异常
  188 + assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_USER_DISABLED);
  189 + // 校验调用参数
  190 + verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
  191 + verify(loginLogService, times(1)).createLoginLog(
  192 + argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
  193 + && o.getResult().equals(SysLoginResultEnum.USER_DISABLED.getResult()))
  194 + );
  195 + }
  196 +
  197 + @Test
  198 + public void testLogin_unknownError() {
  199 + // 准备参数
  200 + String userIp = randomString();
  201 + String userAgent = randomString();
  202 + SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
  203 + // mock 验证码正确
  204 + when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
  205 + // mock 抛出异常
  206 + when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
  207 + .thenThrow(new AuthenticationException("测试未知异常") {});
  208 + // 调用, 并断言异常
  209 + assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_FAIL_UNKNOWN);
  210 + // 校验调用参数
  211 + verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
  212 + verify(loginLogService, times(1)).createLoginLog(
  213 + argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
  214 + && o.getResult().equals(SysLoginResultEnum.UNKNOWN_ERROR.getResult()))
  215 + );
  216 + }
  217 +
  218 + @Test
  219 + public void testLogin_success() {
  220 + // 准备参数
  221 + String userIp = randomString();
  222 + String userAgent = randomString();
  223 + Long userId = randomLongId();
  224 + Set<Long> userRoleIds = randomSet(Long.class);
  225 + String sessionId = randomString();
  226 + SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
  227 + LoginUser loginUser = randomPojo(LoginUser.class, o -> {
  228 + o.setId(userId);
  229 + o.setRoleIds(userRoleIds);
  230 + });
  231 + // mock 验证码正确
  232 + when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
  233 + // mock authentication
  234 + when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
  235 + .thenReturn(authentication);
  236 + when(authentication.getPrincipal()).thenReturn(loginUser);
  237 + // mock 获得 User 拥有的角色编号数组
  238 + when(permissionService.getUserRoleIds(userId, singleton(CommonStatusEnum.ENABLE.getStatus()))).thenReturn(userRoleIds);
  239 + // mock 缓存登陆用户到 Redis
  240 + when(userSessionService.createUserSession(loginUser, userIp, userAgent)).thenReturn(sessionId);
  241 + // 调用, 并断言异常
  242 + String login = authService.login(reqVO, userIp, userAgent);
  243 + assertEquals(sessionId, login);
  244 + // 校验调用参数
  245 + verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
  246 + verify(loginLogService, times(1)).createLoginLog(
  247 + argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
  248 + && o.getResult().equals(SysLoginResultEnum.SUCCESS.getResult()))
  249 + );
  250 + }
  251 +
  252 + @Test
  253 + public void testLogout_success() {
  254 + // 准备参数
  255 + String token = randomString();
  256 + LoginUser loginUser = randomPojo(LoginUser.class);
  257 + // mock
  258 + when(userSessionService.getLoginUser(token)).thenReturn(loginUser);
  259 + // 调用
  260 + authService.logout(token);
  261 + // 校验调用参数
  262 + verify(userSessionService, times(1)).deleteUserSession(token);
  263 + verify(loginLogService, times(1)).createLoginLog(
  264 + argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGOUT_SELF.getType())
  265 + && o.getResult().equals(SysLoginResultEnum.SUCCESS.getResult()))
  266 + );
  267 + }
  268 +
  269 +}
... ...
src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysUserSessionServiceImplTest.java
1 1 package cn.iocoder.dashboard.modules.system.service.auth;
2 2  
  3 +import static cn.hutool.core.util.RandomUtil.randomEle;
  4 +import static cn.iocoder.dashboard.modules.system.dal.redis.SysRedisKeyConstants.LOGIN_USER;
  5 +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  6 +import static cn.iocoder.dashboard.util.RandomUtils.randomDate;
  7 +import static cn.iocoder.dashboard.util.RandomUtils.randomLongId;
  8 +import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
  9 +import static cn.iocoder.dashboard.util.RandomUtils.randomString;
  10 +import static cn.iocoder.dashboard.util.date.DateUtils.addTime;
  11 +import static org.junit.jupiter.api.Assertions.assertEquals;
  12 +import static org.junit.jupiter.api.Assertions.assertNotEquals;
  13 +import static org.junit.jupiter.api.Assertions.assertNotNull;
  14 +import static org.junit.jupiter.api.Assertions.assertNull;
  15 +import static org.mockito.Mockito.when;
  16 +
  17 +import java.time.Duration;
  18 +import java.util.Date;
  19 +import java.util.List;
  20 +import java.util.stream.Collectors;
  21 +import java.util.stream.Stream;
  22 +
  23 +import javax.annotation.Resource;
  24 +
  25 +import org.junit.jupiter.api.Test;
  26 +import org.springframework.boot.test.mock.mockito.MockBean;
  27 +import org.springframework.context.annotation.Import;
  28 +import org.springframework.data.redis.core.StringRedisTemplate;
  29 +
3 30 import cn.hutool.core.date.DateUtil;
4 31 import cn.iocoder.dashboard.BaseDbAndRedisUnitTest;
  32 +import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
  33 +import cn.iocoder.dashboard.common.pojo.PageResult;
5 34 import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
  35 +import cn.iocoder.dashboard.framework.security.core.LoginUser;
  36 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobPageReqVO;
  37 +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO;
  38 +import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;
  39 +import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum;
  40 +import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO;
6 41 import cn.iocoder.dashboard.modules.system.dal.dataobject.auth.SysUserSessionDO;
  42 +import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
7 43 import cn.iocoder.dashboard.modules.system.dal.mysql.auth.SysUserSessionMapper;
  44 +import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper;
8 45 import cn.iocoder.dashboard.modules.system.dal.redis.auth.SysLoginUserRedisDAO;
  46 +import cn.iocoder.dashboard.modules.system.enums.common.SysSexEnum;
9 47 import cn.iocoder.dashboard.modules.system.service.auth.impl.SysUserSessionServiceImpl;
10 48 import cn.iocoder.dashboard.modules.system.service.dept.impl.SysDeptServiceImpl;
11 49 import cn.iocoder.dashboard.modules.system.service.logger.impl.SysLoginLogServiceImpl;
12 50 import cn.iocoder.dashboard.modules.system.service.user.SysUserServiceImpl;
13 51 import cn.iocoder.dashboard.util.AssertUtils;
14 52 import cn.iocoder.dashboard.util.RandomUtils;
15   -import org.junit.jupiter.api.Test;
16   -import org.springframework.boot.test.mock.mockito.MockBean;
17   -import org.springframework.context.annotation.Import;
18   -
19   -import javax.annotation.Resource;
20   -import java.util.Date;
21   -import java.util.List;
22   -import java.util.stream.Collectors;
23   -import java.util.stream.Stream;
24   -
25   -import static org.junit.jupiter.api.Assertions.assertEquals;
  53 +import cn.iocoder.dashboard.util.json.JsonUtils;
  54 +import cn.iocoder.dashboard.util.object.ObjectUtils;
26 55  
27 56 /**
28 57 * SysUserSessionServiceImpl Tester.
... ... @@ -31,13 +60,17 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
31 60 * @version 1.0
32 61 * @since <pre>3月 8, 2021</pre>
33 62 */
34   -@Import(SysUserSessionServiceImpl.class)
  63 +@Import({SysUserSessionServiceImpl.class, SysLoginUserRedisDAO.class})
35 64 public class SysUserSessionServiceImplTest extends BaseDbAndRedisUnitTest {
36 65  
37 66 @Resource
38 67 private SysUserSessionServiceImpl sysUserSessionService;
39 68 @Resource
40 69 private SysUserSessionMapper sysUserSessionMapper;
  70 + @Resource
  71 + private SysLoginUserRedisDAO sysLoginUserRedisDAO;
  72 + @Resource
  73 + private SysUserMapper sysUserMapper;
41 74  
42 75 @MockBean
43 76 private SecurityProperties securityProperties;
... ... @@ -47,8 +80,132 @@ public class SysUserSessionServiceImplTest extends BaseDbAndRedisUnitTest {
47 80 private SysUserServiceImpl sysUserService;
48 81 @MockBean
49 82 private SysLoginLogServiceImpl sysLoginLogService;
50   - @MockBean
51   - private SysLoginUserRedisDAO sysLoginUserRedisDAO;
  83 +
  84 + @Test
  85 + public void testCreateUserSession_success() {
  86 + // 准备参数
  87 + String userIp = randomString();
  88 + String userAgent = randomString();
  89 + LoginUser loginUser = randomPojo(LoginUser.class);
  90 + // mock
  91 + when(securityProperties.getSessionTimeout()).thenReturn(Duration.ofDays(1));
  92 + // 调用
  93 + String sessionId = sysUserSessionService.createUserSession(loginUser, userIp, userAgent);
  94 + // 校验记录的属性是否正确
  95 + SysUserSessionDO sysUserSessionDO = sysUserSessionMapper.selectById(sessionId);
  96 + assertEquals(sysUserSessionDO.getId(), sessionId);
  97 + assertEquals(sysUserSessionDO.getUserId(), loginUser.getId());
  98 + assertEquals(sysUserSessionDO.getUserIp(), userIp);
  99 + assertEquals(sysUserSessionDO.getUserAgent(), userAgent);
  100 + assertEquals(sysUserSessionDO.getUsername(), loginUser.getUsername());
  101 + LoginUser redisLoginUser = sysLoginUserRedisDAO.get(sessionId);
  102 + AssertUtils.assertPojoEquals(redisLoginUser, loginUser, "username","password");
  103 + }
  104 +
  105 + @Test
  106 + public void testCreateRefreshUserSession_success() {
  107 + // 准备参数
  108 + String sessionId = randomString();
  109 + String userIp = randomString();
  110 + String userAgent = randomString();
  111 + Long timeLong = randomLongId();
  112 + String userName = randomString();
  113 + Date date = randomDate();
  114 + LoginUser loginUser = randomPojo(LoginUser.class);
  115 + // mock
  116 + when(securityProperties.getSessionTimeout()).thenReturn(Duration.ofDays(1));
  117 + loginUser.setUpdateTime(date);
  118 + sysLoginUserRedisDAO.set(sessionId, loginUser);
  119 + SysUserSessionDO userSession = SysUserSessionDO.builder().id(sessionId)
  120 + .userId(loginUser.getId()).userIp(userIp).userAgent(userAgent).username(userName)
  121 + .sessionTimeout(addTime(Duration.ofMillis(timeLong)))
  122 + .build();
  123 + sysUserSessionMapper.insert(userSession);
  124 + SysUserSessionDO insertDO = sysUserSessionMapper.selectById(sessionId);
  125 + // 调用
  126 + sysUserSessionService.refreshUserSession(sessionId, loginUser);
  127 + // 校验记录 redis
  128 + LoginUser redisLoginUser = sysLoginUserRedisDAO.get(sessionId);
  129 + assertNotEquals(redisLoginUser.getUpdateTime(), date);
  130 + // 校验记录 SysUserSessionDO
  131 + SysUserSessionDO updateDO = sysUserSessionMapper.selectById(sessionId);
  132 + assertEquals(updateDO.getUsername(), loginUser.getUsername());
  133 + assertNotEquals(updateDO.getUpdateTime(), insertDO.getUpdateTime());
  134 + assertNotEquals(updateDO.getSessionTimeout(), addTime(Duration.ofMillis(timeLong)));
  135 + }
  136 +
  137 + @Test
  138 + public void testDeleteUserSession_success() {
  139 + // 准备参数
  140 + String sessionId = randomString();
  141 + String userIp = randomString();
  142 + String userAgent = randomString();
  143 + Long timeLong = randomLongId();
  144 + LoginUser loginUser = randomPojo(LoginUser.class);
  145 + // mock 存入 Redis
  146 + when(securityProperties.getSessionTimeout()).thenReturn(Duration.ofDays(1));
  147 + sysLoginUserRedisDAO.set(sessionId, loginUser);
  148 + // mock 存入 db
  149 + SysUserSessionDO userSession = SysUserSessionDO.builder().id(sessionId)
  150 + .userId(loginUser.getId()).userIp(userIp).userAgent(userAgent).username(loginUser.getUsername())
  151 + .sessionTimeout(addTime(Duration.ofMillis(timeLong)))
  152 + .build();
  153 + sysUserSessionMapper.insert(userSession);
  154 + // 校验数据存在
  155 + assertNotNull(sysLoginUserRedisDAO.get(sessionId));
  156 + assertNotNull(sysUserSessionMapper.selectById(sessionId));
  157 + // 调用
  158 + sysUserSessionService.deleteUserSession(sessionId);
  159 + // 校验数据不存在了
  160 + assertNull(sysLoginUserRedisDAO.get(sessionId));
  161 + assertNull(sysUserSessionMapper.selectById(sessionId));
  162 + }
  163 +
  164 + @Test
  165 + public void testGetUserSessionPage_success() {
  166 + // mock 数据
  167 + String userIp = randomString();
  168 + SysUserDO dbUser1 = randomPojo(SysUserDO.class, o -> {
  169 + o.setUsername("testUsername1");
  170 + o.setSex(randomEle(SysSexEnum.values()).getSEX());
  171 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  172 + });
  173 + SysUserDO dbUser2 = randomPojo(SysUserDO.class, o -> {
  174 + o.setUsername("testUsername2");
  175 + o.setSex(randomEle(SysSexEnum.values()).getSEX());
  176 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  177 + });
  178 + SysUserSessionDO dbSession = randomPojo(SysUserSessionDO.class, o -> {
  179 + o.setUserId(dbUser1.getId());
  180 + o.setUserIp(userIp);
  181 + });
  182 + sysUserMapper.insert(dbUser1);
  183 + sysUserMapper.insert(dbUser2);
  184 + sysUserSessionMapper.insert(dbSession);
  185 + sysUserSessionMapper.insert(ObjectUtils.clone(dbSession, o -> {
  186 + o.setId(randomString());
  187 + o.setUserId(dbUser2.getId());
  188 + }));
  189 + // 测试 userId 不匹配
  190 + sysUserSessionMapper.insert(ObjectUtils.clone(dbSession, o -> {
  191 + o.setId(randomString());
  192 + o.setUserId(123456l);
  193 + }));
  194 + // 测试 userIp 不匹配
  195 + sysUserSessionMapper.insert(ObjectUtils.clone(dbSession, o -> {
  196 + o.setId(randomString());
  197 + o.setUserIp("testUserIp");
  198 + }));
  199 + // 准备参数
  200 + SysUserSessionPageReqVO reqVo = new SysUserSessionPageReqVO();
  201 + reqVo.setUserIp(userIp);
  202 + // 调用
  203 + PageResult<SysUserSessionDO> pageResult = sysUserSessionService.getUserSessionPage(reqVo);
  204 + // 断言
  205 + assertEquals(3, pageResult.getTotal());
  206 + assertEquals(3, pageResult.getList().size());
  207 + assertPojoEquals(dbSession, pageResult.getList().get(0));
  208 + }
52 209  
53 210 @Test
54 211 public void testClearSessionTimeout_success() throws Exception {
... ...
src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptServiceTest.java
... ... @@ -72,7 +72,6 @@ class SysDeptServiceTest extends BaseDbUnitTest {
72 72 // 断言 maxUpdateTime 缓存
73 73 Date maxUpdateTime = (Date) getFieldValue(deptService, "maxUpdateTime");
74 74 assertEquals(ObjectUtils.max(deptDO1.getUpdateTime(), deptDO2.getUpdateTime()), maxUpdateTime);
75   -
76 75 }
77 76  
78 77 @Test
... ... @@ -92,7 +91,7 @@ class SysDeptServiceTest extends BaseDbUnitTest {
92 91 reqVO.setName("开");
93 92 reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
94 93 // 调用
95   - List<SysDeptDO> sysDeptDOS = deptService.listDepts(reqVO);
  94 + List<SysDeptDO> sysDeptDOS = deptService.getSimpleDepts(reqVO);
96 95 // 断言
97 96 assertEquals(1, sysDeptDOS.size());
98 97 assertPojoEquals(dept, sysDeptDOS.get(0));
... ...
src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostServiceTest.java
... ... @@ -59,7 +59,7 @@ class SysPostServiceTest extends BaseDbUnitTest {
59 59 reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
60 60  
61 61 // 调用
62   - PageResult<SysPostDO> pageResult = postService.pagePosts(reqVO);
  62 + PageResult<SysPostDO> pageResult = postService.getPostPage(reqVO);
63 63  
64 64 // 断言
65 65 assertEquals(1, pageResult.getTotal());
... ... @@ -85,7 +85,7 @@ class SysPostServiceTest extends BaseDbUnitTest {
85 85 reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
86 86  
87 87 // 调用
88   - List<SysPostDO> list = postService.listPosts(reqVO);
  88 + List<SysPostDO> list = postService.getPosts(reqVO);
89 89 // 断言
90 90 assertEquals(1, list.size());
91 91 assertPojoEquals(postDO, list.get(0));
... ...
src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java
... ... @@ -133,7 +133,7 @@ public class SysDictDataServiceTest extends BaseDbUnitTest {
133 133 reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
134 134  
135 135 // 调用
136   - List<SysDictDataDO> list = dictDataService.getDictDataList(reqVO);
  136 + List<SysDictDataDO> list = dictDataService.getDictDatas(reqVO);
137 137 // 断言
138 138 assertEquals(1, list.size());
139 139 assertPojoEquals(dbDictData, list.get(0));
... ...
src/test/java/cn/iocoder/dashboard/modules/system/service/logger/SysOperateLogServiceImplTest.java
1 1 package cn.iocoder.dashboard.modules.system.service.logger;
2 2  
3 3 import cn.hutool.core.map.MapUtil;
4   -import cn.hutool.core.util.ArrayUtil;
5   -import cn.hutool.core.util.RandomUtil;
6   -import cn.hutool.core.util.ReflectUtil;
7 4 import cn.iocoder.dashboard.BaseDbUnitTest;
8 5 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
9 6 import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
10 7 import cn.iocoder.dashboard.common.pojo.PageResult;
11 8 import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum;
12   -import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
13 9 import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils;
14 10 import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogCreateReqVO;
15 11 import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogExportReqVO;
... ... @@ -17,7 +13,6 @@ import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOp
17 13 import cn.iocoder.dashboard.modules.system.dal.dataobject.logger.SysOperateLogDO;
18 14 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
19 15 import cn.iocoder.dashboard.modules.system.dal.mysql.logger.SysOperateLogMapper;
20   -import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper;
21 16 import cn.iocoder.dashboard.modules.system.enums.common.SysSexEnum;
22 17 import cn.iocoder.dashboard.modules.system.service.logger.impl.SysOperateLogServiceImpl;
23 18 import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
... ... @@ -28,105 +23,78 @@ import org.springframework.boot.test.mock.mockito.MockBean;
28 23 import org.springframework.context.annotation.Import;
29 24  
30 25 import javax.annotation.Resource;
31   -import java.lang.reflect.Field;
32   -import java.util.Arrays;
33   -import java.util.HashMap;
34   -import java.util.List;
35   -import java.util.Map;
  26 +import java.util.*;
36 27 import java.util.concurrent.ExecutionException;
37 28 import java.util.concurrent.Future;
38   -import java.util.stream.Collectors;
39 29  
40 30 import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  31 +import static cn.iocoder.dashboard.util.RandomUtils.randomLongId;
41 32 import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
42 33 import static org.junit.jupiter.api.Assertions.assertEquals;
43   -import static org.junit.jupiter.api.Assertions.assertNotNull;
  34 +import static org.mockito.Mockito.when;
44 35  
45 36 @Import({SysOperateLogServiceImpl.class})
46 37 public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
47 38  
48 39 @Resource
49   - private SysOperateLogService sysOperateLogServiceImpl;
  40 + private SysOperateLogService operateLogServiceImpl;
50 41  
51 42 @Resource
52   - private SysOperateLogMapper sysOperateLogMapper;
53   -
54   - @Resource
55   - private SysUserMapper sysUserMapper;
  43 + private SysOperateLogMapper operateLogMapper;
56 44  
57 45 @MockBean
58   - private SysUserService sysUserService;
  46 + private SysUserService userService;
59 47  
60 48 @Test
61 49 public void testCreateOperateLogAsync() throws InterruptedException, ExecutionException {
62   -
63 50 String traceId = TracerUtils.getTraceId();
64   - SysOperateLogCreateReqVO reqVO = RandomUtils.randomPojo(SysOperateLogCreateReqVO.class, vo -> {
65   - vo.setTraceId(traceId);
66   - vo.setUserId(RandomUtil.randomLong(1, Long.MAX_VALUE));
67   -
68   - Map<String, Object> map = MapUtil.builder("orderId", (Object) 1).build();
69   - vo.setExts(map);
  51 + SysOperateLogCreateReqVO reqVO = RandomUtils.randomPojo(SysOperateLogCreateReqVO.class, o -> {
  52 + o.setTraceId(traceId);
  53 + o.setUserId(randomLongId());
  54 + o.setExts(MapUtil.<String, Object>builder("orderId", randomLongId()).build());
70 55 });
71 56  
72 57 // 执行service方法
73   - Future<Boolean> future = sysOperateLogServiceImpl.createOperateLogAsync(reqVO);
74   -
75   - // 等异步执行完
  58 + Future<Boolean> future = operateLogServiceImpl.createOperateLogAsync(reqVO);
76 59 future.get();
77   -
78   - // 查询插入的数据
79   - SysOperateLogDO sysOperateLogDO = sysOperateLogMapper.selectOne("trace_id", traceId);
80   -
81   - // 断言
82   - assertNotNull(sysOperateLogDO);
83   - // 断言,忽略基本字段
  60 + // 断言插入是否正确
  61 + SysOperateLogDO sysOperateLogDO = operateLogMapper.selectOne("trace_id", traceId);
84 62 assertPojoEquals(reqVO, sysOperateLogDO);
85 63 }
86 64  
87   -
88 65 @Test
89   - public void testPageOperateLog() {
90   -
  66 + public void testGetOperateLogPage() {
91 67 // 构造测试数据
92   -
93 68 // 先构造用户
94   - SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, sysUserDO -> {
95   - sysUserDO.setNickname("wangkai");
96   - sysUserDO.setSex(SysSexEnum.MALE.getSEX());
97   - sysUserDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  69 + SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> {
  70 + o.setNickname("wangkai");
  71 + o.setSex(SysSexEnum.MALE.getSEX());
  72 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
98 73 });
99   - sysUserMapper.insert(user);
  74 + when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user));
100 75 Long userId = user.getId();
101   -
102   -
103 76 // 构造操作日志
104   - SysOperateLogDO sysOperateLogDO = RandomUtils.randomPojo(SysOperateLogDO.class, entity -> {
105   - entity.setTraceId(TracerUtils.getTraceId());
106   - entity.setUserId(userId);
107   - entity.setModule("order");
108   - entity.setType(OperateTypeEnum.CREATE.getType());
109   - entity.setStartTime(buildTime(2021, 3, 6));
110   - entity.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode());
111   -
112   - Map<String, Object> map = new HashMap<>();
113   - map.put("orderId", 1);
114   - entity.setExts(map);
  77 + SysOperateLogDO sysOperateLogDO = RandomUtils.randomPojo(SysOperateLogDO.class, o -> {
  78 + o.setUserId(userId);
  79 + o.setModule("order");
  80 + o.setType(OperateTypeEnum.CREATE.getType());
  81 + o.setStartTime(buildTime(2021, 3, 6));
  82 + o.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode());
  83 + o.setExts(MapUtil.<String, Object>builder("orderId", randomLongId()).build());
115 84 });
116   -
117   - sysOperateLogMapper.insert(sysOperateLogDO);
  85 + operateLogMapper.insert(sysOperateLogDO);
118 86  
119 87 // 下面几个是不匹配的数据
120   - // 随机userId
121   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
122   - // module不同
123   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setModule("user")));
124   - // type不同
125   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
126   - // createTime不同
127   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
128   - // resultCode不同
129   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
  88 + // 随机 userId
  89 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
  90 + // module 不同
  91 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setModule("user")));
  92 + // type 不同
  93 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
  94 + // createTime 不同
  95 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
  96 + // resultCode 不同
  97 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
130 98  
131 99 // 构造调用参数
132 100 SysOperateLogPageReqVO reqVO = new SysOperateLogPageReqVO();
... ... @@ -138,8 +106,7 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
138 106 reqVO.setSuccess(true);
139 107  
140 108 // 调用service方法
141   - PageResult<SysOperateLogDO> pageResult = sysOperateLogServiceImpl.pageOperateLog(reqVO);
142   -
  109 + PageResult<SysOperateLogDO> pageResult = operateLogServiceImpl.getOperateLogPage(reqVO);
143 110 // 断言,只查到了一条符合条件的
144 111 assertEquals(1, pageResult.getTotal());
145 112 assertEquals(1, pageResult.getList().size());
... ... @@ -147,47 +114,38 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
147 114 }
148 115  
149 116 @Test
150   - public void testListOperateLogs() {
151   -
  117 + public void testGetOperateLogs() {
152 118 // 构造测试数据
153   -
154 119 // 先构造用户
155   - SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, sysUserDO -> {
156   - sysUserDO.setNickname("wangkai");
157   - sysUserDO.setSex(SysSexEnum.MALE.getSEX());
158   - sysUserDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  120 + SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> {
  121 + o.setNickname("wangkai");
  122 + o.setSex(SysSexEnum.MALE.getSEX());
  123 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
159 124 });
160   - sysUserMapper.insert(user);
  125 + when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user));
161 126 Long userId = user.getId();
162   -
163   -
164 127 // 构造操作日志
165   - SysOperateLogDO sysOperateLogDO = RandomUtils.randomPojo(SysOperateLogDO.class, entity -> {
166   - entity.setTraceId(TracerUtils.getTraceId());
167   - entity.setUserId(userId);
168   - entity.setModule("order");
169   - entity.setType(OperateTypeEnum.CREATE.getType());
170   - entity.setStartTime(buildTime(2021, 3, 6));
171   - entity.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode());
172   -
173   -
174   - Map<String, Object> map = MapUtil.builder("orderId", (Object) 1).build();
175   - entity.setExts(map);
  128 + SysOperateLogDO sysOperateLogDO = RandomUtils.randomPojo(SysOperateLogDO.class, o -> {
  129 + o.setUserId(userId);
  130 + o.setModule("order");
  131 + o.setType(OperateTypeEnum.CREATE.getType());
  132 + o.setStartTime(buildTime(2021, 3, 6));
  133 + o.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode());
  134 + o.setExts(MapUtil.<String, Object>builder("orderId", randomLongId()).build());
176 135 });
177   -
178   - sysOperateLogMapper.insert(sysOperateLogDO);
  136 + operateLogMapper.insert(sysOperateLogDO);
179 137  
180 138 // 下面几个是不匹配的数据
181   - // 随机userId
182   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
183   - // module不同
184   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setModule("user")));
185   - // type不同
186   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
187   - // createTime不同
188   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
189   - // resultCode不同
190   - sysOperateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
  139 + // 随机 userId
  140 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
  141 + // module 不同
  142 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setModule("user")));
  143 + // type 不同
  144 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
  145 + // createTime 不同
  146 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
  147 + // resultCode 不同
  148 + operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
191 149  
192 150 // 构造调用参数
193 151 SysOperateLogExportReqVO reqVO = new SysOperateLogExportReqVO();
... ... @@ -198,11 +156,11 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
198 156 reqVO.setEndTime(buildTime(2021, 3, 7));
199 157 reqVO.setSuccess(true);
200 158  
201   - // 调用service方法
202   - List<SysOperateLogDO> list = sysOperateLogServiceImpl.listOperateLogs(reqVO);
203   -
  159 + // 调用 service 方法
  160 + List<SysOperateLogDO> list = operateLogServiceImpl.getOperateLogs(reqVO);
204 161 // 断言,只查到了一条符合条件的
205 162 assertEquals(1, list.size());
206 163 assertPojoEquals(sysOperateLogDO, list.get(0));
207 164 }
  165 +
208 166 }
... ...
src/test/java/cn/iocoder/dashboard/modules/system/service/permission/SysMenuServiceTest.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.service.permission;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.hutool.core.lang.Assert;
  5 +import cn.iocoder.dashboard.BaseDbUnitTest;
  6 +import cn.iocoder.dashboard.modules.system.controller.permission.vo.menu.SysMenuCreateReqVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.permission.vo.menu.SysMenuListReqVO;
  8 +import cn.iocoder.dashboard.modules.system.controller.permission.vo.menu.SysMenuUpdateReqVO;
  9 +import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysMenuDO;
  10 +import cn.iocoder.dashboard.modules.system.dal.mysql.permission.SysMenuMapper;
  11 +import cn.iocoder.dashboard.modules.system.enums.permission.MenuTypeEnum;
  12 +import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysMenuProducer;
  13 +import cn.iocoder.dashboard.modules.system.service.permission.impl.SysMenuServiceImpl;
  14 +import cn.iocoder.dashboard.util.AopTargetUtils;
  15 +import cn.iocoder.dashboard.util.AssertUtils;
  16 +import cn.iocoder.dashboard.util.RandomUtils;
  17 +import cn.iocoder.dashboard.util.object.ObjectUtils;
  18 +import com.google.common.collect.Multimap;
  19 +import org.junit.jupiter.api.Assertions;
  20 +import org.junit.jupiter.api.Test;
  21 +import org.springframework.boot.test.mock.mockito.MockBean;
  22 +import org.springframework.context.annotation.Import;
  23 +
  24 +import javax.annotation.Resource;
  25 +
  26 +import java.util.*;
  27 +
  28 +import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
  29 +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  30 +import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
  31 +import static cn.iocoder.dashboard.util.RandomUtils.*;
  32 +import static org.junit.jupiter.api.Assertions.assertEquals;
  33 +import static org.mockito.Mockito.verify;
  34 +
  35 +@Import(SysMenuServiceImpl.class)
  36 +public class SysMenuServiceTest extends BaseDbUnitTest {
  37 +
  38 + @Resource
  39 + private SysMenuServiceImpl sysMenuService;
  40 +
  41 + @MockBean
  42 + private SysPermissionService sysPermissionService;
  43 +
  44 + @MockBean
  45 + private SysMenuProducer sysMenuProducer;
  46 +
  47 + @Resource
  48 + private SysMenuMapper menuMapper;
  49 +
  50 + @Test
  51 + public void testInitLocalCache_success() throws Exception {
  52 + SysMenuDO menuDO1 = createMenuDO(MenuTypeEnum.MENU, "xxxx", 0L);
  53 + menuMapper.insert(menuDO1);
  54 + SysMenuDO menuDO2 = createMenuDO(MenuTypeEnum.MENU, "xxxx", 0L);
  55 + menuMapper.insert(menuDO2);
  56 +
  57 + //调用
  58 + sysMenuService.initLocalCache();
  59 +
  60 + // 获取代理对象
  61 + SysMenuServiceImpl target = (SysMenuServiceImpl) AopTargetUtils.getTarget(sysMenuService);
  62 +
  63 + Map<Long, SysMenuDO> menuCache = (Map<Long, SysMenuDO>) BeanUtil.getFieldValue(target, "menuCache");
  64 + Assert.isTrue(menuCache.size() == 2);
  65 + assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId()));
  66 + assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId()));
  67 +
  68 + Multimap<String, SysMenuDO> permissionMenuCache = (Multimap<String, SysMenuDO>) BeanUtil.getFieldValue(target, "permissionMenuCache");
  69 + Assert.isTrue(permissionMenuCache.size() == 2);
  70 + assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission()));
  71 + assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission()));
  72 +
  73 + Date maxUpdateTime = (Date) BeanUtil.getFieldValue(target, "maxUpdateTime");
  74 + assertEquals(ObjectUtils.max(menuDO1.getUpdateTime(), menuDO2.getUpdateTime()), maxUpdateTime);
  75 + }
  76 +
  77 + @Test
  78 + public void testCreateMenu_success() {
  79 + //构造父目录
  80 + SysMenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L);
  81 + menuMapper.insert(menuDO);
  82 + Long parentId = menuDO.getId();
  83 +
  84 + //调用
  85 + SysMenuCreateReqVO vo = randomPojo(SysMenuCreateReqVO.class, o -> {
  86 + o.setParentId(parentId);
  87 + o.setName("testSonName");
  88 + o.setType(MenuTypeEnum.MENU.getType());
  89 + o.setStatus(RandomUtils.randomCommonStatus());
  90 + });
  91 + Long menuId = sysMenuService.createMenu(vo);
  92 +
  93 + //断言
  94 + Assertions.assertNotNull(menuId);
  95 + // 校验记录的属性是否正确
  96 + SysMenuDO ret = menuMapper.selectById(menuId);
  97 + assertPojoEquals(vo, ret);
  98 + // 校验调用
  99 + verify(sysMenuProducer).sendMenuRefreshMessage();
  100 + }
  101 +
  102 + @Test
  103 + public void testUpdateMenu_success() {
  104 + //构造父子目录
  105 + SysMenuDO sonMenuDO = initParentAndSonMenuDO();
  106 + Long sonId = sonMenuDO.getId();
  107 + Long parentId = sonMenuDO.getParentId();
  108 +
  109 + //调用
  110 + SysMenuUpdateReqVO vo = RandomUtils.randomPojo(SysMenuUpdateReqVO.class, o -> {
  111 + o.setId(sonId);
  112 + o.setParentId(parentId);
  113 + o.setType(MenuTypeEnum.MENU.getType());
  114 + o.setStatus(RandomUtils.randomCommonStatus());
  115 + o.setName("pppppp"); //修改名字
  116 + });
  117 + sysMenuService.updateMenu(vo);
  118 +
  119 + //断言
  120 + // 校验记录的属性是否正确
  121 + SysMenuDO ret = menuMapper.selectById(sonId);
  122 + assertPojoEquals(vo, ret);
  123 + // 校验调用
  124 + verify(sysMenuProducer).sendMenuRefreshMessage();
  125 + }
  126 +
  127 + @Test
  128 + public void testUpdateMenu_sonIdNotExist() {
  129 + Long sonId = 99999L;
  130 + Long parentId = 10000L;
  131 +
  132 + //调用
  133 + SysMenuUpdateReqVO vo = RandomUtils.randomPojo(SysMenuUpdateReqVO.class, o -> {
  134 + o.setId(sonId);
  135 + o.setParentId(parentId);
  136 + o.setType(MenuTypeEnum.MENU.getType());
  137 + o.setStatus(RandomUtils.randomCommonStatus());
  138 + });
  139 + //断言
  140 + assertServiceException(() -> sysMenuService.updateMenu(vo), MENU_NOT_EXISTS);
  141 + }
  142 +
  143 + @Test
  144 + public void testDeleteMenu_success() {
  145 + SysMenuDO sonMenuDO = initParentAndSonMenuDO();
  146 + Long sonId = sonMenuDO.getId();
  147 +
  148 + //调用
  149 + sysMenuService.deleteMenu(sonId);
  150 +
  151 + //断言
  152 + SysMenuDO menuDO = menuMapper.selectById(sonId);
  153 + Assert.isNull(menuDO);
  154 + verify(sysPermissionService).processMenuDeleted(sonId);
  155 + verify(sysMenuProducer).sendMenuRefreshMessage();
  156 + }
  157 +
  158 + @Test
  159 + public void testDeleteMenu_menuNotExist() {
  160 + Long sonId = 99999L;
  161 +
  162 + assertServiceException(() -> sysMenuService.deleteMenu(sonId), MENU_NOT_EXISTS);
  163 + }
  164 +
  165 + @Test
  166 + public void testDeleteMenu_existChildren() {
  167 + SysMenuDO sonMenu = initParentAndSonMenuDO();
  168 + Long parentId = sonMenu.getParentId();
  169 +
  170 + assertServiceException(() -> sysMenuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN);
  171 + }
  172 +
  173 + @Test
  174 + public void testGetMenus_success() {
  175 + Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
  176 + SysMenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L);
  177 + menuMapper.insert(menuDO);
  178 + idMenuMap.put(menuDO.getId(), menuDO);
  179 +
  180 + SysMenuDO sonMenu = createMenuDO(MenuTypeEnum.MENU, "son", menuDO.getId());
  181 + menuMapper.insert(sonMenu);
  182 + idMenuMap.put(sonMenu.getId(), sonMenu);
  183 +
  184 + //调用
  185 + List<SysMenuDO> menuDOS = sysMenuService.getMenus();
  186 +
  187 + //断言
  188 + Assert.isTrue(menuDOS.size() == idMenuMap.size());
  189 + menuDOS.stream().forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m));
  190 + }
  191 +
  192 +
  193 + @Test
  194 + public void testGetMenusReqVo_success() {
  195 + Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
  196 + //用于验证可以模糊搜索名称包含"name",状态为1的menu
  197 + SysMenuDO menu = createMenuDO(MenuTypeEnum.MENU, "name2", 0L, 1);
  198 + menuMapper.insert(menu);
  199 + idMenuMap.put(menu.getId(), menu);
  200 +
  201 + menu = createMenuDO(MenuTypeEnum.MENU, "11name111", 0L, 1);
  202 + menuMapper.insert(menu);
  203 + idMenuMap.put(menu.getId(), menu);
  204 +
  205 + menu = createMenuDO(MenuTypeEnum.MENU, "name", 0L, 1);
  206 + menuMapper.insert(menu);
  207 + idMenuMap.put(menu.getId(), menu);
  208 +
  209 + //以下是不符合搜索条件的的menu
  210 + menu = createMenuDO(MenuTypeEnum.MENU, "xxxxxx", 0L, 1);
  211 + menuMapper.insert(menu);
  212 + menu = createMenuDO(MenuTypeEnum.MENU, "name", 0L, 2);
  213 + menuMapper.insert(menu);
  214 +
  215 + //调用
  216 + SysMenuListReqVO reqVO = new SysMenuListReqVO();
  217 + reqVO.setStatus(1);
  218 + reqVO.setName("name");
  219 + List<SysMenuDO> menuDOS = sysMenuService.getMenus(reqVO);
  220 +
  221 + //断言
  222 + Assert.isTrue(menuDOS.size() == idMenuMap.size());
  223 + menuDOS.stream().forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m));
  224 + }
  225 +
  226 + @Test
  227 + public void testListMenusFromCache_success() throws Exception {
  228 + Map<Long, SysMenuDO> mockCacheMap = new HashMap<>();
  229 + //获取代理对象
  230 + SysMenuServiceImpl target = (SysMenuServiceImpl) AopTargetUtils.getTarget(sysMenuService);
  231 + BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
  232 +
  233 + Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
  234 + //用于验证搜索类型为MENU,状态为1的menu
  235 + SysMenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1);
  236 + mockCacheMap.put(menuDO.getId(), menuDO);
  237 + idMenuMap.put(menuDO.getId(), menuDO);
  238 +
  239 + menuDO = createMenuDO(2L, MenuTypeEnum.MENU, "name", 0L, 1);
  240 + mockCacheMap.put(menuDO.getId(), menuDO);
  241 + idMenuMap.put(menuDO.getId(), menuDO);
  242 +
  243 + //以下是不符合搜索条件的menu
  244 + menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1);
  245 + mockCacheMap.put(menuDO.getId(), menuDO);
  246 + menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2);
  247 + mockCacheMap.put(menuDO.getId(), menuDO);
  248 +
  249 + List<SysMenuDO> menuDOS = sysMenuService.listMenusFromCache(Arrays.asList(MenuTypeEnum.MENU.getType()), Arrays.asList(1));
  250 + Assert.isTrue(menuDOS.size() == idMenuMap.size());
  251 + menuDOS.stream().forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m));
  252 + }
  253 +
  254 +
  255 + @Test
  256 + public void testListMenusFromCache2_success() throws Exception {
  257 + Map<Long, SysMenuDO> mockCacheMap = new HashMap<>();
  258 + //获取代理对象
  259 + SysMenuServiceImpl target = (SysMenuServiceImpl) AopTargetUtils.getTarget(sysMenuService);
  260 + BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
  261 +
  262 + Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
  263 + //验证搜索id为1, 类型为MENU, 状态为1 的menu
  264 + SysMenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1);
  265 + mockCacheMap.put(menuDO.getId(), menuDO);
  266 + idMenuMap.put(menuDO.getId(), menuDO);
  267 +
  268 + //以下是不符合搜索条件的menu
  269 + menuDO = createMenuDO(2L, MenuTypeEnum.MENU, "name", 0L, 1);
  270 + mockCacheMap.put(menuDO.getId(), menuDO);
  271 + menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1);
  272 + mockCacheMap.put(menuDO.getId(), menuDO);
  273 + menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2);
  274 + mockCacheMap.put(menuDO.getId(), menuDO);
  275 +
  276 + List<SysMenuDO> menuDOS = sysMenuService.listMenusFromCache(Arrays.asList(1L),
  277 + Arrays.asList(MenuTypeEnum.MENU.getType()), Arrays.asList(1));
  278 + Assert.isTrue(menuDOS.size() == idMenuMap.size());
  279 + menuDOS.stream().forEach(menu -> assertPojoEquals(idMenuMap.get(menu.getId()), menu));
  280 + }
  281 +
  282 + @Test
  283 + public void testCheckParentResource_success() {
  284 + SysMenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L);
  285 + menuMapper.insert(menuDO);
  286 + Long parentId = menuDO.getId();
  287 +
  288 + sysMenuService.checkParentResource(parentId, null);
  289 + }
  290 +
  291 + @Test
  292 + public void testCheckParentResource_canNotSetSelfToBeParent() {
  293 + assertServiceException(() -> sysMenuService.checkParentResource(1L, 1L), MENU_PARENT_ERROR);
  294 + }
  295 +
  296 + @Test
  297 + public void testCheckParentResource_parentNotExist() {
  298 + assertServiceException(() -> sysMenuService.checkParentResource(randomLongId(), null), MENU_PARENT_NOT_EXISTS);
  299 + }
  300 +
  301 + @Test
  302 + public void testCheckParentResource_parentTypeError() {
  303 + SysMenuDO menuDO = createMenuDO(MenuTypeEnum.BUTTON, "parent", 0L);
  304 + menuMapper.insert(menuDO);
  305 + Long parentId = menuDO.getId();
  306 +
  307 + assertServiceException(() -> sysMenuService.checkParentResource(parentId, null), MENU_PARENT_NOT_DIR_OR_MENU);
  308 + }
  309 +
  310 + @Test
  311 + public void testCheckResource_success(){
  312 + SysMenuDO sonMenu=initParentAndSonMenuDO();
  313 + Long parentId=sonMenu.getParentId();
  314 +
  315 + Long otherSonMenuId=randomLongId();
  316 + String otherSonMenuName=randomString();
  317 +
  318 + sysMenuService.checkResource(parentId,otherSonMenuName,otherSonMenuId);
  319 + }
  320 +
  321 + @Test
  322 + public void testCheckResource_sonMenuNameDuplicate(){
  323 + SysMenuDO sonMenu=initParentAndSonMenuDO();
  324 + Long parentId=sonMenu.getParentId();
  325 +
  326 + Long otherSonMenuId=randomLongId();
  327 + String otherSonMenuName=sonMenu.getName(); //相同名称
  328 +
  329 + assertServiceException(()->sysMenuService.checkResource(parentId,otherSonMenuName,otherSonMenuId), MENU_NAME_DUPLICATE);
  330 + }
  331 +
  332 + /**
  333 + * 构造父子目录,返回子目录
  334 + *
  335 + * @return
  336 + */
  337 + private SysMenuDO initParentAndSonMenuDO() {
  338 + //构造父子目录
  339 + SysMenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L);
  340 + menuMapper.insert(menuDO);
  341 + Long parentId = menuDO.getId();
  342 +
  343 + SysMenuDO sonMenuDO = createMenuDO(MenuTypeEnum.MENU, "testSonName", parentId);
  344 + menuMapper.insert(sonMenuDO);
  345 + return sonMenuDO;
  346 + }
  347 +
  348 + private SysMenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId) {
  349 + return createMenuDO(typeEnum, menuName, parentId, RandomUtils.randomCommonStatus());
  350 + }
  351 +
  352 + private SysMenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) {
  353 + return createMenuDO(null, typeEnum, menuName, parentId, status);
  354 + }
  355 +
  356 + private SysMenuDO createMenuDO(Long id, MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) {
  357 + SysMenuDO sonMenuDO = RandomUtils.randomPojo(SysMenuDO.class, o -> {
  358 + o.setId(id);
  359 + o.setParentId(parentId);
  360 + o.setType(typeEnum.getType());
  361 + o.setStatus(status);
  362 + o.setName(menuName);
  363 + });
  364 + return sonMenuDO;
  365 + }
  366 +
  367 +
  368 +}
... ...
src/test/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionServiceTest.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.service.permission;
  2 +
  3 +import cn.iocoder.dashboard.BaseDbUnitTest;
  4 +import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleMenuDO;
  5 +import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysUserRoleDO;
  6 +import cn.iocoder.dashboard.modules.system.dal.mysql.permission.SysRoleMenuMapper;
  7 +import cn.iocoder.dashboard.modules.system.dal.mysql.permission.SysUserRoleMapper;
  8 +import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysPermissionProducer;
  9 +import cn.iocoder.dashboard.modules.system.service.permission.impl.SysPermissionServiceImpl;
  10 +import org.junit.jupiter.api.Test;
  11 +import org.springframework.boot.test.mock.mockito.MockBean;
  12 +import org.springframework.context.annotation.Import;
  13 +
  14 +import javax.annotation.Resource;
  15 +import java.util.List;
  16 +
  17 +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  18 +import static cn.iocoder.dashboard.util.RandomUtils.randomLongId;
  19 +import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
  20 +import static org.junit.jupiter.api.Assertions.assertEquals;
  21 +import static org.mockito.Mockito.verify;
  22 +
  23 +@Import(SysPermissionServiceImpl.class)
  24 +public class SysPermissionServiceTest extends BaseDbUnitTest {
  25 +
  26 + @Resource
  27 + private SysPermissionServiceImpl permissionService;
  28 +
  29 + @Resource
  30 + private SysRoleMenuMapper roleMenuMapper;
  31 + @Resource
  32 + private SysUserRoleMapper userRoleMapper;
  33 +
  34 + @MockBean
  35 + private SysRoleService roleService;
  36 + @MockBean
  37 + private SysMenuService menuService;
  38 +
  39 + @MockBean
  40 + private SysPermissionProducer permissionProducer;
  41 +
  42 + @Test
  43 + public void testProcessRoleDeleted() {
  44 + // 准备参数
  45 + Long roleId = randomLongId();
  46 + // mock 数据 UserRole
  47 + SysUserRoleDO userRoleDO01 = randomPojo(SysUserRoleDO.class, o -> o.setRoleId(roleId)); // 被删除
  48 + userRoleMapper.insert(userRoleDO01);
  49 + SysUserRoleDO userRoleDO02 = randomPojo(SysUserRoleDO.class); // 不被删除
  50 + userRoleMapper.insert(userRoleDO02);
  51 + // mock 数据 RoleMenu
  52 + SysRoleMenuDO roleMenuDO01 = randomPojo(SysRoleMenuDO.class, o -> o.setRoleId(roleId)); // 被删除
  53 + roleMenuMapper.insert(roleMenuDO01);
  54 + SysRoleMenuDO roleMenuDO02 = randomPojo(SysRoleMenuDO.class); // 不被删除
  55 + roleMenuMapper.insert(roleMenuDO02);
  56 +
  57 + // 调用
  58 + permissionService.processRoleDeleted(roleId);
  59 + // 断言数据 RoleMenuDO
  60 + List<SysRoleMenuDO> dbRoleMenus = roleMenuMapper.selectList();
  61 + assertEquals(1, dbRoleMenus.size());
  62 + assertPojoEquals(dbRoleMenus.get(0), roleMenuDO02);
  63 + // 断言数据 UserRoleDO
  64 + List<SysUserRoleDO> dbUserRoles = userRoleMapper.selectList();
  65 + assertEquals(1, dbUserRoles.size());
  66 + assertPojoEquals(dbUserRoles.get(0), userRoleDO02);
  67 + // 断言调用
  68 + verify(permissionProducer).sendRoleMenuRefreshMessage();
  69 + }
  70 +
  71 + @Test
  72 + public void testProcessMenuDeleted() {
  73 + // 准备参数
  74 + Long menuId = randomLongId();
  75 + // mock 数据
  76 + SysRoleMenuDO roleMenuDO01 = randomPojo(SysRoleMenuDO.class, o -> o.setMenuId(menuId)); // 被删除
  77 + roleMenuMapper.insert(roleMenuDO01);
  78 + SysRoleMenuDO roleMenuDO02 = randomPojo(SysRoleMenuDO.class); // 不被删除
  79 + roleMenuMapper.insert(roleMenuDO02);
  80 +
  81 + // 调用
  82 + permissionService.processMenuDeleted(menuId);
  83 + // 断言数据
  84 + List<SysRoleMenuDO> dbRoleMenus = roleMenuMapper.selectList();
  85 + assertEquals(1, dbRoleMenus.size());
  86 + assertPojoEquals(dbRoleMenus.get(0), roleMenuDO02);
  87 + // 断言调用
  88 + verify(permissionProducer).sendRoleMenuRefreshMessage();
  89 + }
  90 +
  91 + @Test
  92 + public void testProcessUserDeleted() {
  93 + // 准备参数
  94 + Long userId = randomLongId();
  95 + // mock 数据
  96 + SysUserRoleDO userRoleDO01 = randomPojo(SysUserRoleDO.class, o -> o.setUserId(userId)); // 被删除
  97 + userRoleMapper.insert(userRoleDO01);
  98 + SysUserRoleDO userRoleDO02 = randomPojo(SysUserRoleDO.class); // 不被删除
  99 + userRoleMapper.insert(userRoleDO02);
  100 +
  101 + // 调用
  102 + permissionService.processUserDeleted(userId);
  103 + // 断言数据
  104 + List<SysUserRoleDO> dbUserRoles = userRoleMapper.selectList();
  105 + assertEquals(1, dbUserRoles.size());
  106 + assertPojoEquals(dbUserRoles.get(0), userRoleDO02);
  107 + }
  108 +
  109 +}
... ...
src/test/java/cn/iocoder/dashboard/util/AopTargetUtils.java 0 → 100644
  1 +package cn.iocoder.dashboard.util;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import org.springframework.aop.framework.AdvisedSupport;
  5 +import org.springframework.aop.framework.AopProxy;
  6 +import org.springframework.aop.support.AopUtils;
  7 +
  8 +import java.lang.reflect.Field;
  9 +
  10 +/**
  11 + * http://www.bubuko.com/infodetail-3471885.html
  12 + */
  13 +public class AopTargetUtils {
  14 +
  15 + /**
  16 + * 获取 目标对象
  17 + *
  18 + * @param proxy 代理对象
  19 + * @return
  20 + * @throws Exception
  21 + */
  22 + public static Object getTarget(Object proxy) throws Exception {
  23 + if (!AopUtils.isAopProxy(proxy)) {
  24 + return proxy; //不是代理对象
  25 + }
  26 + if (AopUtils.isJdkDynamicProxy(proxy)) {
  27 + return getJdkDynamicProxyTargetObject(proxy);
  28 + } else { //cglib
  29 + return getCglibProxyTargetObject(proxy);
  30 + }
  31 + }
  32 +
  33 + private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
  34 + Object dynamicAdvisedInterceptor = BeanUtil.getFieldValue(proxy, "CGLIB$CALLBACK_0");
  35 + AdvisedSupport advisedSupport = (AdvisedSupport) BeanUtil.getFieldValue(dynamicAdvisedInterceptor, "advised");
  36 + Object target = advisedSupport.getTargetSource().getTarget();
  37 + return target;
  38 + }
  39 +
  40 + private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
  41 + AopProxy aopProxy = (AopProxy) BeanUtil.getFieldValue(proxy, "h");
  42 + AdvisedSupport advisedSupport = (AdvisedSupport) BeanUtil.getFieldValue(aopProxy, "advised");
  43 + Object target = advisedSupport.getTargetSource().getTarget();
  44 + return target;
  45 + }
  46 +
  47 +}
0 48 \ No newline at end of file
... ...
src/test/resources/sql/clean.sql
1 1 -- inf 开头的 DB
2 2 DELETE FROM "inf_config";
3 3 DELETE FROM "inf_file";
  4 +DELETE FROM "inf_job";
  5 +DELETE FROM "inf_job_log";
  6 +DELETE FROM "inf_api_access_log";
  7 +DELETE FROM "inf_api_error_log";
4 8  
5 9 -- sys 开头的 DB
6 10 DELETE FROM "sys_dept";
... ... @@ -8,6 +12,7 @@ DELETE FROM &quot;sys_dict_data&quot;;
8 12 DELETE FROM "sys_role";
9 13 DELETE FROM "sys_role_menu";
10 14 DELETE FROM "sys_menu";
  15 +DELETE FROM "sys_user_role";
11 16 DELETE FROM "sys_dict_type";
12 17 DELETE FROM "sys_user_session";
13 18 DELETE FROM "sys_post";
... ...
src/test/resources/sql/create_tables.sql
... ... @@ -29,6 +29,44 @@ CREATE TABLE IF NOT EXISTS &quot;inf_file&quot; (
29 29 PRIMARY KEY ("id")
30 30 ) COMMENT '文件表';
31 31  
  32 +CREATE TABLE IF NOT EXISTS "inf_job" (
  33 + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '任务编号',
  34 + "name" varchar(32) NOT NULL COMMENT '任务名称',
  35 + "status" tinyint(4) NOT NULL COMMENT '任务状态',
  36 + "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字',
  37 + "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数',
  38 + "cron_expression" varchar(32) NOT NULL COMMENT 'CRON 表达式',
  39 + "retry_count" int(11) NOT NULL DEFAULT '0' COMMENT '重试次数',
  40 + "retry_interval" int(11) NOT NULL DEFAULT '0' COMMENT '重试间隔',
  41 + "monitor_timeout" int(11) NOT NULL DEFAULT '0' COMMENT '监控超时时间',
  42 + "creator" varchar(64) DEFAULT '' COMMENT '创建者',
  43 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  44 + "updater" varchar(64) DEFAULT '' COMMENT '更新者',
  45 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  46 + "deleted" bit NOT NULL DEFAULT FALSE COMMENT '是否删除',
  47 + PRIMARY KEY ("id")
  48 +) COMMENT='定时任务表';
  49 +
  50 +DROP TABLE IF EXISTS "inf_job_log";
  51 +CREATE TABLE "inf_job_log" (
  52 + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '日志编号',
  53 + "job_id" bigint(20) NOT NULL COMMENT '任务编号',
  54 + "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字',
  55 + "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数',
  56 + "execute_index" tinyint(4) NOT NULL DEFAULT '1' COMMENT '第几次执行',
  57 + "begin_time" datetime NOT NULL COMMENT '开始执行时间',
  58 + "end_time" datetime DEFAULT NULL COMMENT '结束执行时间',
  59 + "duration" int(11) DEFAULT NULL COMMENT '执行时长',
  60 + "status" tinyint(4) NOT NULL COMMENT '任务状态',
  61 + "result" varchar(4000) DEFAULT '' COMMENT '结果数据',
  62 + "creator" varchar(64) DEFAULT '' COMMENT '创建者',
  63 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  64 + "updater" varchar(64) DEFAULT '' COMMENT '更新者',
  65 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  66 + "deleted" bit(1) NOT NULL DEFAULT FALSE COMMENT '是否删除',
  67 + PRIMARY KEY ("id")
  68 +)COMMENT='定时任务日志表';
  69 +
32 70 -- sys 开头的 DB
33 71  
34 72 CREATE TABLE IF NOT EXISTS "sys_dept" (
... ... @@ -113,6 +151,18 @@ CREATE TABLE IF NOT EXISTS &quot;sys_menu&quot; (
113 151 PRIMARY KEY ("id")
114 152 ) COMMENT '菜单权限表';
115 153  
  154 +CREATE TABLE IF NOT EXISTS "sys_user_role" (
  155 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  156 + "user_id" bigint NOT NULL,
  157 + "role_id" bigint NOT NULL,
  158 + "creator" varchar(64) DEFAULT '',
  159 + "create_time" timestamp DEFAULT NULL,
  160 + "updater" varchar(64) DEFAULT '',
  161 + "update_time" timestamp DEFAULT NULL,
  162 + "deleted" bit DEFAULT FALSE,
  163 + PRIMARY KEY ("id")
  164 +) COMMENT '用户和角色关联表';
  165 +
116 166 CREATE TABLE IF NOT EXISTS "sys_dict_type" (
117 167 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
118 168 "name" varchar(100) NOT NULL DEFAULT '',
... ... @@ -219,7 +269,7 @@ CREATE TABLE IF NOT EXISTS `sys_operate_log` (
219 269 PRIMARY KEY (`id`)
220 270 ) COMMENT ='操作日志记录';
221 271  
222   -create table IF NOT EXISTS "sys_user" (
  272 +CREATE TABLE IF NOT EXISTS "sys_user" (
223 273 "id" bigint not null GENERATED BY DEFAULT AS IDENTITY,
224 274 "username" varchar(30) not null,
225 275 "password" varchar(100) not null default '',
... ... @@ -242,8 +292,7 @@ create table IF NOT EXISTS &quot;sys_user&quot; (
242 292 primary key ("id")
243 293 ) comment '用户信息表';
244 294  
245   -
246   -create table "inf_api_access_log" (
  295 +CREATE TABLE IF NOT EXISTS "inf_api_access_log" (
247 296 "id" bigint not null GENERATED BY DEFAULT AS IDENTITY,
248 297 "trace_id" varchar(64) not null default '',
249 298 "user_id" bigint not null default '0',
... ... @@ -265,10 +314,9 @@ create table &quot;inf_api_access_log&quot; (
265 314 "update_time" timestamp not null default current_timestamp,
266 315 "deleted" bit not null default false,
267 316 primary key ("id")
268   -) comment 'API 访问日志表';
269   -
  317 +) COMMENT 'API 访问日志表';
270 318  
271   -create table "inf_api_error_log" (
  319 +CREATE TABLE IF NOT EXISTS "inf_api_error_log" (
272 320 "id" integer not null GENERATED BY DEFAULT AS IDENTITY,
273 321 "trace_id" varchar(64) not null,
274 322 "user_id" bigint not null default '0',
... ... @@ -297,4 +345,4 @@ create table &quot;inf_api_error_log&quot; (
297 345 "update_time" timestamp not null default current_timestamp,
298 346 "deleted" bit not null default false,
299 347 primary key ("id")
300   -) comment '系统异常日志';
301 348 \ No newline at end of file
  349 +) COMMENT '系统异常日志';
... ...