单表配置多级类型,按名称模糊筛选

页面要求 表结构

代码逻辑:

Groovy 复制代码
typeName = Utils.val("typeName")
def sql = """
    WITH RECURSIVE type_cte (
        type_id, parent_type_id, type_code, type_name, info_source, 
        timeliness, publish_type, publish_rule, info_desc, state, create_time, create_by, update_time, update_by
    ) AS (
        SELECT 
            type_id, parent_type_id, type_code, type_name, info_source, 
            timeliness, publish_type, publish_rule, info_desc, state, create_time, create_by, update_time, update_by
        FROM js_em_publish_info_type
        WHERE state = 'A'
          AND parent_type_id = 0

        UNION ALL

        SELECT 
            t.type_id, t.parent_type_id, t.type_code, t.type_name, t.info_source, 
            t.timeliness, t.publish_type, t.publish_rule, t.info_desc, t.state, t.create_time, t.create_by, t.update_time, t.update_by
        FROM js_em_publish_info_type t
        INNER JOIN type_cte p ON t.parent_type_id = p.type_id
        WHERE t.state = 'A'
    )
    SELECT t1.type_id, t1.parent_type_id, t1.type_code, t1.type_name, 
        t1.info_source, t2.dict_value as info_source_name,
        t1.timeliness, t3.dict_value as timeliness_name,
        t1.publish_type, t4.dict_value as publish_type_name,
        t1.publish_rule, t1.info_desc, t1.state, 
        TO_CHAR(t1.create_time, 'YYYY-MM-DD HH24:MI:SS') AS create_time,
        t1.create_by, t1.update_time, t1.update_by 
    FROM type_cte t1 
    LEFT JOIN js_sys_dict t2 ON t1.info_source = t2.dict_code and t2.class_code='psmp_info_source'
    LEFT JOIN js_sys_dict t3 ON t1.timeliness = t3.dict_code and t3.class_code='psmp_info_timeliness'
    LEFT JOIN js_sys_dict t4 ON t1.publish_type = t4.dict_code and t4.class_code='psmp_info_publish_date_type'
    where 1=1
   -- ?{typeName, and t1.type_name like concat('%', #{typeName}, '%')}     
    ORDER BY t1.type_id ASC
"""

log.info("日志输出2: {}", sql)
allTypeList = db.find(sql)

// 优化:在树构建后,仅保留与模糊查询匹配的节点及其祖先、所有子孙,树会自动裁剪非匹配支。

def typeNameParam = typeName ?: null

// 遍历树形数据,匹配需要模糊查询的类型名称,返回过滤后的树型数据
def filterTypeTreeByName(typeList, typeName) {
    if (!typeName) return typeList
    def result = []
    typeList.each { node ->
        if ((node.typeName ?: '').contains(typeName)) {
            // 节点匹配,保留整棵子树
            result << node
        } else if (node.children && node.children.size() > 0) {
            def filteredChildren = filterTypeTreeByName(node.children, typeName)
            if (!filteredChildren.isEmpty()) {
                node.children = filteredChildren
                result << node
            }
        }
    }
    return result
}

// 把无等级树结构的数据,格式化成前端可以直接用的树结构数据
def buildTypeTree(typeList) {
    def roots = typeList.findAll { it.parentTypeId == 0 }
    roots.each { t ->
        t.children = getChildTypes(t.typeId, typeList)
    }
    return roots
}

def getChildTypes(parentId, typeList) {
    def children = typeList.findAll { it.parentTypeId == parentId }
    children.each { c ->
        c.children = getChildTypes(c.typeId, typeList)
    }
    return children
}

// 处理数据为前端需要的树数据结构
resultTree = buildTypeTree(allTypeList)

// 如果按类型名称模糊查询的入参不为空,去过滤
if (typeNameParam) {
    resultTree = filterTypeTreeByName(resultTree, typeNameParam)
}

return resultTree
相关推荐
2601_9539880716 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·后端·物联网·tcp/ip·数学建模·前端框架
chuan.bai16 小时前
Java RAG 实战(第 8 篇):Spring Boot RAG 查询 API
java·spring boot·贪心算法
FlyWIHTSKY16 小时前
idea中集成claude功能
java·ide·人工智能·intellij-idea·cloudera
IT_陈寒16 小时前
SpringBoot自动配置坑了我三天,原来漏了这个注解
前端·人工智能·后端
Java成神之路-16 小时前
Spring AI 统一结构化返回:ChatModel / ChatClient 两种实现方式
java·springaialibaba
Mr. zhihao16 小时前
深度解析:为什么Java序列化需要搭配ByteArrayOutputStream?IO装饰器模式的精妙设计
java·开发语言·装饰器模式
存在morning16 小时前
【Python 开发实践 一】Python vs Go vs Java 三门语言对比
java·python·golang
vx-程序开发16 小时前
springboot旅游推介平台---附源码24175
java·spring boot·python·spring cloud·eclipse·django·idea
AINative软件工程16 小时前
模型路由别写死在代码里:Policy-as-Code 才是 LLM 成本和质量的刹车片
后端
艾莉丝努力练剑17 小时前
【QT:解决问题】Qt5Core.dll:无法定位程序输入点
java·开发语言·qt·学习·面试