From 922b28126b5ffc4bb88a3e861930b1ac227d5fa7 Mon Sep 17 00:00:00 2001 From: Charles7c Date: Tue, 24 Jan 2023 01:14:48 +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/=E9=83=A8=E9=97=A8?= =?UTF-8?q?=E7=AE=A1=E7=90=86/=E6=96=B0=E5=A2=9E=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnadmin/common/util/TreeUtils.java | 65 +++ .../model/request/CreateDeptRequest.java | 65 +++ .../cnadmin/system/service/DeptService.java | 43 ++ .../system/service/impl/DeptServiceImpl.java | 71 +++- continew-admin-ui/src/api/common/index.ts | 13 + continew-admin-ui/src/api/system/dept.ts | 20 +- .../views/list/search-table/locale/en-US.ts | 3 + .../views/list/search-table/locale/zh-CN.ts | 5 +- .../src/views/system/dept/index.vue | 402 +++++++++++++++++- .../controller/common/CommonController.java | 61 +++ .../controller/system/DeptController.java | 20 +- 11 files changed, 721 insertions(+), 47 deletions(-) create mode 100644 continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/TreeUtils.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/CreateDeptRequest.java create mode 100644 continew-admin-ui/src/api/common/index.ts create mode 100644 continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/common/CommonController.java diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/TreeUtils.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/TreeUtils.java new file mode 100644 index 00000000..225f6250 --- /dev/null +++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/TreeUtils.java @@ -0,0 +1,65 @@ +/* + * 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.common.util; + +import java.util.ArrayList; +import java.util.List; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.lang.tree.TreeNodeConfig; +import cn.hutool.core.lang.tree.TreeUtil; +import cn.hutool.core.lang.tree.parser.NodeParser; +import cn.hutool.core.util.ReflectUtil; + +/** + * 树工具类 + * + * @author Charles7c + * @since 2023/1/22 22:11 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class TreeUtils { + + /** 默认属性配置对象(根据前端树结构灵活调整名称) */ + private static final TreeNodeConfig DEFAULT_CONFIG = + TreeNodeConfig.DEFAULT_CONFIG.setNameKey("title").setIdKey("key").setWeightKey("sort"); + + /** + * 树构建 + * + * @param + * 转换的实体 为数据源里的对象类型 + * @param + * ID类型 + * @param list + * 源数据集合 + * @param nodeParser + * 转换器 + * @return List + */ + public static List> build(List list, NodeParser nodeParser) { + if (CollUtil.isEmpty(list)) { + return new ArrayList<>(); + } + E parentId = (E)ReflectUtil.getFieldValue(list.get(0), DEFAULT_CONFIG.getParentIdKey()); + return TreeUtil.build(list, parentId, DEFAULT_CONFIG, nodeParser); + } +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/CreateDeptRequest.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/CreateDeptRequest.java new file mode 100644 index 00000000..a055ab02 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/CreateDeptRequest.java @@ -0,0 +1,65 @@ +/* + * 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 java.io.Serializable; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * 创建部门信息 + * + * @author Charles7c + * @since 2023/1/24 00:21 + */ +@Data +@Schema(description = "创建部门信息") +public class CreateDeptRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 上级部门 ID + */ + @Schema(description = "上级部门 ID", defaultValue = "0") + private Long parentId = 0L; + + /** + * 部门名称 + */ + @Schema(description = "部门名称") + @NotBlank(message = "部门名称不能为空") + private String deptName; + + /** + * 部门排序 + */ + @Schema(description = "部门排序", defaultValue = "999") + private Integer deptSort = 999; + + /** + * 描述 + */ + @Schema(description = "描述") + @Size(max = 200, message = "描述长度不能超过 200 个字符") + private String description; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/DeptService.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/DeptService.java index 6871b13e..9116ce94 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/DeptService.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/DeptService.java @@ -18,7 +18,10 @@ package top.charles7c.cnadmin.system.service; import java.util.List; +import cn.hutool.core.lang.tree.Tree; + import top.charles7c.cnadmin.system.model.query.DeptQuery; +import top.charles7c.cnadmin.system.model.request.CreateDeptRequest; import top.charles7c.cnadmin.system.model.vo.DeptVO; /** @@ -37,4 +40,44 @@ public interface DeptService { * @return 列表数据 */ List list(DeptQuery query); + + /** + * 构建树 + * + * @param list + * 原始列表数据 + * @return 树列表 + */ + List buildListTree(List list); + + /** + * 构建树 + * + * @param list + * 原始列表数据 + * @return 树列表 + */ + List> buildTree(List list); + + /** + * 新增 + * + * @param request + * 创建信息 + * @return 新增记录 ID + */ + Long create(CreateDeptRequest request); + + /** + * 检查部门名称是否存在 + * + * @param deptName + * 部门名称 + * @param parentId + * 上级部门 ID + * @param deptId + * 部门 ID + * @return 是否存在 + */ + boolean checkDeptNameExist(String deptName, Long parentId, Long deptId); } diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/DeptServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/DeptServiceImpl.java index 2a0e0397..793af09e 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/DeptServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/DeptServiceImpl.java @@ -24,17 +24,23 @@ import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.tree.Tree; +import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; import top.charles7c.cnadmin.common.util.ExceptionUtils; +import top.charles7c.cnadmin.common.util.TreeUtils; import top.charles7c.cnadmin.common.util.helper.QueryHelper; import top.charles7c.cnadmin.system.mapper.DeptMapper; import top.charles7c.cnadmin.system.model.entity.SysDept; import top.charles7c.cnadmin.system.model.query.DeptQuery; +import top.charles7c.cnadmin.system.model.request.CreateDeptRequest; import top.charles7c.cnadmin.system.model.vo.DeptVO; import top.charles7c.cnadmin.system.service.DeptService; import top.charles7c.cnadmin.system.service.UserService; @@ -60,31 +66,11 @@ public class DeptServiceImpl implements DeptService { List list = deptMapper.selectList(queryWrapper); List voList = BeanUtil.copyToList(list, DeptVO.class); voList.forEach(this::fill); - return buildTree(voList); + return voList; } - /** - * 填充数据 - * - * @param vo - * VO - */ - private void fill(DeptVO vo) { - Long updateUser = vo.getUpdateUser(); - if (updateUser == null) { - return; - } - vo.setUpdateUserString(ExceptionUtils.exToNull(() -> userService.getById(vo.getUpdateUser())).getNickname()); - } - - /** - * 构建树 - * - * @param list - * 原始列表数据 - * @return 树列表 - */ - private List buildTree(List list) { + @Override + public List buildListTree(List list) { if (CollUtil.isEmpty(list)) { return new ArrayList<>(); } @@ -134,4 +120,43 @@ public class DeptServiceImpl implements DeptService { return list.stream().filter(d -> Objects.equals(d.getParentId(), dept.getDeptId())) .map(d -> d.setChildren(this.getChildren(d, list))).collect(Collectors.toList()); } + + @Override + public List> buildTree(List list) { + return TreeUtils.build(list, (dept, tree) -> { + tree.setId(dept.getDeptId()); + tree.setName(dept.getDeptName()); + tree.setParentId(dept.getParentId()); + tree.setWeight(dept.getDeptSort()); + }); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long create(CreateDeptRequest request) { + SysDept sysDept = BeanUtil.copyProperties(request, SysDept.class); + sysDept.setStatus(DisEnableStatusEnum.ENABLE); + deptMapper.insert(sysDept); + return sysDept.getDeptId(); + } + + @Override + public boolean checkDeptNameExist(String deptName, Long parentId, Long deptId) { + return deptMapper.exists(Wrappers.lambdaQuery().eq(SysDept::getDeptName, deptName) + .eq(SysDept::getParentId, parentId).ne(deptId != null, SysDept::getDeptId, deptId)); + } + + /** + * 填充数据 + * + * @param vo + * VO + */ + private void fill(DeptVO vo) { + Long updateUser = vo.getUpdateUser(); + if (updateUser == null) { + return; + } + vo.setUpdateUserString(ExceptionUtils.exToNull(() -> userService.getById(vo.getUpdateUser())).getNickname()); + } } diff --git a/continew-admin-ui/src/api/common/index.ts b/continew-admin-ui/src/api/common/index.ts new file mode 100644 index 00000000..b0365b6e --- /dev/null +++ b/continew-admin-ui/src/api/common/index.ts @@ -0,0 +1,13 @@ +import axios from 'axios'; +import qs from 'query-string'; +import { DeptParams } from '@/api/system/dept'; +import { TreeNodeData } from '@arco-design/web-vue'; + +export default function getDeptTree(params: DeptParams) { + return axios.get('/common/tree/dept', { + params, + paramsSerializer: (obj) => { + return qs.stringify(obj); + }, + }); +} \ No newline at end of file diff --git a/continew-admin-ui/src/api/system/dept.ts b/continew-admin-ui/src/api/system/dept.ts index 45d9e659..0d21ef6d 100644 --- a/continew-admin-ui/src/api/system/dept.ts +++ b/continew-admin-ui/src/api/system/dept.ts @@ -1,11 +1,10 @@ import axios from 'axios'; - import qs from 'query-string'; export interface DeptRecord { deptId: string; deptName: string; - parentId: string; + parentId: number; deptSort: number; description: string; status: number; @@ -14,10 +13,9 @@ export interface DeptRecord { children: Array, } -export interface DeptParams extends Partial { - page: number; - size: number; - sort: Array; +export interface DeptParams { + deptName?: string; + status?: number; } export function getDeptList(params: DeptParams) { @@ -27,4 +25,14 @@ export function getDeptList(params: DeptParams) { return qs.stringify(obj); }, }); +} + +export interface CreateDeptReq { + parentId: number; + deptName: string; + deptSort: number; + description: string; +} +export function createDept(req: CreateDeptReq) { + return axios.post('/system/dept', req); } \ No newline at end of file diff --git a/continew-admin-ui/src/views/list/search-table/locale/en-US.ts b/continew-admin-ui/src/views/list/search-table/locale/en-US.ts index c5ac3326..666bc8b7 100644 --- a/continew-admin-ui/src/views/list/search-table/locale/en-US.ts +++ b/continew-admin-ui/src/views/list/search-table/locale/en-US.ts @@ -19,6 +19,9 @@ export default { 'searchTable.form.reset': 'Reset', 'searchTable.form.selectDefault': 'All', 'searchTable.operation.create': 'Create', + 'searchTable.operation.update': 'Update', + 'searchTable.operation.delete': 'Delete', + 'searchTable.operation.export': 'Export', 'searchTable.operation.import': 'Import', 'searchTable.operation.download': 'Download', // columns diff --git a/continew-admin-ui/src/views/list/search-table/locale/zh-CN.ts b/continew-admin-ui/src/views/list/search-table/locale/zh-CN.ts index ca4cd442..ef4e8533 100644 --- a/continew-admin-ui/src/views/list/search-table/locale/zh-CN.ts +++ b/continew-admin-ui/src/views/list/search-table/locale/zh-CN.ts @@ -18,7 +18,10 @@ export default { 'searchTable.form.search': '查询', 'searchTable.form.reset': '重置', 'searchTable.form.selectDefault': '全部', - 'searchTable.operation.create': '新建', + 'searchTable.operation.create': '新增', + 'searchTable.operation.update': '修改', + 'searchTable.operation.delete': '删除', + 'searchTable.operation.export': '导出', 'searchTable.operation.import': '批量导入', 'searchTable.operation.download': '下载', // columns diff --git a/continew-admin-ui/src/views/system/dept/index.vue b/continew-admin-ui/src/views/system/dept/index.vue index d9dafc09..81f3139a 100644 --- a/continew-admin-ui/src/views/system/dept/index.vue +++ b/continew-admin-ui/src/views/system/dept/index.vue @@ -12,17 +12,17 @@ v-model="queryFormData.deptName" placeholder="输入部门名称搜索" allow-clear - style="width: 150px;" + style="width: 150px" @press-enter="toQuery" /> @@ -40,24 +40,230 @@ + + + + + + + {{ $t('searchTable.operation.create') }} + + + + {{ $t('searchTable.operation.update') }} + + + + {{ $t('searchTable.operation.delete') }} + + + + + + + {{ $t('searchTable.operation.export') }} + + +
+ +
+
+ + +
+
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + @@ -65,19 +271,47 @@