From 8200ea822f20e90d9d9fede623605cab8e05e391 Mon Sep 17 00:00:00 2001 From: Charles7c <charles7c@126.com> Date: Sun, 26 Feb 2023 00:19:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=AE=A1=E7=90=86/=E5=B2=97=E4=BD=8D?= =?UTF-8?q?=E7=AE=A1=E7=90=86=EF=BC=88=E5=88=97=E8=A1=A8=E3=80=81=E6=9F=A5?= =?UTF-8?q?=E7=9C=8B=E8=AF=A6=E6=83=85=E3=80=81=E6=96=B0=E5=A2=9E=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E3=80=81=E5=88=A0=E9=99=A4=E3=80=81=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnadmin/common/model/dto/LoginUser.java | 2 +- .../cnadmin/auth/model/vo/UserInfoVO.java | 4 +- .../cnadmin/system/mapper/PostMapper.java | 28 + .../cnadmin/system/mapper/UserPostMapper.java | 28 + .../cnadmin/system/model/entity/PostDO.java | 64 ++ .../cnadmin/system/model/entity/RoleDO.java | 2 +- .../cnadmin/system/model/entity/UserDO.java | 2 +- .../system/model/entity/UserPostDO.java | 53 ++ .../cnadmin/system/model/query/PostQuery.java | 55 ++ .../system/model/request/PostRequest.java | 78 +++ .../system/model/request/UserRequest.java | 6 + .../cnadmin/system/model/vo/PostDetailVO.java | 77 +++ .../cnadmin/system/model/vo/PostVO.java | 69 +++ .../cnadmin/system/model/vo/UserDetailVO.java | 40 +- .../cnadmin/system/service/PostService.java | 53 ++ .../system/service/UserPostService.java | 56 ++ .../cnadmin/system/service/UserService.java | 9 - .../system/service/impl/PostServiceImpl.java | 113 ++++ .../system/service/impl/RoleServiceImpl.java | 15 +- .../service/impl/UserPostServiceImpl.java | 74 +++ .../system/service/impl/UserServiceImpl.java | 30 +- continew-admin-ui/src/api/common/index.ts | 17 +- continew-admin-ui/src/api/system/post.ts | 54 ++ continew-admin-ui/src/api/system/user.ts | 7 +- continew-admin-ui/src/locale/en-US.ts | 2 + continew-admin-ui/src/locale/zh-CN.ts | 2 + .../src/router/routes/modules/system.ts | 10 + .../src/views/system/dept/index.vue | 2 +- .../src/views/system/post/index.vue | 552 ++++++++++++++++++ .../src/views/system/post/locale/en-US.ts | 3 + .../src/views/system/post/locale/zh-CN.ts | 3 + .../src/views/system/user/index.vue | 119 ++-- .../controller/common/CommonController.java | 16 +- .../controller/system/PostController.java | 40 ++ .../changelog/v0.0.1/continew-admin_data.sql | 50 +- .../changelog/v0.0.1/continew-admin_table.sql | 23 +- 36 files changed, 1656 insertions(+), 102 deletions(-) create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/PostMapper.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/UserPostMapper.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/PostDO.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserPostDO.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/query/PostQuery.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/PostRequest.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/PostDetailVO.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/PostVO.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/PostService.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserPostService.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/PostServiceImpl.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserPostServiceImpl.java create mode 100644 continew-admin-ui/src/api/system/post.ts create mode 100644 continew-admin-ui/src/views/system/post/index.vue create mode 100644 continew-admin-ui/src/views/system/post/locale/en-US.ts create mode 100644 continew-admin-ui/src/views/system/post/locale/zh-CN.ts create mode 100644 continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/system/PostController.java diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/dto/LoginUser.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/dto/LoginUser.java index ac927b44..7952bb28 100644 --- a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/dto/LoginUser.java +++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/dto/LoginUser.java @@ -75,7 +75,7 @@ public class LoginUser implements Serializable { private String description; /** - * 最后一次修改密码的时间 + * 最后一次修改密码时间 */ private LocalDateTime pwdResetTime; diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/vo/UserInfoVO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/vo/UserInfoVO.java index e60b6412..ce1f745f 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/vo/UserInfoVO.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/vo/UserInfoVO.java @@ -93,9 +93,9 @@ public class UserInfoVO implements Serializable { private String description; /** - * 最后一次修改密码的时间 + * 最后一次修改密码时间 */ - @Schema(description = "最后一次修改密码的时间") + @Schema(description = "最后一次修改密码时间") private LocalDateTime pwdResetTime; /** diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/PostMapper.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/PostMapper.java new file mode 100644 index 00000000..478d1000 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/PostMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.mapper; + +import top.charles7c.cnadmin.common.base.BaseMapper; +import top.charles7c.cnadmin.system.model.entity.PostDO; + +/** + * 岗位 Mapper + * + * @author Charles7c + * @since 2023/2/25 22:26 + */ +public interface PostMapper extends BaseMapper<PostDO> {} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/UserPostMapper.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/UserPostMapper.java new file mode 100644 index 00000000..803c7448 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/UserPostMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.mapper; + +import top.charles7c.cnadmin.common.base.BaseMapper; +import top.charles7c.cnadmin.system.model.entity.UserPostDO; + +/** + * 用户和岗位 Mapper + * + * @author Charles7c + * @since 2023/2/25 22:28 + */ +public interface UserPostMapper extends BaseMapper<UserPostDO> {} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/PostDO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/PostDO.java new file mode 100644 index 00000000..a03b4c0f --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/PostDO.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.model.entity; + +import lombok.Data; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import top.charles7c.cnadmin.common.base.BaseDO; +import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; + +/** + * 岗位实体 + * + * @author Charles7c + * @since 2023/2/25 22:25 + */ +@Data +@TableName("sys_post") +public class PostDO extends BaseDO { + + private static final long serialVersionUID = 1L; + + /** + * 岗位 ID + */ + @TableId + private Long postId; + + /** + * 岗位名称 + */ + private String postName; + + /** + * 描述 + */ + private String description; + + /** + * 岗位排序 + */ + private Integer postSort; + + /** + * 状态(1启用 2禁用) + */ + private DisEnableStatusEnum status; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/RoleDO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/RoleDO.java index 7428d51e..42237425 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/RoleDO.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/RoleDO.java @@ -32,7 +32,7 @@ import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; * @since 2023/2/8 22:54 */ @Data -@TableName(value = "sys_role", autoResultMap = true) +@TableName("sys_role") public class RoleDO extends BaseDO { private static final long serialVersionUID = 1L; diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserDO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserDO.java index 5d490c95..85f17711 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserDO.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserDO.java @@ -91,7 +91,7 @@ public class UserDO extends BaseDO { private DisEnableStatusEnum status; /** - * 最后一次修改密码的时间 + * 最后一次修改密码时间 */ private LocalDateTime pwdResetTime; diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserPostDO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserPostDO.java new file mode 100644 index 00000000..1638b0f2 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserPostDO.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.model.entity; + +import java.io.Serializable; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import com.baomidou.mybatisplus.annotation.TableName; + +/** + * 用户和岗位实体 + * + * @author Charles7c + * @since 2023/2/25 22:28 + */ +@Data +@NoArgsConstructor +@TableName("sys_user_post") +public class UserPostDO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 用户 ID + */ + private Long userId; + + /** + * 岗位 ID + */ + private Long postId; + + public UserPostDO(Long userId, Long postId) { + this.userId = userId; + this.postId = postId; + } +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/query/PostQuery.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/query/PostQuery.java new file mode 100644 index 00000000..3e9fb71e --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/query/PostQuery.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.model.query; + +import java.io.Serializable; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +import org.springdoc.api.annotations.ParameterObject; + +import top.charles7c.cnadmin.common.annotation.Query; + +/** + * 岗位查询条件 + * + * @author Charles7c + * @since 2023/2/25 22:30 + */ +@Data +@ParameterObject +@Schema(description = "岗位查询条件") +public class PostQuery implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 岗位名称 + */ + @Schema(description = "岗位名称") + @Query(type = Query.Type.INNER_LIKE) + private String postName; + + /** + * 状态(1启用 2禁用) + */ + @Schema(description = "状态(1启用 2禁用)") + @Query + private Integer status; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/PostRequest.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/PostRequest.java new file mode 100644 index 00000000..dd5722c1 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/PostRequest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.model.request; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +import org.hibernate.validator.constraints.Length; + +import top.charles7c.cnadmin.common.base.BaseRequest; +import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; + +/** + * 创建或修改岗位信息 + * + * @author Charles7c + * @since 2023/2/25 22:31 + */ +@Data +@Schema(description = "创建或修改岗位信息") +public class PostRequest extends BaseRequest { + + private static final long serialVersionUID = 1L; + + /** + * 岗位 ID + */ + @Schema(description = "岗位 ID") + @Null(message = "新增时,ID 必须为空", groups = Create.class) + @NotNull(message = "修改时,ID 不能为空", groups = Update.class) + private Long postId; + + /** + * 岗位名称 + */ + @Schema(description = "岗位名称") + @NotBlank(message = "岗位名称不能为空") + private String postName; + + /** + * 岗位排序 + */ + @Schema(description = "岗位排序") + @NotNull(message = "岗位排序不能为空") + private Integer postSort; + + /** + * 描述 + */ + @Schema(description = "描述") + @Length(max = 200, message = "描述长度不能超过 {max} 个字符") + private String description; + + /** + * 状态(1启用 2禁用) + */ + @Schema(description = "状态(1启用 2禁用)", type = "Integer", allowableValues = {"1", "2"}) + private DisEnableStatusEnum status; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/UserRequest.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/UserRequest.java index 7600fa88..884b96e6 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/UserRequest.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/UserRequest.java @@ -107,6 +107,12 @@ public class UserRequest extends BaseRequest { @NotNull(message = "所属部门不能为空") private Long deptId; + /** + * 岗位 ID 列表 + */ + @Schema(description = "所属岗位") + private List<Long> postIds; + /** * 角色 ID 列表 */ diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/PostDetailVO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/PostDetailVO.java new file mode 100644 index 00000000..f0b175a7 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/PostDetailVO.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.model.vo; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; + +import top.charles7c.cnadmin.common.base.BaseDetailVO; +import top.charles7c.cnadmin.common.config.easyexcel.ExcelBaseEnumConverter; +import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; + +/** + * 岗位详情信息 + * + * @author Charles7c + * @since 2023/2/25 22:35 + */ +@Data +@ExcelIgnoreUnannotated +@Schema(description = "岗位详情信息") +public class PostDetailVO extends BaseDetailVO { + + private static final long serialVersionUID = 1L; + + /** + * 岗位 ID + */ + @Schema(description = "岗位 ID") + @ExcelProperty(value = "岗位ID") + private Long postId; + + /** + * 岗位名称 + */ + @Schema(description = "岗位名称") + @ExcelProperty(value = "岗位名称") + private String postName; + + /** + * 岗位排序 + */ + @Schema(description = "岗位排序") + @ExcelProperty(value = "岗位排序") + private Integer postSort; + + /** + * 状态(1启用 2禁用) + */ + @Schema(description = "状态(1启用 2禁用)") + @ExcelProperty(value = "状态", converter = ExcelBaseEnumConverter.class) + private DisEnableStatusEnum status; + + /** + * 描述 + */ + @Schema(description = "描述") + @ExcelProperty(value = "描述") + private String description; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/PostVO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/PostVO.java new file mode 100644 index 00000000..9d1506b4 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/PostVO.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.model.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +import io.swagger.v3.oas.annotations.media.Schema; + +import top.charles7c.cnadmin.common.base.BaseVO; +import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; + +/** + * 岗位信息 + * + * @author Charles7c + * @since 2023/2/25 22:34 + */ +@Data +@Accessors(chain = true) +@Schema(description = "岗位信息") +public class PostVO extends BaseVO { + + private static final long serialVersionUID = 1L; + + /** + * 岗位 ID + */ + @Schema(description = "岗位 ID") + private Long postId; + + /** + * 岗位名称 + */ + @Schema(description = "岗位名称") + private String postName; + + /** + * 岗位排序 + */ + @Schema(description = "岗位排序") + private Integer postSort; + + /** + * 状态(1启用 2禁用) + */ + @Schema(description = "状态(1启用 2禁用)") + private DisEnableStatusEnum status; + + /** + * 描述 + */ + @Schema(description = "描述") + private String description; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/UserDetailVO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/UserDetailVO.java index 74edf5ed..da52af81 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/UserDetailVO.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/UserDetailVO.java @@ -16,6 +16,7 @@ package top.charles7c.cnadmin.system.model.vo; +import java.time.LocalDateTime; import java.util.List; import lombok.Data; @@ -107,17 +108,10 @@ public class UserDetailVO extends BaseDetailVO { private String description; /** - * 角色 ID 列表 + * 最后一次修改密码时间 */ - @Schema(description = "角色 ID 列表") - private List<Long> roleIds; - - /** - * 所属角色 - */ - @Schema(description = "所属角色") - @ExcelProperty(value = "所属角色") - private String roleNames; + @Schema(description = "最后一次修改密码时间") + private LocalDateTime pwdResetTime; /** * 部门 ID @@ -131,4 +125,30 @@ public class UserDetailVO extends BaseDetailVO { @Schema(description = "所属部门") @ExcelProperty(value = "所属部门") private String deptName; + + /** + * 岗位 ID 列表 + */ + @Schema(description = "岗位 ID 列表") + private List<Long> postIds; + + /** + * 所属岗位 + */ + @Schema(description = "所属岗位") + @ExcelProperty(value = "所属岗位") + private String postNames; + + /** + * 角色 ID 列表 + */ + @Schema(description = "角色 ID 列表") + private List<Long> roleIds; + + /** + * 所属角色 + */ + @Schema(description = "所属角色") + @ExcelProperty(value = "所属角色") + private String roleNames; } diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/PostService.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/PostService.java new file mode 100644 index 00000000..b5e3548e --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/PostService.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.service; + +import java.util.List; + +import top.charles7c.cnadmin.common.base.BaseService; +import top.charles7c.cnadmin.common.model.vo.LabelValueVO; +import top.charles7c.cnadmin.system.model.query.PostQuery; +import top.charles7c.cnadmin.system.model.request.PostRequest; +import top.charles7c.cnadmin.system.model.vo.PostDetailVO; +import top.charles7c.cnadmin.system.model.vo.PostVO; + +/** + * 岗位业务接口 + * + * @author Charles7c + * @since 2023/2/25 22:38 + */ +public interface PostService extends BaseService<PostVO, PostDetailVO, PostQuery, PostRequest> { + + /** + * 构建字典 + * + * @param list + * 原始列表数据 + * @return 字典列表 + */ + List<LabelValueVO<Long>> buildDict(List<PostVO> list); + + /** + * 根据岗位 ID 列表查询 + * + * @param postIds + * 岗位 ID 列表 + * @return 岗位名称列表 + */ + List<String> listPostNamesByPostIds(List<Long> postIds); +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserPostService.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserPostService.java new file mode 100644 index 00000000..1d6ce5f2 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserPostService.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.service; + +import java.util.List; + +/** + * 用户和岗位业务接口 + * + * @author Charles7c + * @since 2023/2/25 22:40 + */ +public interface UserPostService { + + /** + * 保存 + * + * @param postIds + * 岗位 ID 列表 + * @param userId + * 用户 ID + */ + void save(List<Long> postIds, Long userId); + + /** + * 根据岗位 ID 列表查询 + * + * @param postIds + * 岗位 ID 列表 + * @return 总记录数 + */ + Long countByPostIds(List<Long> postIds); + + /** + * 根据用户 ID 查询 + * + * @param userId + * 用户 ID + * @return 岗位 ID 列表 + */ + List<Long> listPostIdsByUserId(Long userId); +} \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java index 05c4d24b..f44a67bd 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java @@ -106,13 +106,4 @@ public interface UserService extends BaseService<UserVO, UserDetailVO, UserQuery * @return 用户数量 */ Long countByDeptIds(List<Long> deptIds); - - /** - * 根据角色 ID 列表查询 - * - * @param roleIds - * 角色 ID 列表 - * @return 用户数量 - */ - Long countByRoleIds(List<Long> roleIds); } diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/PostServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/PostServiceImpl.java new file mode 100644 index 00000000..bcf96f7c --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/PostServiceImpl.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.service.impl; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import lombok.RequiredArgsConstructor; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import cn.hutool.core.collection.CollUtil; + +import top.charles7c.cnadmin.common.base.BaseServiceImpl; +import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; +import top.charles7c.cnadmin.common.model.vo.LabelValueVO; +import top.charles7c.cnadmin.common.util.validate.CheckUtils; +import top.charles7c.cnadmin.system.mapper.PostMapper; +import top.charles7c.cnadmin.system.model.entity.PostDO; +import top.charles7c.cnadmin.system.model.query.PostQuery; +import top.charles7c.cnadmin.system.model.request.PostRequest; +import top.charles7c.cnadmin.system.model.vo.*; +import top.charles7c.cnadmin.system.service.*; + +/** + * 岗位业务实现类 + * + * @author Charles7c + * @since 2023/2/25 22:38 + */ +@Service +@RequiredArgsConstructor +public class PostServiceImpl extends BaseServiceImpl<PostMapper, PostDO, PostVO, PostDetailVO, PostQuery, PostRequest> + implements PostService { + + private final UserPostService userPostService; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long add(PostRequest request) { + String postName = request.getPostName(); + boolean isExists = this.checkNameExists(postName, request.getPostId()); + CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", postName)); + + // 新增岗位 + request.setStatus(DisEnableStatusEnum.ENABLE); + return super.add(request); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(PostRequest request) { + String postName = request.getPostName(); + boolean isExists = this.checkNameExists(postName, request.getPostId()); + CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", postName)); + + // 更新岗位 + super.update(request); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(List<Long> ids) { + CheckUtils.throwIf(() -> userPostService.countByPostIds(ids) > 0, "所选岗位存在用户关联,请解除关联后重试"); + super.delete(ids); + } + + /** + * 检查名称是否存在 + * + * @param name + * 名称 + * @param id + * ID + * @return 是否存在 + */ + private boolean checkNameExists(String name, Long id) { + return super.lambdaQuery().eq(PostDO::getPostName, name).ne(id != null, PostDO::getPostId, id).exists(); + } + + @Override + public List<LabelValueVO<Long>> buildDict(List<PostVO> list) { + if (CollUtil.isEmpty(list)) { + return Collections.emptyList(); + } + return list.stream().map(p -> new LabelValueVO<>(p.getPostName(), p.getPostId())).collect(Collectors.toList()); + } + + @Override + public List<String> listPostNamesByPostIds(List<Long> postIds) { + List<PostDO> postList = super.lambdaQuery().select(PostDO::getPostName).in(PostDO::getPostId, postIds).list(); + if (CollUtil.isEmpty(postList)) { + return Collections.emptyList(); + } + return postList.stream().map(PostDO::getPostName).collect(Collectors.toList()); + } +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/RoleServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/RoleServiceImpl.java index 384f8abf..bb7fd5eb 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/RoleServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/RoleServiceImpl.java @@ -20,8 +20,6 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import javax.annotation.Resource; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -57,15 +55,14 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO, private final RoleMenuService roleMenuService; private final RoleDeptService roleDeptService; private final MenuService menuService; - @Resource - private UserService userService; + private final UserRoleService userRoleService; @Override @Transactional(rollbackFor = Exception.class) public Long add(RoleRequest request) { String roleName = request.getRoleName(); - boolean isExist = this.checkNameExists(roleName, request.getRoleId()); - CheckUtils.throwIf(() -> isExist, String.format("新增失败,'%s'已存在", roleName)); + boolean isExists = this.checkNameExists(roleName, request.getRoleId()); + CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", roleName)); // 新增角色 request.setStatus(DisEnableStatusEnum.ENABLE); @@ -81,8 +78,8 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO, @Transactional(rollbackFor = Exception.class) public void update(RoleRequest request) { String roleName = request.getRoleName(); - boolean isExist = this.checkNameExists(roleName, request.getRoleId()); - CheckUtils.throwIf(() -> isExist, String.format("修改失败,'%s'已存在", roleName)); + boolean isExists = this.checkNameExists(roleName, request.getRoleId()); + CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", roleName)); // 更新角色 super.update(request); @@ -96,7 +93,7 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO, @Override @Transactional(rollbackFor = Exception.class) public void delete(List<Long> ids) { - CheckUtils.throwIf(() -> userService.countByRoleIds(ids) > 0, "所选角色存在用户关联,请解除关联后重试"); + CheckUtils.throwIf(() -> userRoleService.countByRoleIds(ids) > 0, "所选角色存在用户关联,请解除关联后重试"); super.delete(ids); } diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserPostServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserPostServiceImpl.java new file mode 100644 index 00000000..53d15dd5 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserPostServiceImpl.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.service.impl; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import lombok.RequiredArgsConstructor; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; + +import cn.hutool.core.collection.CollUtil; + +import top.charles7c.cnadmin.system.mapper.UserPostMapper; +import top.charles7c.cnadmin.system.model.entity.UserPostDO; +import top.charles7c.cnadmin.system.service.UserPostService; + +/** + * 用户和岗位业务实现类 + * + * @author Charles7c + * @since 2023/2/25 22:40 + */ +@Service +@RequiredArgsConstructor +public class UserPostServiceImpl implements UserPostService { + + private final UserPostMapper userPostMapper; + + @Override + public void save(List<Long> postIds, Long userId) { + if (CollUtil.isEmpty(postIds)) { + return; + } + // 删除原有关联 + userPostMapper.delete(Wrappers.<UserPostDO>lambdaQuery().eq(UserPostDO::getUserId, userId)); + // 保存最新关联 + List<UserPostDO> userPostList = + postIds.stream().map(postId -> new UserPostDO(userId, postId)).collect(Collectors.toList()); + userPostMapper.insertBatch(userPostList); + } + + @Override + public Long countByPostIds(List<Long> postIds) { + return userPostMapper.selectCount(Wrappers.<UserPostDO>lambdaQuery().in(UserPostDO::getPostId, postIds)); + } + + @Override + public List<Long> listPostIdsByUserId(Long userId) { + List<UserPostDO> userPostList = userPostMapper.selectList( + Wrappers.<UserPostDO>lambdaQuery().select(UserPostDO::getPostId).eq(UserPostDO::getUserId, userId)); + if (CollUtil.isEmpty(userPostList)) { + return Collections.emptyList(); + } + return userPostList.stream().map(UserPostDO::getPostId).collect(Collectors.toList()); + } +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java index 79c92c76..71cd2b7c 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java @@ -51,10 +51,7 @@ import top.charles7c.cnadmin.system.model.request.UpdateUserRoleRequest; import top.charles7c.cnadmin.system.model.request.UserRequest; import top.charles7c.cnadmin.system.model.vo.UserDetailVO; import top.charles7c.cnadmin.system.model.vo.UserVO; -import top.charles7c.cnadmin.system.service.DeptService; -import top.charles7c.cnadmin.system.service.RoleService; -import top.charles7c.cnadmin.system.service.UserRoleService; -import top.charles7c.cnadmin.system.service.UserService; +import top.charles7c.cnadmin.system.service.*; /** * 用户业务实现类 @@ -67,19 +64,20 @@ import top.charles7c.cnadmin.system.service.UserService; public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO, UserDetailVO, UserQuery, UserRequest> implements UserService, CommonUserService { + private final UserPostService userPostService; + private final PostService postService; private final UserRoleService userRoleService; + private final RoleService roleService; private final LocalStorageProperties localStorageProperties; @Resource - private RoleService roleService; - @Resource private DeptService deptService; @Override @Transactional(rollbackFor = Exception.class) public Long add(UserRequest request) { String username = request.getUsername(); - boolean isExist = this.checkNameExists(username, request.getUserId()); - CheckUtils.throwIf(() -> isExist, String.format("新增失败,'%s'已存在", username)); + boolean isExists = this.checkNameExists(username, request.getUserId()); + CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", username)); // 新增用户 request.setStatus(DisEnableStatusEnum.ENABLE); @@ -87,6 +85,8 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO, super.lambdaUpdate() .set(UserDO::getPassword, SecureUtils.md5Salt(Constants.DEFAULT_PASSWORD, userId.toString())) .set(UserDO::getPwdResetTime, LocalDateTime.now()).eq(UserDO::getUserId, userId).update(); + // 保存用户和岗位关联 + userPostService.save(request.getPostIds(), userId); // 保存用户和角色关联 userRoleService.save(request.getRoleIds(), userId); return userId; @@ -96,12 +96,14 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO, @Transactional(rollbackFor = Exception.class) public void update(UserRequest request) { String username = request.getUsername(); - boolean isExist = this.checkNameExists(username, request.getUserId()); - CheckUtils.throwIf(() -> isExist, String.format("修改失败,'%s'已存在", username)); + boolean isExists = this.checkNameExists(username, request.getUserId()); + CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", username)); // 更新用户 super.update(request); Long userId = request.getUserId(); + // 保存用户和岗位关联 + userPostService.save(request.getPostIds(), userId); // 保存用户和角色关联 userRoleService.save(request.getRoleIds(), userId); } @@ -128,6 +130,9 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO, List<Long> roleIds = userRoleService.listRoleIdsByUserId(detailVO.getUserId()); detailVO.setRoleIds(roleIds); detailVO.setRoleNames(String.join(",", roleService.listRoleNamesByRoleIds(roleIds))); + List<Long> postIds = userPostService.listPostIdsByUserId(detailVO.getUserId()); + detailVO.setPostIds(postIds); + detailVO.setPostNames(String.join(",", postService.listPostNamesByPostIds(postIds))); } } @@ -227,11 +232,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO, return super.lambdaQuery().in(UserDO::getDeptId, deptIds).count(); } - @Override - public Long countByRoleIds(List<Long> roleIds) { - return userRoleService.countByRoleIds(roleIds); - } - @Override public String getNicknameById(Long userId) { return super.getById(userId).getNickname(); diff --git a/continew-admin-ui/src/api/common/index.ts b/continew-admin-ui/src/api/common/index.ts index 80d67b76..71a63b5d 100644 --- a/continew-admin-ui/src/api/common/index.ts +++ b/continew-admin-ui/src/api/common/index.ts @@ -3,8 +3,14 @@ import qs from 'query-string'; import { DeptParam } from '@/api/system/dept'; import { MenuParam } from '@/api/system/menu'; import { RoleParam } from '@/api/system/role'; +import { PostParam } from '@/api/system/post'; import { TreeNodeData } from '@arco-design/web-vue'; +export interface LabelValueRecord { + label: string; + value: any; +} + export function listDeptTree(params: DeptParam) { return axios.get<TreeNodeData[]>('/common/tree/dept', { params, @@ -24,10 +30,19 @@ export function listMenuTree(params: MenuParam) { } export function listRoleDict(params: RoleParam) { - return axios.get<TreeNodeData[]>('/common/dict/role', { + return axios.get<LabelValueRecord[]>('/common/dict/role', { params, paramsSerializer: (obj) => { return qs.stringify(obj); }, }); } + +export function listPostDict(params: PostParam) { + return axios.get<LabelValueRecord[]>('/common/dict/post', { + params, + paramsSerializer: (obj) => { + return qs.stringify(obj); + }, + }); +} \ No newline at end of file diff --git a/continew-admin-ui/src/api/system/post.ts b/continew-admin-ui/src/api/system/post.ts new file mode 100644 index 00000000..ff33ceb4 --- /dev/null +++ b/continew-admin-ui/src/api/system/post.ts @@ -0,0 +1,54 @@ +import axios from 'axios'; +import qs from 'query-string'; + +const BASE_URL = '/system/post'; + +export interface PostRecord { + postId?: number; + postName: string; + postSort?: number; + description?: string; + status?: number; + createUserString?: string; + createTime?: string; + updateUserString?: string; + updateTime?: string; +} + +export interface PostParam { + postName?: string; + status?: number; + page?: number; + size?: number; + sort?: Array<string>; +} + +export interface PostListRes { + list: PostRecord[]; + total: number; +} + +export function listPost(params: PostParam) { + return axios.get<PostListRes>(`${BASE_URL}`, { + params, + paramsSerializer: (obj) => { + return qs.stringify(obj); + }, + }); +} + +export function getPost(id: number) { + return axios.get<PostRecord>(`${BASE_URL}/${id}`); +} + +export function addPost(req: PostRecord) { + return axios.post(BASE_URL, req); +} + +export function updatePost(req: PostRecord) { + return axios.put(BASE_URL, req); +} + +export function deletePost(ids: number | Array<number>) { + return axios.delete(`${BASE_URL}/${ids}`); +} diff --git a/continew-admin-ui/src/api/system/user.ts b/continew-admin-ui/src/api/system/user.ts index 0b888c58..a122dec9 100644 --- a/continew-admin-ui/src/api/system/user.ts +++ b/continew-admin-ui/src/api/system/user.ts @@ -11,14 +11,17 @@ export interface UserRecord { email?: string; phone?: string; description?: string; - roleIds?: Array<number>; - deptId?: number; status?: number; + pwdResetTime?: string; createUserString?: string; createTime?: string; updateUserString?: string; updateTime?: string; + deptId?: number; deptName?: string; + postIds?: Array<number>; + postNames?: Array<string>; + roleIds?: Array<number>; roleNames?: Array<string>; disabled?: boolean; } diff --git a/continew-admin-ui/src/locale/en-US.ts b/continew-admin-ui/src/locale/en-US.ts index 10d1262e..3be651ac 100644 --- a/continew-admin-ui/src/locale/en-US.ts +++ b/continew-admin-ui/src/locale/en-US.ts @@ -4,6 +4,7 @@ import localeUser from '@/views/system/user/locale/en-US'; import localeRole from '@/views/system/role/locale/en-US'; import localeMenu from '@/views/system/menu/locale/en-US'; import localeDept from '@/views/system/dept/locale/en-US'; +import localePost from '@/views/system/post/locale/en-US'; import localeOnlineUser from '@/views/monitor/online/locale/en-US'; import localeLoginLog from '@/views/monitor/log/login/locale/en-US'; @@ -55,6 +56,7 @@ export default { ...localeRole, ...localeMenu, ...localeDept, + ...localePost, ...localeOnlineUser, ...localeLoginLog, diff --git a/continew-admin-ui/src/locale/zh-CN.ts b/continew-admin-ui/src/locale/zh-CN.ts index 88774c06..81f81e5f 100644 --- a/continew-admin-ui/src/locale/zh-CN.ts +++ b/continew-admin-ui/src/locale/zh-CN.ts @@ -4,6 +4,7 @@ import localeUser from '@/views/system/user/locale/zh-CN'; import localeRole from '@/views/system/role/locale/zh-CN'; import localeMenu from '@/views/system/menu/locale/zh-CN'; import localeDept from '@/views/system/dept/locale/zh-CN'; +import localePost from '@/views/system/post/locale/zh-CN'; import localeOnlineUser from '@/views/monitor/online/locale/zh-CN'; import localeLoginLog from '@/views/monitor/log/login/locale/zh-CN'; @@ -55,6 +56,7 @@ export default { ...localeRole, ...localeMenu, ...localeDept, + ...localePost, ...localeOnlineUser, ...localeLoginLog, diff --git a/continew-admin-ui/src/router/routes/modules/system.ts b/continew-admin-ui/src/router/routes/modules/system.ts index 10405cba..8c82ce25 100644 --- a/continew-admin-ui/src/router/routes/modules/system.ts +++ b/continew-admin-ui/src/router/routes/modules/system.ts @@ -52,6 +52,16 @@ const System: AppRouteRecordRaw = { roles: ['*'], }, }, + { + path: '/system/post', + name: 'Post', + component: () => import('@/views/system/post/index.vue'), + meta: { + locale: 'menu.system.post.list', + requiresAuth: true, + roles: ['*'], + }, + }, ], }; diff --git a/continew-admin-ui/src/views/system/dept/index.vue b/continew-admin-ui/src/views/system/dept/index.vue index a6b0bed0..34393b8b 100644 --- a/continew-admin-ui/src/views/system/dept/index.vue +++ b/continew-admin-ui/src/views/system/dept/index.vue @@ -216,7 +216,7 @@ render-to-body @cancel="handleDetailCancel" > - <a-descriptions title="基础信息" :column="2" bordered size="large"> + <a-descriptions :column="2" bordered size="large" layout="vertical"> <a-descriptions-item label="部门名称"> <a-skeleton v-if="detailLoading" :animation="true"> <a-skeleton-line :rows="1" /> diff --git a/continew-admin-ui/src/views/system/post/index.vue b/continew-admin-ui/src/views/system/post/index.vue new file mode 100644 index 00000000..717640c2 --- /dev/null +++ b/continew-admin-ui/src/views/system/post/index.vue @@ -0,0 +1,552 @@ +<template> + <div class="app-container"> + <Breadcrumb :items="['menu.system', 'menu.system.post.list']" /> + <a-card class="general-card" :title="$t('menu.system.post.list')"> + <!-- 头部区域 --> + <div class="header"> + <!-- 搜索栏 --> + <div v-if="showQuery" class="header-query"> + <a-form ref="queryRef" :model="queryParams" layout="inline"> + <a-form-item field="postName" hide-label> + <a-input + v-model="queryParams.postName" + placeholder="输入岗位名称搜索" + allow-clear + style="width: 150px" + @press-enter="handleQuery" + /> + </a-form-item> + <a-form-item field="status" hide-label> + <a-select + v-model="queryParams.status" + :options="statusOptions" + placeholder="状态搜索" + allow-clear + style="width: 150px" + /> + </a-form-item> + <a-form-item hide-label> + <a-space> + <a-button type="primary" @click="handleQuery"> + <template #icon><icon-search /></template>查询 + </a-button> + <a-button @click="resetQuery"> + <template #icon><icon-refresh /></template>重置 + </a-button> + </a-space> + </a-form-item> + </a-form> + </div> + <!-- 操作栏 --> + <div class="header-operation"> + <a-row> + <a-col :span="12"> + <a-space> + <a-button type="primary" @click="toCreate"> + <template #icon><icon-plus /></template>新增 + </a-button> + <a-button + type="primary" + status="success" + :disabled="single" + :title="single ? '请选择一条要修改的数据' : ''" + @click="toUpdate(ids[0])" + > + <template #icon><icon-edit /></template>修改 + </a-button> + <a-button + type="primary" + status="danger" + :disabled="multiple" + :title="multiple ? '请选择要删除的数据' : ''" + @click="handleBatchDelete" + > + <template #icon><icon-delete /></template>删除 + </a-button> + <a-button + :loading="exportLoading" + type="primary" + status="warning" + @click="handleExport" + > + <template #icon><icon-download /></template>导出 + </a-button> + </a-space> + </a-col> + <a-col :span="12"> + <right-toolbar + v-model:show-query="showQuery" + @refresh="getList" + /> + </a-col> + </a-row> + </div> + </div> + + <!-- 列表区域 --> + <a-table + ref="tableRef" + :data="postList" + :row-selection="{ + type: 'checkbox', + showCheckedAll: true, + onlyCurrent: false, + }" + :pagination="{ + showTotal: true, + showPageSize: true, + total: total, + current: queryParams.page, + }" + row-key="postId" + :bordered="false" + :stripe="true" + :loading="loading" + size="large" + @page-change="handlePageChange" + @page-size-change="handlePageSizeChange" + @selection-change="handleSelectionChange" + > + <template #columns> + <a-table-column title="ID" data-index="postId" /> + <a-table-column title="岗位名称"> + <template #cell="{ record }"> + <a-link @click="toDetail(record.postId)">{{ + record.postName + }}</a-link> + </template> + </a-table-column> + <a-table-column + title="岗位排序" + align="center" + data-index="postSort" + /> + <a-table-column title="状态" align="center" data-index="status"> + <template #cell="{ record }"> + <a-switch + v-model="record.status" + :checked-value="1" + :unchecked-value="2" + :disabled="record.disabled" + @change="handleChangeStatus(record)" + /> + </template> + </a-table-column> + <a-table-column title="描述" data-index="description" /> + <a-table-column title="创建人" data-index="createUserString" /> + <a-table-column title="创建时间" data-index="createTime" /> + <a-table-column title="操作" align="center"> + <template #cell="{ record }"> + <a-button + v-permission="['admin']" + type="text" + size="small" + title="修改" + :disabled="record.disabled" + @click="toUpdate(record.postId)" + > + <template #icon><icon-edit /></template>修改 + </a-button> + <a-popconfirm + content="确定要删除当前选中的数据吗?" + type="warning" + @ok="handleDelete([record.postId])" + > + <a-button + v-permission="['admin']" + type="text" + size="small" + title="删除" + :disabled="record.disabled" + > + <template #icon><icon-delete /></template>删除 + </a-button> + </a-popconfirm> + </template> + </a-table-column> + </template> + </a-table> + + <!-- 表单区域 --> + <a-modal + :title="title" + :visible="visible" + :mask-closable="false" + unmount-on-close + render-to-body + @ok="handleOk" + @cancel="handleCancel" + > + <a-form ref="formRef" :model="form" :rules="rules" size="large"> + <a-form-item label="岗位名称" field="postName"> + <a-input v-model="form.postName" placeholder="请输入岗位名称" /> + </a-form-item> + <a-form-item label="岗位排序" field="postSort"> + <a-input-number + v-model="form.postSort" + placeholder="请输入岗位排序" + :min="1" + mode="button" + /> + </a-form-item> + <a-form-item label="描述" field="description"> + <a-textarea + v-model="form.description" + :max-length="200" + placeholder="请输入描述" + :auto-size="{ + minRows: 3, + }" + show-word-limit + /> + </a-form-item> + </a-form> + </a-modal> + + <!-- 详情区域 --> + <a-drawer + title="岗位详情" + :visible="detailVisible" + :width="580" + :footer="false" + unmount-on-close + render-to-body + @cancel="handleDetailCancel" + > + <a-descriptions :column="2" bordered size="large" layout="vertical"> + <a-descriptions-item label="岗位名称"> + <a-skeleton v-if="detailLoading" :animation="true"> + <a-skeleton-line :rows="1" /> + </a-skeleton> + <span v-else>{{ post.postName }}</span> + </a-descriptions-item> + <a-descriptions-item label="状态"> + <a-skeleton v-if="detailLoading" :animation="true"> + <a-skeleton-line :rows="1" /> + </a-skeleton> + <span v-else> + <a-tag v-if="post.status === 1" color="green">启用</a-tag> + <a-tag v-else color="red">禁用</a-tag> + </span> + </a-descriptions-item> + <a-descriptions-item label="创建人"> + <a-skeleton v-if="detailLoading" :animation="true"> + <a-skeleton-line :rows="1" /> + </a-skeleton> + <span v-else>{{ post.createUserString }}</span> + </a-descriptions-item> + <a-descriptions-item label="创建时间"> + <a-skeleton v-if="detailLoading" :animation="true"> + <a-skeleton-line :rows="1" /> + </a-skeleton> + <span v-else>{{ post.createTime }}</span> + </a-descriptions-item> + <a-descriptions-item label="修改人"> + <a-skeleton v-if="detailLoading" :animation="true"> + <a-skeleton-line :rows="1" /> + </a-skeleton> + <span v-else>{{ post.updateUserString }}</span> + </a-descriptions-item> + <a-descriptions-item label="修改时间"> + <a-skeleton v-if="detailLoading" :animation="true"> + <a-skeleton-line :rows="1" /> + </a-skeleton> + <span v-else>{{ post.updateTime }}</span> + </a-descriptions-item> + <a-descriptions-item label="描述"> + <a-skeleton v-if="detailLoading" :animation="true"> + <a-skeleton-line :rows="1" /> + </a-skeleton> + <span v-else>{{ post.description }}</span> + </a-descriptions-item> + </a-descriptions> + </a-drawer> + </a-card> + </div> +</template> + +<script lang="ts" setup> + import { getCurrentInstance, ref, toRefs, reactive } from 'vue'; + import { SelectOptionData } from '@arco-design/web-vue'; + import { + PostRecord, + PostParam, + listPost, + getPost, + addPost, + updatePost, + deletePost, + } from '@/api/system/post'; + + const { proxy } = getCurrentInstance() as any; + + const postList = ref<PostRecord[]>([]); + const post = ref<PostRecord>({ + postName: '', + status: 1, + createUserString: '', + createTime: '', + updateUserString: '', + updateTime: '', + description: '', + }); + const total = ref(0); + const ids = ref<Array<number>>([]); + const title = ref(''); + const single = ref(true); + const multiple = ref(true); + const showQuery = ref(true); + const loading = ref(false); + const detailLoading = ref(false); + const exportLoading = ref(false); + const visible = ref(false); + const detailVisible = ref(false); + const statusOptions = ref<SelectOptionData[]>([ + { label: '启用', value: 1 }, + { label: '禁用', value: 2 }, + ]); + + const data = reactive({ + // 查询参数 + queryParams: { + postName: undefined, + status: undefined, + page: 1, + size: 10, + sort: ['createTime,desc'], + }, + // 表单数据 + form: {} as PostRecord, + // 表单验证规则 + rules: { + postName: [{ required: true, message: '请输入岗位名称' }], + postSort: [{ required: true, message: '请输入岗位排序' }], + }, + }); + const { queryParams, form, rules } = toRefs(data); + + /** + * 查询列表 + * + * @param params 查询参数 + */ + const getList = (params: PostParam = { ...queryParams.value }) => { + loading.value = true; + listPost(params) + .then((res) => { + postList.value = res.data.list; + total.value = res.data.total; + }) + .finally(() => { + loading.value = false; + }); + }; + getList(); + + /** + * 打开新增对话框 + */ + const toCreate = () => { + reset(); + title.value = '新增岗位'; + visible.value = true; + }; + + /** + * 打开修改对话框 + * + * @param id ID + */ + const toUpdate = (id: number) => { + reset(); + getPost(id).then((res) => { + form.value = res.data; + title.value = '修改岗位'; + visible.value = true; + }); + }; + + /** + * 重置表单 + */ + const reset = () => { + form.value = { + postId: undefined, + postName: '', + description: '', + postSort: 999, + status: 1, + }; + proxy.$refs.formRef?.resetFields(); + }; + + /** + * 取消 + */ + const handleCancel = () => { + visible.value = false; + proxy.$refs.formRef.resetFields(); + }; + + /** + * 确定 + */ + const handleOk = () => { + proxy.$refs.formRef.validate((valid: any) => { + if (!valid) { + if (form.value.postId !== undefined) { + updatePost(form.value).then((res) => { + handleCancel(); + getList(); + proxy.$message.success(res.msg); + }); + } else { + addPost(form.value).then((res) => { + handleCancel(); + getList(); + proxy.$message.success(res.msg); + }); + } + } + }); + }; + + /** + * 查看详情 + * + * @param id ID + */ + const toDetail = async (id: number) => { + if (detailLoading.value) return; + detailLoading.value = true; + detailVisible.value = true; + getPost(id) + .then((res) => { + post.value = res.data; + }) + .finally(() => { + detailLoading.value = false; + }); + }; + + /** + * 关闭详情 + */ + const handleDetailCancel = () => { + detailVisible.value = false; + }; + + /** + * 批量删除 + */ + const handleBatchDelete = () => { + if (ids.value.length === 0) { + proxy.$message.info('请选择要删除的数据'); + } else { + proxy.$modal.warning({ + title: '警告', + titleAlign: 'start', + content: '确定要删除当前选中的数据吗?', + hideCancel: false, + onOk: () => { + handleDelete(ids.value); + }, + }); + } + }; + + /** + * 删除 + * + * @param ids ID 列表 + */ + const handleDelete = (ids: Array<number>) => { + deletePost(ids).then((res) => { + proxy.$message.success(res.msg); + getList(); + }); + }; + + /** + * 已选择的数据行发生改变时触发 + * + * @param rowKeys ID 列表 + */ + const handleSelectionChange = (rowKeys: Array<any>) => { + ids.value = rowKeys; + single.value = rowKeys.length !== 1; + multiple.value = !rowKeys.length; + }; + + /** + * 导出 + */ + const handleExport = () => { + if (exportLoading.value) return; + exportLoading.value = true; + proxy + .download('/system/post/export', { ...queryParams.value }, '岗位数据') + .finally(() => { + exportLoading.value = false; + }); + }; + + /** + * 修改状态 + * + * @param record 记录信息 + */ + const handleChangeStatus = (record: PostRecord) => { + const tip = record.status === 1 ? '启用' : '禁用'; + updatePost(record) + .then(() => { + proxy.$message.success(`${tip}成功`); + }) + .catch(() => { + record.status = record.status === 1 ? 2 : 1; + }); + }; + + /** + * 查询 + */ + const handleQuery = () => { + getList(); + }; + + /** + * 重置 + */ + const resetQuery = () => { + proxy.$refs.queryRef.resetFields(); + handleQuery(); + }; + + /** + * 切换页码 + * + * @param current 页码 + */ + const handlePageChange = (current: number) => { + queryParams.value.page = current; + getList(); + }; + + /** + * 切换每页条数 + * + * @param pageSize 每页条数 + */ + const handlePageSizeChange = (pageSize: number) => { + queryParams.value.size = pageSize; + getList(); + }; +</script> + +<script lang="ts"> + export default { + name: 'Post', + }; +</script> + +<style scoped lang="less"></style> diff --git a/continew-admin-ui/src/views/system/post/locale/en-US.ts b/continew-admin-ui/src/views/system/post/locale/en-US.ts new file mode 100644 index 00000000..d984aca1 --- /dev/null +++ b/continew-admin-ui/src/views/system/post/locale/en-US.ts @@ -0,0 +1,3 @@ +export default { + 'menu.system.post.list': 'Post management', +}; diff --git a/continew-admin-ui/src/views/system/post/locale/zh-CN.ts b/continew-admin-ui/src/views/system/post/locale/zh-CN.ts new file mode 100644 index 00000000..c5702f99 --- /dev/null +++ b/continew-admin-ui/src/views/system/post/locale/zh-CN.ts @@ -0,0 +1,3 @@ +export default { + 'menu.system.post.list': '岗位管理', +}; diff --git a/continew-admin-ui/src/views/system/user/index.vue b/continew-admin-ui/src/views/system/user/index.vue index 0228f2bf..51c72faf 100644 --- a/continew-admin-ui/src/views/system/user/index.vue +++ b/continew-admin-ui/src/views/system/user/index.vue @@ -243,7 +243,7 @@ <a-modal :title="title" :visible="visible" - :width="580" + :width="565" :mask-closable="false" unmount-on-close render-to-body @@ -293,6 +293,29 @@ <a-radio :value="0" disabled>未知</a-radio> </a-radio-group> </a-form-item> + <a-form-item label="所属部门" field="deptId"> + <a-tree-select + v-model="form.deptId" + :data="deptOptions" + placeholder="请选择所属部门" + allow-clear + allow-search + :filter-tree-node="filterDeptOptions" + style="width: 416px" + /> + </a-form-item> + <a-form-item label="所属岗位" field="postIds"> + <a-select + v-model="form.postIds" + :options="postOptions" + placeholder="请选择所属岗位" + :loading="postLoading" + multiple + allow-clear + :allow-search="{ retainInputValue: true }" + style="width: 416px" + /> + </a-form-item> <a-form-item label="所属角色" field="roleIds"> <a-select v-model="form.roleIds" @@ -305,17 +328,6 @@ style="width: 416px" /> </a-form-item> - <a-form-item label="所属部门" field="deptId"> - <a-tree-select - v-model="form.deptId" - :data="deptOptions" - placeholder="请选择所属部门" - allow-clear - allow-search - :filter-tree-node="filterDeptOptions" - style="width: 416px" - /> - </a-form-item> <a-form-item label="描述" field="description"> <a-textarea v-model="form.description" @@ -367,7 +379,7 @@ render-to-body @cancel="handleDetailCancel" > - <a-descriptions title="基础信息" :column="2" bordered size="large"> + <a-descriptions :column="2" bordered size="large" layout="vertical"> <a-descriptions-item label="用户名"> <a-skeleton v-if="detailLoading" :animation="true"> <a-skeleton-line :rows="1" /> @@ -410,17 +422,29 @@ </a-skeleton> <span v-else>{{ user.phone || '无' }}</span> </a-descriptions-item> + <a-descriptions-item label="所属部门"> + <a-skeleton v-if="detailLoading" :animation="true"> + <a-skeleton-line :rows="1" /> + </a-skeleton> + <span v-else>{{ user.deptName }}</span> + </a-descriptions-item> + <a-descriptions-item label="所属岗位"> + <a-skeleton v-if="detailLoading" :animation="true"> + <a-skeleton-line :rows="1" /> + </a-skeleton> + <span v-else>{{ user.postNames }}</span> + </a-descriptions-item> <a-descriptions-item label="所属角色"> <a-skeleton v-if="detailLoading" :animation="true"> <a-skeleton-line :rows="1" /> </a-skeleton> <span v-else>{{ user.roleNames }}</span> </a-descriptions-item> - <a-descriptions-item label="所属部门"> + <a-descriptions-item label="最后一次修改密码时间"> <a-skeleton v-if="detailLoading" :animation="true"> <a-skeleton-line :rows="1" /> </a-skeleton> - <span v-else>{{ user.deptName }}</span> + <span v-else>{{ user.pwdResetTime }}</span> </a-descriptions-item> <a-descriptions-item label="创建人"> <a-skeleton v-if="detailLoading" :animation="true"> @@ -472,7 +496,12 @@ resetPassword, updateUserRole, } from '@/api/system/user'; - import { listRoleDict, listDeptTree } from '@/api/common'; + import { + LabelValueRecord, + listDeptTree, + listPostDict, + listRoleDict, + } from '@/api/common'; import getAvatar from '@/utils/avatar'; const { proxy } = getCurrentInstance() as any; @@ -485,6 +514,7 @@ email: undefined, phone: undefined, status: 1, + pwdResetTime: '', createUserString: '', createTime: '', updateUserString: '', @@ -509,10 +539,12 @@ { label: '启用', value: 1 }, { label: '禁用', value: 2 }, ]); - const roleLoading = ref(false); const deptLoading = ref(false); - const roleOptions = ref<TreeNodeData[]>([]); + const postLoading = ref(false); + const roleLoading = ref(false); const deptOptions = ref<TreeNodeData[]>([]); + const postOptions = ref<LabelValueRecord[]>([]); + const roleOptions = ref<LabelValueRecord[]>([]); const deptTree = ref<TreeNodeData[]>([]); const deptName = ref(''); @@ -580,8 +612,9 @@ */ const toCreate = () => { reset(); - getRoleOptions(); getDeptOptions(); + getPostOptions(); + getRoleOptions(); title.value = '新增用户'; visible.value = true; }; @@ -593,8 +626,9 @@ */ const toUpdate = (id: number) => { reset(); - getRoleOptions(); getDeptOptions(); + getPostOptions(); + getRoleOptions(); getUser(id).then((res) => { form.value = res.data; title.value = '修改用户'; @@ -616,20 +650,6 @@ }); }; - /** - * 查询角色列表 - */ - const getRoleOptions = () => { - roleLoading.value = true; - listRoleDict({}) - .then((res) => { - roleOptions.value = res.data; - }) - .finally(() => { - roleLoading.value = false; - }); - }; - /** * 查询部门列表 */ @@ -644,6 +664,34 @@ }); }; + /** + * 查询岗位列表 + */ + const getPostOptions = () => { + postLoading.value = true; + listPostDict({}) + .then((res) => { + postOptions.value = res.data; + }) + .finally(() => { + postLoading.value = false; + }); + }; + + /** + * 查询角色列表 + */ + const getRoleOptions = () => { + roleLoading.value = true; + listRoleDict({}) + .then((res) => { + roleOptions.value = res.data; + }) + .finally(() => { + roleLoading.value = false; + }); + }; + /** * 重置表单 */ @@ -657,8 +705,9 @@ phone: undefined, description: '', status: 1, - roleIds: [] as Array<number>, deptId: undefined, + postIds: [] as Array<number>, + roleIds: [] as Array<number>, }; proxy.$refs.formRef?.resetFields(); }; diff --git a/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/common/CommonController.java b/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/common/CommonController.java index 9dc26f72..5b255f06 100644 --- a/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/common/CommonController.java +++ b/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/common/CommonController.java @@ -36,12 +36,15 @@ import top.charles7c.cnadmin.common.model.vo.R; import top.charles7c.cnadmin.monitor.annotation.Log; import top.charles7c.cnadmin.system.model.query.DeptQuery; import top.charles7c.cnadmin.system.model.query.MenuQuery; +import top.charles7c.cnadmin.system.model.query.PostQuery; import top.charles7c.cnadmin.system.model.query.RoleQuery; import top.charles7c.cnadmin.system.model.vo.DeptVO; import top.charles7c.cnadmin.system.model.vo.MenuVO; +import top.charles7c.cnadmin.system.model.vo.PostVO; import top.charles7c.cnadmin.system.model.vo.RoleVO; import top.charles7c.cnadmin.system.service.DeptService; import top.charles7c.cnadmin.system.service.MenuService; +import top.charles7c.cnadmin.system.service.PostService; import top.charles7c.cnadmin.system.service.RoleService; /** @@ -51,6 +54,7 @@ import top.charles7c.cnadmin.system.service.RoleService; * @since 2023/1/22 21:48 */ @Tag(name = "公共 API") +@Log(ignore = true) @RestController @RequiredArgsConstructor @RequestMapping("/common") @@ -59,8 +63,8 @@ public class CommonController { private final DeptService deptService; private final MenuService menuService; private final RoleService roleService; + private final PostService postService; - @Log(ignore = true) @Operation(summary = "查询部门树", description = "查询树结构的部门列表") @GetMapping("/tree/dept") public R<List<Tree<Long>>> listDeptTree(@Validated DeptQuery query, @Validated SortQuery sortQuery) { @@ -69,7 +73,6 @@ public class CommonController { return R.ok(treeList); } - @Log(ignore = true) @Operation(summary = "查询菜单树", description = "查询树结构的菜单列表") @GetMapping("/tree/menu") public R<List<Tree<Long>>> listMenuTree(@Validated MenuQuery query, @Validated SortQuery sortQuery) { @@ -78,7 +81,6 @@ public class CommonController { return R.ok(treeList); } - @Log(ignore = true) @Operation(summary = "查询角色字典", description = "查询角色字典列表") @GetMapping("/dict/role") public R<List<LabelValueVO<Long>>> listRoleDict(@Validated RoleQuery query, @Validated SortQuery sortQuery) { @@ -86,4 +88,12 @@ public class CommonController { List<LabelValueVO<Long>> dictList = roleService.buildDict(list); return R.ok(dictList); } + + @Operation(summary = "查询岗位字典", description = "查询岗位字典列表") + @GetMapping("/dict/post") + public R<List<LabelValueVO<Long>>> listPostDict(@Validated PostQuery query, @Validated SortQuery sortQuery) { + List<PostVO> list = postService.list(query, sortQuery); + List<LabelValueVO<Long>> dictList = postService.buildDict(list); + return R.ok(dictList); + } } diff --git a/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/system/PostController.java b/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/system/PostController.java new file mode 100644 index 00000000..f984a66c --- /dev/null +++ b/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/system/PostController.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.webapi.controller.system; + +import io.swagger.v3.oas.annotations.tags.Tag; + +import org.springframework.web.bind.annotation.RestController; + +import top.charles7c.cnadmin.common.annotation.CrudRequestMapping; +import top.charles7c.cnadmin.common.base.BaseController; +import top.charles7c.cnadmin.system.model.query.PostQuery; +import top.charles7c.cnadmin.system.model.request.PostRequest; +import top.charles7c.cnadmin.system.model.vo.PostDetailVO; +import top.charles7c.cnadmin.system.model.vo.PostVO; +import top.charles7c.cnadmin.system.service.PostService; + +/** + * 岗位管理 API + * + * @author Charles7c + * @since 2023/2/25 22:54 + */ +@Tag(name = "岗位管理 API") +@RestController +@CrudRequestMapping("/system/post") +public class PostController extends BaseController<PostService, PostVO, PostDetailVO, PostQuery, PostRequest> {} diff --git a/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_data.sql b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_data.sql index 5007c27b..9a9decc2 100644 --- a/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_data.sql +++ b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_data.sql @@ -3,21 +3,33 @@ -- changeset Charles7c:1 -- 初始化默认菜单 INSERT IGNORE INTO `sys_menu` VALUES (1000, '系统管理', 0, 1, 'system', NULL, NULL, 'settings', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1010, '角色管理', 1000, 2, '/system/role', 'Role', 'system/role/index', NULL, b'0', b'0', b'0', 'system:role:list', 2, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1011, '角色新增', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:create', 1, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1012, '角色修改', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:update', 2, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1013, '角色删除', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:delete', 3, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1014, '角色导出', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:export', 4, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1010, '用户管理', 1000, 2, '/system/user', 'User', '/system/user/index', NULL, b'0', b'0', b'0', 'system:user:list', 1, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1011, '用户新增', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:create', 1, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1012, '用户修改', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:update', 2, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1013, '用户删除', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:delete', 3, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1014, '用户导出', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:export', 4, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1015, '重置密码', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:password:reset', 5, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1016, '分配角色', 1010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:user:role:update', 6, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1020, '角色管理', 1000, 2, '/system/role', 'Role', 'system/role/index', NULL, b'0', b'0', b'0', 'system:role:list', 2, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1021, '角色新增', 1020, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:create', 1, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1022, '角色修改', 1020, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:update', 2, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1023, '角色删除', 1020, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:delete', 3, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1024, '角色导出', 1020, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:role:export', 4, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_menu` VALUES (1030, '菜单管理', 1000, 2, '/system/menu', 'Menu', 'system/menu/index', NULL, b'0', b'0', b'0', 'system:menu:list', 3, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_menu` VALUES (1031, '菜单新增', 1030, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:menu:create', 1, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_menu` VALUES (1032, '菜单修改', 1030, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:menu:update', 2, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_menu` VALUES (1033, '菜单删除', 1030, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:menu:delete', 3, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_menu` VALUES (1034, '菜单导出', 1030, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:menu:export', 4, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1050, '部门管理', 1000, 2, '/system/dept', 'Dept', 'system/dept/index', NULL, b'0', b'0', b'0', 'system:dept:list', 4, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1051, '部门新增', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:create', 1, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1052, '部门修改', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:update', 2, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1053, '部门删除', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:delete', 3, 1, 1, NOW(), 1, NOW()); -INSERT IGNORE INTO `sys_menu` VALUES (1054, '部门导出', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:export', 4, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1040, '部门管理', 1000, 2, '/system/dept', 'Dept', 'system/dept/index', NULL, b'0', b'0', b'0', 'system:dept:list', 4, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1041, '部门新增', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:create', 1, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1042, '部门修改', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:update', 2, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1043, '部门删除', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:delete', 3, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1044, '部门导出', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dept:export', 4, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1050, '岗位管理', 1000, 2, '/system/post', 'Post', '/system/post/index', NULL, b'0', b'0', b'0', 'system:post:list', 5, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1051, '岗位新增', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:post:create', 1, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1052, '岗位修改', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:post:update', 2, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1053, '岗位删除', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:post:delete', 3, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_menu` VALUES (1054, '岗位导出', 1050, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:post:export', 4, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_menu` VALUES (2000, '系统监控', 0, 1, 'monitor', NULL, NULL, 'computer', b'0', b'0', b'0', NULL, 2, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_menu` VALUES (2010, '在线用户', 2000, 2, '/monitor/online', 'OnlineUser', 'monitor/online/index', NULL, b'0', b'0', b'0', 'monitor:online:user:list', 1, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_menu` VALUES (2011, '强退用户', 2010, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'monitor:online:user:delete', 1, 1, 1, NOW(), 1, NOW()); @@ -37,6 +49,18 @@ INSERT IGNORE INTO `sys_dept` VALUES (6, '运维部', 2, '系统初始部门', 4 INSERT IGNORE INTO `sys_dept` VALUES (7, '研发一组', 3, '系统初始部门', 1, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_dept` VALUES (8, '研发二组', 3, '系统初始部门', 2, 2, 1, NOW(), 1, NOW()); +-- 初始化默认岗位 +INSERT IGNORE INTO `sys_post` VALUES (1, '项目总监', '系统初始岗位', 1, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_post` VALUES (2, '技术总监', '系统初始岗位', 2, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_post` VALUES (3, '销售经理', '系统初始岗位', 3, 2, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_post` VALUES (4, '项目经理', '系统初始岗位', 4, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_post` VALUES (5, '产品经理', '系统初始岗位', 5, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_post` VALUES (6, '技术经理', '系统初始岗位', 6, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_post` VALUES (7, '测试经理', '系统初始岗位', 7, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_post` VALUES (8, '销售专员', '系统初始岗位', 8, 2, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_post` VALUES (9, '软件开发', '系统初始岗位', 9, 1, 1, NOW(), 1, NOW()); +INSERT IGNORE INTO `sys_post` VALUES (10, '软件测试', '系统初始岗位', 10, 1, 1, NOW(), 1, NOW()); + -- 初始化默认角色 INSERT IGNORE INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, '系统初始角色', 1, 1, 1, NOW(), 1, NOW()); INSERT IGNORE INTO `sys_role` VALUES (2, '测试人员', 'test', 5, '系统初始角色', 2, 2, 1, NOW(), 1, NOW()); @@ -68,4 +92,8 @@ INSERT IGNORE INTO `sys_role_dept` VALUES (2, 5); -- 初始化默认用户和角色关联数据 INSERT IGNORE INTO `sys_user_role` VALUES (1, 1); -INSERT IGNORE INTO `sys_user_role` VALUES (2, 2); \ No newline at end of file +INSERT IGNORE INTO `sys_user_role` VALUES (2, 2); + +-- 初始化默认用户和岗位关联数据 +INSERT IGNORE INTO `sys_user_post` VALUES (1, 1); +INSERT IGNORE INTO `sys_user_post` VALUES (2, 10); \ No newline at end of file diff --git a/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_table.sql b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_table.sql index 2a987cee..6e091b44 100644 --- a/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_table.sql +++ b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_table.sql @@ -72,6 +72,21 @@ CREATE TABLE IF NOT EXISTS `sys_role_dept` ( PRIMARY KEY (`role_id`,`dept_id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色和部门关联表'; +CREATE TABLE IF NOT EXISTS `sys_post` ( + `post_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '岗位ID', + `post_name` varchar(255) NOT NULL COMMENT '岗位名称', + `description` varchar(512) DEFAULT NULL COMMENT '描述', + `post_sort` int(11) unsigned DEFAULT 999 COMMENT '岗位排序', + `status` tinyint(1) unsigned DEFAULT 1 COMMENT '状态(1启用 2禁用)', + `create_user` bigint(20) unsigned NOT NULL COMMENT '创建人', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_user` bigint(20) unsigned NOT NULL COMMENT '修改人', + `update_time` datetime NOT NULL COMMENT '修改时间', + PRIMARY KEY (`post_id`) USING BTREE, + INDEX `idx_create_user`(`create_user`) USING BTREE, + INDEX `idx_update_user`(`update_user`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='岗位表'; + CREATE TABLE IF NOT EXISTS `sys_user` ( `user_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '用户ID', `username` varchar(255) NOT NULL COMMENT '用户名', @@ -83,7 +98,7 @@ CREATE TABLE IF NOT EXISTS `sys_user` ( `avatar` varchar(255) DEFAULT NULL COMMENT '头像地址', `description` varchar(512) DEFAULT NULL COMMENT '描述', `status` tinyint(1) unsigned DEFAULT 1 COMMENT '状态(1启用 2禁用)', - `pwd_reset_time` datetime DEFAULT NULL COMMENT '最后一次修改密码的时间', + `pwd_reset_time` datetime DEFAULT NULL COMMENT '最后一次修改密码时间', `dept_id` bigint(20) unsigned DEFAULT NULL COMMENT '部门ID', `create_user` bigint(20) unsigned NOT NULL COMMENT '创建人', `create_time` datetime NOT NULL COMMENT '创建时间', @@ -103,6 +118,12 @@ CREATE TABLE IF NOT EXISTS `sys_user_role` ( PRIMARY KEY (`user_id`,`role_id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户和角色关联表'; +CREATE TABLE IF NOT EXISTS `sys_user_post` ( + `user_id` bigint(20) unsigned NOT NULL COMMENT '用户ID', + `post_id` bigint(20) unsigned NOT NULL COMMENT '岗位ID', + PRIMARY KEY (`user_id`,`post_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户和岗位关联表'; + CREATE TABLE IF NOT EXISTS `sys_log` ( `log_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '日志ID', `description` varchar(255) NOT NULL COMMENT '日志描述',