package ${packageName}.service.impl;
<#if table.cacheServiceType==0 >
    <#assign Service = "AbstractCRUDServiceImpl">
<#elseif table.cacheServiceType==1 >
    <#assign Service = "AbstractCRUDCacheServiceImpl">
<#elseif table.cacheServiceType==2 >
    <#assign Service = "AbstractCRUDDynamicCacheServiceImpl">
<#else >
    <#assign Service = "AbstractCRUDServiceImpl">
</#if>
import org.springframework.stereotype.Service;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.impl.${Service};
import ${packageName}.dao.${ClassName}Dao;
import ${packageName}.model.${ClassName}Entity;
import ${packageName}.model.${ClassName}Query;
import ${packageName}.service.${ClassName}Service;
import ${packageName}.model.${ClassName}TreeSelect;
import org.springframework.util.ObjectUtils;
import java.util.*;
import java.util.stream.Collectors;
<#if pkColumn??&&pkColumn.isIncrement==0 >
import cn.hutool.core.util.IdUtil;
</#if>
<#if pkColumn??&&pkColumn.isIncrement==0 >
    <#assign Temp>
    @Override
    protected void saveBefore(${ClassName}Entity entity, Context context) throws AppException {
    //非系统自增，需这里设置主键
    <#if pkColumn.javaType=="String" >
        entity.set${pkColumn.javaField?cap_first}(IdUtil.fastSimpleUUID());
    <#elseif pkColumn.javaType=="Integer">
        entity.set${pkColumn.javaField?cap_first}(((Long)IdUtil.getSnowflake(1024,512).nextId()).intValue());
    <#elseif pkColumn.javaType=="Long">
        entity.set${pkColumn.javaField?cap_first}(IdUtil.getSnowflake(1024,512).nextId());
    </#if>
    super.saveBefore(entity, context);
    }
    </#assign>
    <#else>
    <#assign Temp ></#assign>
</#if>
/**
* ${ClassName}Service
* ${functionName} service实现
*
* @author ${author}
* @date ${datetime}
*/
@Service("${ClassName?uncap_first}Service")
public class ${ClassName}ServiceImpl extends ${Service}<${ClassName}Dao, ${ClassName}Entity, ${pkColumn.javaType}> implements ${ClassName}Service {

    @Override
    protected void saveBefore(${ClassName}Entity entity, Context context) throws AppException {
        ${ClassName}Entity parent${ClassName}Entity = this.get(entity.get${treeParentCode?cap_first}());

        if (!ObjectUtils.isEmpty(parent${ClassName}Entity)) {
            entity.setAncestors(parent${ClassName}Entity.getAncestors() + "," + entity.get${treeParentCode?cap_first}());
        }

        super.saveBefore(entity, context);
    }

    @Override
    protected void updateBefore(${ClassName}Entity entity, Context context) throws AppException {
        ${ClassName}Entity newParentEntity = this.get(entity.get${treeParentCode?cap_first}());
        ${ClassName}Entity oldEntity = this.get(entity.get${pkColumn.javaField?cap_first}());
        if (!ObjectUtils.isEmpty(newParentEntity) && !ObjectUtils.isEmpty(oldEntity)) {
            String newAncestors = newParentEntity.getAncestors() + "," + newParentEntity.get${pkColumn.javaField?cap_first}();
            String oldAncestors = oldEntity.getAncestors();
            entity.setAncestors(newAncestors);
            update${ClassName}Children(entity.get${pkColumn.javaField?cap_first}(), newAncestors, oldAncestors, context);
        }
        super.updateBefore(entity, context);
    }

    /**
    * 修改子元素关系
    *
    * @param ${ClassName?uncap_first}Id       被修改的${functionName}ID
    * @param newAncestors 新的父ID集合
    * @param oldAncestors 旧的父ID集合
    */
    public void update${ClassName}Children(Long ${ClassName?uncap_first}Id, String newAncestors, String oldAncestors, Context context) {
        List<${ClassName}Entity> children =  getDao().selectChildren${ClassName}ById(${ClassName?uncap_first}Id.toString());
        for (${ClassName}Entity child : children) {
            child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            this.updateAfter(children, context);
        }
    }


    @Override
    protected void removeBefore(Long[] ids, Context context) throws AppException {
        //有子节点 禁止删除
        if (hasChildBy${ClassName}Id(ids[0])) {
            throw new AppException("存在下级${functionName},不允许删除");
        }
        super.removeBefore(ids, context);
    }

    @Override
    public boolean hasChildBy${ClassName}Id(Long ${ClassName?uncap_first}Id) {
        List<${ClassName}Entity> list = this.find(new ${ClassName}Query().${treeParentCode}(${ClassName?uncap_first}Id));
        return list.size() > 0 ? true : false;
    }

    @Override
    public List<${ClassName}TreeSelect> build${ClassName}TreeSelect(List<${ClassName}Entity> list) {
        List<${ClassName}Entity> returnList = new ArrayList<>();
        List<Long> tempList = list.stream().map(${ClassName}Entity::get${pkColumn.javaField?cap_first}).collect(Collectors.toList());

        for (Iterator<${ClassName}Entity> iterator = list.iterator(); iterator.hasNext(); ) {
            ${ClassName}Entity ${ClassName?uncap_first}Entity = iterator.next();
            if (!tempList.contains(${ClassName?uncap_first}Entity.get${treeParentCode?cap_first}())) {
                recursionFn(list, ${ClassName?uncap_first}Entity);
                returnList.add(${ClassName?uncap_first}Entity);
            }
            }
            if (returnList.isEmpty()) {
            returnList = list;
        }
        return returnList.stream().map(${ClassName}TreeSelect::new).collect(Collectors.toList());
    }


    /**
    * 递归列表
    */
    private void recursionFn(List<${ClassName}Entity> list, ${ClassName}Entity t) {
        // 得到子节点列表
        List<${ClassName}Entity> childList = getChildList(list, t);
        t.setChildren(childList);
        for (${ClassName}Entity tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
    * 判断是否有子节点
    */
    private boolean hasChild(List<${ClassName}Entity> list, ${ClassName}Entity t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }

    /**
    * 得到子节点列表
    */
    private List<${ClassName}Entity> getChildList(List<${ClassName}Entity> list, ${ClassName}Entity t) {
        return list.stream().map(item->{
            if (!ObjectUtils.isEmpty(item.get${treeParentCode?cap_first}()) && item.get${treeParentCode?cap_first}() == t.get${pkColumn.javaField?cap_first}()) {
                return item;
            }
            return null;
            }).filter(f->f!=null).collect(Collectors.toList());
    }

    @Override
    public List<${ClassName}TreeSelect> getListByParentId(${treeParentCodeType} parentId, Context context) {
        if (ObjectUtils.isEmpty(parentId)) {
            parentId = 0L;
        }
        //只做一层
        List<${ClassName}TreeSelect> collect = this.find(new ${ClassName}Query().${treeParentCode}(parentId), context).stream().map(item -> new ${ClassName}TreeSelect(item)
        ).collect(Collectors.toList());
        return collect;
    }

}