package com.jspxcms.core.service.impl; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.apache.shiro.util.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.jspxcms.common.orm.Limitable; import com.jspxcms.common.orm.SearchFilter; import com.jspxcms.common.util.RowSide; import com.jspxcms.core.domain.Org; import com.jspxcms.core.listener.OrgDeleteListener; import com.jspxcms.core.repository.OrgDao; import com.jspxcms.core.service.OrgService; /** * OrgServiceImpl * * @author liufang * */ @Service @Transactional(readOnly = true) public class OrgServiceImpl implements OrgService { public List<Org> findList(Integer parentId, Boolean showDescendants, Map<String, String[]> params, Sort sort) { String treeNumber = null; if (showDescendants != null && showDescendants) { if (parentId != null) { Org parent = dao.findOne(parentId); if (parent != null) { treeNumber = parent.getTreeNumber(); } else { return Collections.emptyList(); } } else { treeNumber = ""; } parentId = null; } return dao.findAll(spec(parentId, treeNumber, params), sort); } public RowSide<Org> findSide(Integer parentId, Boolean showDescendants, Map<String, String[]> params, Org bean, Integer position, Sort sort) { if (position == null) { return new RowSide<Org>(); } String treeNumber = null; if (showDescendants != null && showDescendants) { if (parentId == null) { Org parent = dao.findOne(parentId); if (parent != null) { treeNumber = parent.getTreeNumber(); } else { return new RowSide<Org>(); } } else { treeNumber = ""; } parentId = null; } Limitable limit = RowSide.limitable(position, sort); List<Org> list = dao.findAll(spec(parentId, treeNumber, params), limit); return RowSide.create(list, bean); } private Specification<Org> spec(final Integer parentId, final String treeNumber, Map<String, String[]> params) { Collection<SearchFilter> filters = SearchFilter.parse(params).values(); final Specification<Org> fs = SearchFilter.spec(filters, Org.class); Specification<Org> sp = new Specification<Org>() { public Predicate toPredicate(Root<Org> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Predicate pred = fs.toPredicate(root, query, cb); if (treeNumber != null) { Path<String> tnPath = root.get("treeNumber"); pred = cb.and(pred, cb.like(tnPath, treeNumber + "%")); } else if (parentId != null) { Path<Integer> pidPath = root.get("parent").get("id"); pred = cb.and(pred, cb.equal(pidPath, parentId)); } else { pred = cb.and(pred, root.get("parent").isNull()); } return pred; } }; return sp; } public List<Org> findList() { return dao.findAll(new Sort("treeNumber")); } public Org get(Integer id) { return dao.findOne(id); } @Transactional public Org save(Org bean, Integer parentId) { Org parent = null; if (parentId != null) { parent = dao.findOne(parentId); bean.setParent(parent); parent.addChild(bean); } bean.applyDefaultValue(); treeSave(bean, parent); bean = dao.save(bean); return bean; } @Transactional private void treeSave(Org bean, Org parent) { bean.setTreeMax(Org.long2hex(0)); if (parent == null) { String treeMax = dao.findMaxRootTreeNumber(); long maxLong = Org.hex2long(treeMax); treeMax = Org.long2hex(maxLong + 1); bean.setTreeLevel(0); bean.setTreeNumber(treeMax); bean.setTreeMax(Org.long2hex(0)); } else { bean.setTreeLevel(parent.getTreeLevel() + 1); String treeMax = parent.getTreeMax(); bean.setTreeNumber(parent.getTreeNumber() + "-" + treeMax); long big = parent.getTreeMaxLong() + 1; parent.setTreeMax(Org.long2hex(big)); dao.save(parent); } } @Transactional public Org update(Org bean, Integer parentId) { bean.applyDefaultValue(); bean = dao.save(bean); Org parent = bean.getParent(); if ((parent != null && !parent.getId().equals(parentId)) || (parent == null && parentId != null)) { move(new Integer[] { bean.getId() }, parentId); } return bean; } @Transactional public Org[] batchUpdate(Integer[] id, String[] name, String[] number, boolean isUpdateTree) { Map<Integer, List<Integer>> listMap = new HashMap<Integer, List<Integer>>(); Org[] beans = new Org[id.length]; for (int i = 0, len = id.length; i < len; i++) { beans[i] = dao.findOne(id[i]); beans[i].setName(name[i]); beans[i].setNumber(number[i]); dao.save(beans[i]); if (isUpdateTree) { Org parent = beans[i].getParent(); Integer parentId; if (parent != null) { parentId = parent.getId(); } else { parentId = -1; } List<Integer> list = listMap.get(parentId); if (list != null) { list.add(id[i]); } else { list = new ArrayList<Integer>(); list.add(id[i]); listMap.put(parentId, list); } } } String parentTreeNumber, origTreeNumber, treeNumber; for (Entry<Integer, List<Integer>> entry : listMap.entrySet()) { Integer parentId = entry.getKey(); List<Integer> ids = entry.getValue(); if (parentId == -1) { dao.appendModifiedFlag("%"); int len = ids.size(); if (dao.countRoot() != len) { continue; } for (int i = 0; i < len; i++) { origTreeNumber = dao.findTreeNumber(ids.get(i)); treeNumber = Org.long2hex(i); dao.updateTreeNumber(origTreeNumber + "%", treeNumber, treeNumber.length() + 2); } } else { parentTreeNumber = dao.findTreeNumber(parentId); dao.appendModifiedFlag(parentTreeNumber + "-%"); int len = ids.size(); if (dao.countByParentId(parentId) != len) { continue; } for (int i = 0; i < len; i++) { origTreeNumber = dao.findTreeNumber(ids.get(i)); treeNumber = parentTreeNumber + "-" + Org.long2hex(i); dao.updateTreeNumber(origTreeNumber + "%", treeNumber, treeNumber.length() + 2); } // 修改父节点的treeMax dao.updateTreeMax(parentId, Org.long2hex(len)); } } return beans; } @Transactional public int move(Integer[] ids, Integer id) { int count = 0; String modifiedTreeNumber, treeNumber; if (id == null) { long treeMax = Org.hex2long(dao.findMaxRootTreeNumber()) + 1; for (int i = 0, len = ids.length; i < len; i++) { treeNumber = dao.findTreeNumber(ids[i]); modifiedTreeNumber = Org.long2hex(treeMax++); count += dao.updateTreeNumber(treeNumber + "%", modifiedTreeNumber, treeNumber.length() + 1); dao.updateParentId(ids[i], id); } } else { Org parent = dao.findOne(id); String parentTreeNumber = parent.getTreeNumber(); long treeMax = parent.getTreeMaxLong(); for (int i = 0, len = ids.length; i < len; i++) { dao.updateTreeMax(id, Org.long2hex(treeMax + 1)); treeNumber = dao.findTreeNumber(ids[i]); modifiedTreeNumber = parentTreeNumber + "-" + Org.long2hex(treeMax++); count += dao.updateTreeNumber(treeNumber + "%", modifiedTreeNumber, treeNumber.length() + 1); dao.updateParentId(ids[i], id); } } return count; } private Org doDelete(Integer id) { Org entity = dao.findOne(id); if (entity != null) { dao.delete(entity); } return entity; } @Transactional public Org delete(Integer id) { firePreDelete(new Integer[] { id }); return doDelete(id); } @Transactional public Org[] delete(Integer[] ids) { firePreDelete(ids); Org[] beans = new Org[ids.length]; for (int i = 0; i < ids.length; i++) { beans[i] = doDelete(ids[i]); } return beans; } private void firePreDelete(Integer[] ids) { if (!CollectionUtils.isEmpty(deleteListeners)) { for (OrgDeleteListener listener : deleteListeners) { listener.preOrgDelete(ids); } } } private List<OrgDeleteListener> deleteListeners; @Autowired(required = false) public void setDeleteListeners(List<OrgDeleteListener> deleteListeners) { this.deleteListeners = deleteListeners; } private OrgDao dao; @Autowired public void setDao(OrgDao dao) { this.dao = dao; } }