复制树形列表功能实现

 图为需要复制的内容

需求简述:每个年度有不同的树形列表,该功能为复制新增树:先选择某个年度的树,点击复制新增后需要变为指定年度的树,树的结构完全一致,变化的是id,年度;

详情:第一张图中的树是由2部分数据拼接的,其中深度为1-3的树在另一张表中定义,深度4+的树为需要复制的数据;

难点:新生成的id与pid的映射

解决思路:通过cpid中间字段保存旧id,实现映射

代码思路:将原来数组按照树的深度拆分为各个数组,根据深度进行遍历,将每个深度的数组id,pid和年度逐一替换(很笨拙的方法,后续待改进)

后端实现

1、model

用到的实体类有3个,BudgetTreeYear(实体类),BudgetTreeYearVO(用于拼装树,含children),BudgetTreeYearParam(传参用实体类)

BudgetTreeYear

BudgetTreeYearVO

BudgetTreeYearParam

2、dao,平台封装,具体实现不难,这里不赘述

3、service

4、impl

 /**
     * 复制新增
     *
     * @param param
     * @return
     */
    @Override
    public Pager<BudgetTreeYear> getCopyMain(BudgetTreeYearParam param) {
        String budYear = param.getBudYear();
        String newYear = param.getNewYear();
        List<BudgetTreeYear> oldList = getBudgetTreeYearByYear(budYear);
        List<BudgetTreeYear> list4 = get4List(oldList, newYear);
        List<BudgetTreeYear> result = new ArrayList<>();
        List<List<BudgetTreeYear>> newList = new ArrayList<>();
        int times = getMaxDepth(oldList) - 4;
        newList.add(list4);

        // 这个循环是重点!!!!!!!

        for (int i = 0; i < times; i++) {
            newList.add(getNewList(getIList(oldList, i + 5), newList.get(i), newYear));
        }
        for (List<BudgetTreeYear> i : newList) {
            result.addAll(i);
        }
        Pager<BudgetTreeYear> pager = new Pager<>(param.getPageNo(),param.getPageSize(),result.size(),result);
        for (BudgetTreeYear bty: result) {
            opeMain(bty);
        }
        return pager;
    }

    /**
     * 获取同一深度的新数组
     *
     * @param oldList
     * @return
     */
    private List<BudgetTreeYear> getNewList(List<BudgetTreeYear> oldList, List<BudgetTreeYear> lastDepthList, String newYear) {
        List<BudgetTreeYear> newList = new ArrayList<>();
        for (int i = 0; i < oldList.size(); i++) {
            BudgetTreeYear bty = oldList.get(i);
            bty.setCopyId(bty.getId());
            bty.setId(IDUtil.getUUID());
            bty.setBudYear(newYear);
            bty.setParentId(getIdbyPid(lastDepthList, bty.getParentId()));
            newList.add(bty);
        }
        return newList;
    }

    /**
     * 返回深度为depth的oldList
     * @param list
     * @param depth
     * @return
     */
    private List<BudgetTreeYear> getIList(List<BudgetTreeYear> list, int depth) {
        List<BudgetTreeYear> listI = new ArrayList<>();
        int len = list.size();
        for (int i = 0; i < len; i++) {
            BudgetTreeYear bty = list.get(i);
            int oldDepth = Integer.parseInt(bty.getCateDepth());
            if (oldDepth == depth) {
                listI.add(bty);
            }
        }
        return listI;
    }

    /**
     * 根据旧的Pid获取新的Pid,通过cid获取
     * @param list
     * @param pId
     * @return
     */
    private String getIdbyPid(List<BudgetTreeYear> list, String pId) {
        String id = "";
        for (BudgetTreeYear bty : list) {
            if (pId.equals(bty.getCopyId())) {
                id = bty.getId();
            }
        }
        return id;
    }

    /**
     * 深度为3的数据固定,获取深度为4的数据
     * @param list
     * @param newYear
     * @return
     */
    private List<BudgetTreeYear> get4List(List<BudgetTreeYear> list, String newYear) {
        List<BudgetTreeYear> list4 = new ArrayList<>();
        int len = list.size();
        for (int i = 0; i < len; i++) {
            BudgetTreeYear bty = list.get(i);
            int depth = Integer.parseInt(bty.getCateDepth());
            if (depth == 4) {
                bty.setCopyId(bty.getId());
                bty.setId(IDUtil.getUUID());
                bty.setBudYear(newYear);
                list4.add(bty);
            }
        }
        return list4;
    }

    /**
     * 获取树的最大深度
     * @param list
     * @return
     */
    private int getMaxDepth(List<BudgetTreeYear> list) {
        List<Integer> depthList = new ArrayList();
        for (BudgetTreeYear bty : list) {
            depthList.add(Integer.parseInt(bty.getCateDepth()));
        }
        return Collections.max(depthList);
    }

以上是复制树的代码,拼装树的代码如下:

    /**
     * 组装树
     *
     * @param menus
     * @param voList
     */
    private void buildMenus(List<BudgetTreeYear> menus, List<BudgetTreeYearVO> voList) {
        for (BudgetTreeYear menu : menus) {
            if (StringUtils.isBlank(menu.getParentId())) {
                BudgetTreeYearVO vo = new BudgetTreeYearVO();
                BeanUtils.copyProperties(vo, menu);
                buildChildrenMenu(menus, vo, menu.getId());
                voList.add(vo);
            }
        }
    }

    /**
     * 组装树
     *
     * @param menus
     * @param vo
     * @param menuId
     */
    private void buildChildrenMenu(List<BudgetTreeYear> menus, BudgetTreeYearVO vo, String menuId) {
        List<BudgetTreeYearVO> children = new ArrayList<BudgetTreeYearVO>();
        for (BudgetTreeYear menu : menus) {
            if (StringUtils.isNotBlank(menu.getParentId()) &&
                    menu.getParentId().equals(menuId)) {
                BudgetTreeYearVO vo_ = new BudgetTreeYearVO();
                BeanUtils.copyProperties(vo_, menu);
                buildChildrenMenu(menus, vo_, menu.getId());
                children.add(vo_);
            }
        }
        vo.setChildren(children);
    }

5、用到的sql(sqlServer)

<?xml version="1.0" encoding="UTF-8"?>
<sqls>
	<sql id="get_tree" clazz="com.toone.im.model.bm.BudgetTreeYear">
	 <![CDATA[
		select * from ( select TOP 99.999999 PERCENT * from t_ip_year_budget_def t order by cate_prio) aa
		where 1=1
		<if null budYear>
		  AND aa.bud_year like CONCAT(CONCAT('%',:budYear),'%')
		</if null budYear>
		UNION all
		select *,null as bud_year from t_ip_budget_tree
	  ]]>
	</sql>
<sqls>

Sql中第一层select TOP 99.999999 是为了 union all 排序,其中t_ip_year_budget_def 存的是树深度为4+的数据,t_ip_budget_tree为深度1-3的数据

一点点积累,慢慢进步鸭QAQ!

-------------------20200716更新------------------------

以上方法蠢到家,以下是新思路

/**
     * 复制新增
     *
     * @param param
     * @return
     */
    @Override
    public Pager<BudgetTreeYear> getCopyMain(BudgetTreeYearParam param) {
        String budYear = param.getBudYear();
        POCondition condition = new POCondition();
        condition.addOrderDesc("budYear");
        List<BudgetTreeYear> list = budgetTreeYearDao.findPoList(BudgetTreeYear.class, condition);
        String newYear = CalcUtil.getNextCode(list.get(0).getBudYear(), 4);
        // 复制原数据
        condition = new POCondition();
        condition.addEQ("budYear", budYear);
        List<BudgetTreeYear> source = budgetTreeYearDao.findPoList(BudgetTreeYear.class, condition);
        Map<String, String> idMap = new HashMap<>(source.size());
        for (BudgetTreeYear item : source) {
            String newId = IDUtil.getUUID();
            idMap.put(item.getId(), newId);
            item.setId(newId);
            item.setBudYear(newYear);
            String code = item.getCateCode();
            if (StringUtils.isBlank(code) || code.length() < 4) {
                continue;
            }
            item.setCateCode(newYear + code.substring(4));
        }
        for (BudgetTreeYear b : source) {
            String parentId = idMap.get(b.getParentId());
            if (parentId != null) {
                b.setParentId(parentId);
            }
        }
        budgetTreeYearDao.addPoBatch(source);
        // 返回新列表
        param.setBudYear(newYear);
        return listMain(param);
    }

果然,业务功能实现功能方面,思路最重要,越复杂的功能思路越清晰就越简单,想好再动手,省时省力;没想好就动手纯粹浪费时间,当然赶进度除外,害

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值