feat(qms): 检测项类别增加祖先节点和父节点功能,改为树形结构

- 在 QcInspectionItemCategory 模型中添加 parentId 和 ancestors 字段
- 更新相关 BO、VO 类以及 Mapper XML
- 修改服务层逻辑,支持祖先节点的自动填充
- 优化删除功能,增加子节点存在性检查
- 移除页面上的导出模板按钮
master
zch 2 days ago
parent 155014c9b6
commit a86686f752

@ -1,8 +1,7 @@
package org.dromara.qms.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.ArrayList;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
@ -21,14 +20,13 @@ import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.qms.domain.vo.QcInspectionItemCategoryVo;
import org.dromara.qms.domain.bo.QcInspectionItemCategoryBo;
import org.dromara.qms.service.IQcInspectionItemCategoryService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
* 访:/qms/qcInspectionItemCategory
*
* @author zch
* @date 2025-07-14
* @date 2025-07-17
*/
@Validated
@RequiredArgsConstructor
@ -43,8 +41,9 @@ public class QcInspectionItemCategoryController extends BaseController {
*/
@SaCheckPermission("qms:qcInspectionItemCategory:list")
@GetMapping("/list")
public TableDataInfo<QcInspectionItemCategoryVo> list(QcInspectionItemCategoryBo bo, PageQuery pageQuery) {
return qcInspectionItemCategoryService.queryPageList(bo, pageQuery);
public R<List<QcInspectionItemCategoryVo>> list(QcInspectionItemCategoryBo bo) {
List<QcInspectionItemCategoryVo> list = qcInspectionItemCategoryService.queryList(bo);
return R.ok(list);
}
/**
@ -69,6 +68,7 @@ public class QcInspectionItemCategoryController extends BaseController {
ExcelUtil.exportExcel(list, "检测项类别", QcInspectionItemCategoryVo.class, response);
}
/**
*
*

@ -11,7 +11,7 @@ import java.io.Serial;
* qc_inspection_item_category
*
* @author zch
* @date 2025-07-14
* @date 2025-07-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ -24,9 +24,18 @@ public class QcInspectionItemCategory extends TenantEntity {
/**
*
*/
@TableId(value = "category_id", type = IdType.ASSIGN_ID)
private Long categoryId;
/**
* ID
*/
private Long parentId;
/**
*
*/
private String ancestors;
/**
*
*/

@ -13,7 +13,7 @@ import jakarta.validation.constraints.*;
* qc_inspection_item_category
*
* @author zch
* @date 2025-07-14
* @date 2025-07-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ -26,6 +26,17 @@ public class QcInspectionItemCategoryBo extends BaseEntity {
// @NotNull(message = "检测项类别主键不能为空", groups = { AddGroup.class, EditGroup.class })
private Long categoryId;
/**
* ID
*/
@NotNull(message = "父级不能为空", groups = { AddGroup.class, EditGroup.class })
private Long parentId;
/**
*
*/
private String ancestors;
/**
*
*/

@ -1,6 +1,5 @@
package org.dromara.qms.domain.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import org.dromara.qms.domain.QcInspectionItemCategory;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
@ -19,7 +18,7 @@ import java.util.Date;
* qc_inspection_item_category
*
* @author zch
* @date 2025-07-14
* @date 2025-07-17
*/
@Data
@ExcelIgnoreUnannotated
@ -35,6 +34,18 @@ public class QcInspectionItemCategoryVo implements Serializable {
@ExcelProperty(value = "检测项类别主键")
private Long categoryId;
/**
* ID
*/
// @ExcelProperty(value = "父级ID")
private Long parentId;
/**
*
*/
// @ExcelProperty(value = "祖级列表")
private String ancestors;
/**
*
*/

@ -1,10 +1,9 @@
package org.dromara.qms.service.impl;
import org.apache.commons.lang3.ObjectUtils;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -25,7 +24,7 @@ import java.util.Collection;
* Service
*
* @author zch
* @date 2025-07-14
* @date 2025-07-17
*/
@RequiredArgsConstructor
@Service
@ -44,19 +43,6 @@ public class QcInspectionItemCategoryServiceImpl implements IQcInspectionItemCat
return baseMapper.selectVoById(categoryId);
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<QcInspectionItemCategoryVo> queryPageList(QcInspectionItemCategoryBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<QcInspectionItemCategory> lqw = buildQueryWrapper(bo);
Page<QcInspectionItemCategoryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
@ -80,6 +66,8 @@ public class QcInspectionItemCategoryServiceImpl implements IQcInspectionItemCat
.leftJoin(QcInspectionType.class, QcInspectionType::getTypeId, QcInspectionItemCategory::getTypeId)
.eq(bo.getCategoryId() != null, QcInspectionItemCategory::getCategoryId, bo.getCategoryId())
.eq(bo.getParentId() != null, QcInspectionItemCategory::getParentId, bo.getParentId())
.eq(StringUtils.isNotBlank(bo.getAncestors()), QcInspectionItemCategory::getAncestors, bo.getAncestors())
.eq(StringUtils.isNotBlank(bo.getCategoryCode()), QcInspectionItemCategory::getCategoryCode, bo.getCategoryCode())
.like(StringUtils.isNotBlank(bo.getCategoryName()), QcInspectionItemCategory::getCategoryName, bo.getCategoryName())
.eq(bo.getTypeId() != null, QcInspectionItemCategory::getTypeId, bo.getTypeId())
@ -98,6 +86,18 @@ public class QcInspectionItemCategoryServiceImpl implements IQcInspectionItemCat
public Boolean insertByBo(QcInspectionItemCategoryBo bo) {
QcInspectionItemCategory add = MapstructUtils.convert(bo, QcInspectionItemCategory.class);
validEntityBeforeSave(add);
// 获取父节点信息
QcInspectionItemCategoryVo query = baseMapper.selectVoById(bo.getParentId());
if (ObjectUtils.isNotEmpty(query)) {
//若父节点不为空则将父节点的ancestors拼接父节点id拼接成ancestors
add.setAncestors(query.getAncestors() + "," + bo.getParentId());
}else{
//若父节点为空则ancestors仅有父节点id
add.setAncestors(bo.getParentId().toString());
}
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setCategoryId(add.getCategoryId());
@ -136,7 +136,17 @@ public class QcInspectionItemCategoryServiceImpl implements IQcInspectionItemCat
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
for (Long id : ids) {
// 判断是否存在子节点
QcInspectionItemCategory query = new QcInspectionItemCategory();
query.setParentId(id);
if (baseMapper.selectCount(Wrappers.lambdaQuery(query)) > 0) {
throw new ServiceException("存在子节点,不允许删除");
}
}
}
return baseMapper.deleteByIds(ids) > 0;
}
}

@ -7,6 +7,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="QcInspectionItemCategory" id="QcInspectionItemCategoryResult">
<result property="categoryId" column="category_id" />
<result property="tenantId" column="tenant_id" />
<result property="parentId" column="parent_id" />
<result property="ancestors" column="ancestors" />
<result property="categoryCode" column="category_code" />
<result property="categoryName" column="category_name" />
<result property="typeId" column="type_id" />
@ -20,7 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectQcInspectionItemCategoryVo">
select category_id, tenant_id, category_code, category_name, type_id, description, create_by, create_dept, create_time, update_by, update_time, del_flag
select category_id, tenant_id, parent_id, ancestors, category_code, category_name, type_id, description, create_by, create_dept, create_time, update_by, update_time, del_flag
from qc_inspection_item_category
</sql>
@ -28,6 +30,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectQcInspectionItemCategoryVo"/>
<where>
<if test="categoryId != null "> and category_id = #{categoryId}</if>
<if test="parentId != null "> and parent_id = #{parentId}</if>
<if test="ancestors != null and ancestors != ''"> and ancestors = #{ancestors}</if>
<if test="categoryCode != null and categoryCode != ''"> and category_code = #{categoryCode}</if>
<if test="categoryName != null and categoryName != ''"> and category_name like concat('%', #{categoryName}, '%')</if>
<if test="typeId != null "> and type_id = #{typeId}</if>

@ -3,7 +3,7 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width='100px'>
<el-form ref="queryFormRef" :model="queryParams" :inline="true" >
#foreach($column in $columns)
#if($column.query)
#set($dictType=$column.dictType)
@ -78,11 +78,6 @@
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExportTemplate" v-hasPermi="['${moduleName}:${businessName}:export']">导出模板</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" :columns="columns" :search="true" @queryTable="getList"></right-toolbar>
</el-row>
</template>
@ -471,13 +466,6 @@ const handleExport = () => {
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
}
/** 导出模板按钮操作 */
const handleExportTemplate = () => {
proxy?.download('${moduleName}/${businessName}/exportTemplate', {
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
}
onMounted(() => {
getList();
});

Loading…
Cancel
Save