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

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

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

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

@ -13,7 +13,7 @@ import jakarta.validation.constraints.*;
* qc_inspection_item_category * qc_inspection_item_category
* *
* @author zch * @author zch
* @date 2025-07-14 * @date 2025-07-17
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ -26,6 +26,17 @@ public class QcInspectionItemCategoryBo extends BaseEntity {
// @NotNull(message = "检测项类别主键不能为空", groups = { AddGroup.class, EditGroup.class }) // @NotNull(message = "检测项类别主键不能为空", groups = { AddGroup.class, EditGroup.class })
private Long categoryId; 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; package org.dromara.qms.domain.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import org.dromara.qms.domain.QcInspectionItemCategory; import org.dromara.qms.domain.QcInspectionItemCategory;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
@ -19,7 +18,7 @@ import java.util.Date;
* qc_inspection_item_category * qc_inspection_item_category
* *
* @author zch * @author zch
* @date 2025-07-14 * @date 2025-07-17
*/ */
@Data @Data
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
@ -35,6 +34,18 @@ public class QcInspectionItemCategoryVo implements Serializable {
@ExcelProperty(value = "检测项类别主键") @ExcelProperty(value = "检测项类别主键")
private Long categoryId; 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; 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.MapstructUtils;
import org.dromara.common.core.utils.StringUtils; 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.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -25,7 +24,7 @@ import java.util.Collection;
* Service * Service
* *
* @author zch * @author zch
* @date 2025-07-14 * @date 2025-07-17
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
@ -44,19 +43,6 @@ public class QcInspectionItemCategoryServiceImpl implements IQcInspectionItemCat
return baseMapper.selectVoById(categoryId); 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) .leftJoin(QcInspectionType.class, QcInspectionType::getTypeId, QcInspectionItemCategory::getTypeId)
.eq(bo.getCategoryId() != null, QcInspectionItemCategory::getCategoryId, bo.getCategoryId()) .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()) .eq(StringUtils.isNotBlank(bo.getCategoryCode()), QcInspectionItemCategory::getCategoryCode, bo.getCategoryCode())
.like(StringUtils.isNotBlank(bo.getCategoryName()), QcInspectionItemCategory::getCategoryName, bo.getCategoryName()) .like(StringUtils.isNotBlank(bo.getCategoryName()), QcInspectionItemCategory::getCategoryName, bo.getCategoryName())
.eq(bo.getTypeId() != null, QcInspectionItemCategory::getTypeId, bo.getTypeId()) .eq(bo.getTypeId() != null, QcInspectionItemCategory::getTypeId, bo.getTypeId())
@ -98,6 +86,18 @@ public class QcInspectionItemCategoryServiceImpl implements IQcInspectionItemCat
public Boolean insertByBo(QcInspectionItemCategoryBo bo) { public Boolean insertByBo(QcInspectionItemCategoryBo bo) {
QcInspectionItemCategory add = MapstructUtils.convert(bo, QcInspectionItemCategory.class); QcInspectionItemCategory add = MapstructUtils.convert(bo, QcInspectionItemCategory.class);
validEntityBeforeSave(add); 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; boolean flag = baseMapper.insert(add) > 0;
if (flag) { if (flag) {
bo.setCategoryId(add.getCategoryId()); bo.setCategoryId(add.getCategoryId());
@ -136,7 +136,17 @@ public class QcInspectionItemCategoryServiceImpl implements IQcInspectionItemCat
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){ if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验 //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; return baseMapper.deleteByIds(ids) > 0;
} }
} }

@ -7,6 +7,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="QcInspectionItemCategory" id="QcInspectionItemCategoryResult"> <resultMap type="QcInspectionItemCategory" id="QcInspectionItemCategoryResult">
<result property="categoryId" column="category_id" /> <result property="categoryId" column="category_id" />
<result property="tenantId" column="tenant_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="categoryCode" column="category_code" />
<result property="categoryName" column="category_name" /> <result property="categoryName" column="category_name" />
<result property="typeId" column="type_id" /> <result property="typeId" column="type_id" />
@ -20,7 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap> </resultMap>
<sql id="selectQcInspectionItemCategoryVo"> <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 from qc_inspection_item_category
</sql> </sql>
@ -28,6 +30,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectQcInspectionItemCategoryVo"/> <include refid="selectQcInspectionItemCategoryVo"/>
<where> <where>
<if test="categoryId != null "> and category_id = #{categoryId}</if> <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="categoryCode != null and categoryCode != ''"> and category_code = #{categoryCode}</if>
<if test="categoryName != null and categoryName != ''"> and category_name like concat('%', #{categoryName}, '%')</if> <if test="categoryName != null and categoryName != ''"> and category_name like concat('%', #{categoryName}, '%')</if>
<if test="typeId != null "> and type_id = #{typeId}</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"> <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <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) #foreach($column in $columns)
#if($column.query) #if($column.query)
#set($dictType=$column.dictType) #set($dictType=$column.dictType)
@ -78,11 +78,6 @@
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button> <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button>
</el-col> </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> <right-toolbar v-model:showSearch="showSearch" :columns="columns" :search="true" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
@ -471,13 +466,6 @@ const handleExport = () => {
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`) }, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
} }
/** 导出模板按钮操作 */
const handleExportTemplate = () => {
proxy?.download('${moduleName}/${businessName}/exportTemplate', {
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
}
onMounted(() => { onMounted(() => {
getList(); getList();
}); });

Loading…
Cancel
Save