Skip to content

Commit

Permalink
完善
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangkaitao committed Mar 10, 2013
1 parent f9842ef commit bd85ac3
Show file tree
Hide file tree
Showing 280 changed files with 26,728 additions and 709 deletions.
22 changes: 22 additions & 0 deletions common/src/main/java/com/sishuok/es/common/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,26 @@ public interface Constants {
* 消息key
*/
String MESSAGE = "message";

/**
* 错误key
*/
String ERROR = "error";

/**
* 上个页面地址
*/
String BACK_URL = "BackURL";

/**
* 当前请求的地址 带参数
*/
String CURRENT_URL = "currentURL";

/**
* 当前请求的地址 不带参数
*/
String NO_QUERYSTRING_CURRENT_URL = "noQueryStringCurrentURL";

String CONTEXT_PATH = "ctx";
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public static <T> void convertSearchValueToEntityValue(
searchFilter.setSearchPropertyMappingInfo(mappingDefinition.getSearchPropertyMapping(searchProperty));
}

//一元运算符不需要计算
if(searchFilter.isUnaryFilter()) {
continue;
}

String entityProperty = searchFilter.getEntityProperty();

Object value = searchFilter.getValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@
* <p>Date: 13-1-12 下午4:25
* <p>Version: 1.0
*/
public interface Stateable<T extends Enum<? extends Stateable.State>> {
public interface Stateable<T extends Enum<? extends Stateable.Status>> {

public void setState(T state);
public void setStatus(T status);

public T getState();
public T getStatus();


/**
* 标识接口,所有状态实现,需要实现该状态接口
*/
public static interface State {
public static interface Status {
}

/**
* 审核状态
*/
public static enum AuditStatus implements State {
public static enum AuditStatus implements Status {
fail("审核失败"), success("审核成功");
private final String info;

Expand All @@ -43,7 +43,7 @@ public String getInfo() {
/**
* 是否显示
*/
public static enum ShowStatus implements State {
public static enum ShowStatus implements Status {
hide("不显示"), show("显示");
private final String info;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,16 @@
*/
package com.sishuok.es.common.plugin.entity;

import java.io.Serializable;

/**
* <p>实体实现该接口表示想要实现树结构
* <p> path表示路径信息,长度为<code>getPathLength</code>方法返回的长度,假如长度为2结构如下
* <pre>
* 01 中国
* 0101 北京
* 010102 海淀
* </pre>
* <p/>
* <p>User: Zhang Kaitao
* <p>Date: 13-1-12 下午4:18
* <p>Version: 1.0
*/
public interface Treeable {
public interface Treeable<ID extends Serializable> {

public void setName(String name);

Expand All @@ -32,41 +28,52 @@ public interface Treeable {

public void setIcon(String icon);

public String getPath();
/**
* 父路径
* @return
*/
public ID getParentId();

public void setPath(String path);
public void setParentId(ID parentId);

/**
* 父路径
* 所有父路径 如1,2,3,
* @return
*/
public String getParentPath();
public String getParentIds();

public void setParentIds(String parentIds);

/**
* 是否是根节点
* 获取 parentIds 之间的分隔符
* @return
*/
public boolean isRoot();
public String getSeparator();

/**
* 是否是叶子节点
* 把自己构造出新的父节点路径
* @return
*/
public boolean isLeaf();
public String makeSelfAsNewParentIds();

/**
* 每级路径的长度
*
* 权重 用于排序 越小越排在前边
* @return
*/
public int getPathLength();
public Integer getWeight();
public void setWeight(Integer weight);

/**
* 是否是根节点
* @return
*/
public boolean isRoot();

/**
* 匹配儿子节点的后缀
* 是否是叶子节点
* @return
*/
public String getChildPathSuffix();
public boolean isLeaf();

/**
* 根节点默认图标 如果没有默认 空即可 大小为16×16
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.Serializable;
import java.util.List;

Expand All @@ -25,75 +26,106 @@
* <p>Date: 13-2-22 下午5:26
* <p>Version: 1.0
*/
public abstract class BaseTreeableService<M extends BaseEntity & Treeable, ID extends Serializable> extends BaseService<M, ID> {
public abstract class BaseTreeableService<M extends BaseEntity<ID> & Treeable<ID>, ID extends Serializable> extends BaseService<M, ID> {

private BaseRepositoryImpl<M, ID> baseRepositoryImpl;

private final String DELETE_SELF_AND_CHILD_QL;
private final String FIND_MAX_CHILD_PATH_QL;
private final String FIND_BY_PATH_QL;
private final String UPDATE_SELF_AND_CHILD_QL;
private final String DELETE_CHILDREN_QL;
private final String UPDATE_CHILDREN_PARENT_IDS_QL;
private final String FIND_SELF_AND_NEXT_SIBLINGS_QL;
private final String FIND_NEXT_WEIGHT_QL;

protected <R extends BaseRepository<M, ID>> BaseTreeableService() {
baseRepositoryImpl = BaseRepositoryImpl.<M, ID>defaultBaseRepositoryImpl(entityClass);
String entityName = this.entityClass.getSimpleName();

DELETE_SELF_AND_CHILD_QL = String.format("delete from %s where path like concat(?1, %s)", entityName, "'%'");
FIND_MAX_CHILD_PATH_QL = String.format("select max(path) from %s where path like concat(?1, ?2)", entityName);
FIND_BY_PATH_QL = String.format("from %s where path = ?1", entityName);
UPDATE_SELF_AND_CHILD_QL =
String.format("update %s set path = ?2 || substr(path, length(?1)+1) where path like concat(?1, %s)", entityName, "'%'");
DELETE_CHILDREN_QL = String.format("delete from %s where id=?1 or parentIds like concat(?2, %s)", entityName, "'%'");

UPDATE_CHILDREN_PARENT_IDS_QL =
String.format("update %s set parentIds=(?1 || substr(parentIds, length(?2)+1)) where parentIds like concat(?2, %s)", entityName, "'%'");

FIND_SELF_AND_NEXT_SIBLINGS_QL =
String.format("from %s where path >= ?1 and path like concat(substr(?1, 1, length(?1) - 3), ?2) order by path asc", entityName);
String.format("from %s where parentIds = ?1 and weight>=?2 order by weight asc", entityName);

FIND_NEXT_WEIGHT_QL =
String.format("select case when max(weight) is null then 1 else (max(weight) + 1) end from %s where parentId = ?1", entityName);
}

@Override
public M save(M m) {
if(m.getWeight() == null) {
m.setWeight(nextWeight(m.getParentId()));
}
return super.save(m);
}

@Override
public M saveAndFlush(M m) {
if(m.getWeight() == null) {
m.setWeight(nextWeight(m.getParentId()));
}
return super.saveAndFlush(m);
}

@Transactional
public void deleteSelfAndChild(M m) {
baseRepositoryImpl.batchUpdate(DELETE_SELF_AND_CHILD_QL, m.getPath());
baseRepositoryImpl.batchUpdate(DELETE_CHILDREN_QL, m.getId(), m.makeSelfAsNewParentIds());
}

@Transactional
public void appendChild(M parent, M child) {
String nextChildPath = nextChildPath(parent.getPath(), parent.getChildPathSuffix());
child.setPath(nextChildPath);
child.setParentId(parent.getId());
child.setParentIds(parent.makeSelfAsNewParentIds());
child.setWeight(nextWeight(parent.getId()));
save(child);
}

private String nextChildPath(String parentPath, String childPathSuffix) {
String maxChildPath = baseRepositoryImpl.findOne(FIND_MAX_CHILD_PATH_QL, parentPath, childPathSuffix);
if(StringUtils.isEmpty(maxChildPath)) {
return parentPath + String.format("%0" + childPathSuffix.length() + "d", 1);
}
return String.format("%0" + maxChildPath.length() + "d", Long.valueOf(maxChildPath) + 1);
}
public int nextWeight(ID id) {
return baseRepositoryImpl.findOne(FIND_NEXT_WEIGHT_QL, id);
}

public M findByPath(String path) {
return baseRepositoryImpl.findOne(FIND_BY_PATH_QL, path);
}

/**
* 移动节点
* 根节点不能移动
* @param source 源节点
* @param targetPath 目标节点
* @param target 目标节点
* @param moveType 位置
*/
@Transactional
public void move(M source, String targetPath, String moveType) {
M target = findByPath(targetPath);
public void move(M source, M target, String moveType) {
if(source == null || target == null || source.isRoot() || target.isRoot()) { //根节点不能移动
return;
}

//如果是相邻的兄弟 直接交换weight即可
boolean isSibling = source.getParentId().equals(target.getParentId());
boolean isNextOrPrevMoveType = "next".equals(moveType) || "prev".equals(moveType);
if(isSibling && isNextOrPrevMoveType && Math.abs(source.getWeight() - target.getWeight()) == 1) {

//无需移动
if("next".equals(moveType) && source.getWeight() > target.getWeight()) {
return;
}
if("prev".equals(moveType) && source.getWeight() < target.getWeight()) {
return;
}


int sourceWeight = source.getWeight();
source.setWeight(target.getWeight());
target.setWeight(sourceWeight);
return;
}

//移动到目标节点之后
if ("next".equals(moveType)) {
List<M> siblings = findSelfAndNextSiblings(target.getPath(), target.getChildPathSuffix());
List<M> siblings = findSelfAndNextSiblings(target.getParentIds(), target.getWeight());
siblings.remove(0);//把自己移除

if(siblings.size() == 0) { //如果没有兄弟了 则直接把源的设置为目标即可
String nextTargetChildPath = nextChildPath(target.getParentPath(), target.getChildPathSuffix());
updateSelftAndChild(source.getPath(), nextTargetChildPath);
int nextWeight = nextWeight(target.getParentId());
updateSelftAndChild(source, target.getParentId(), target.getParentIds(), nextWeight);
return;
} else {
moveType = "prev";
Expand All @@ -103,52 +135,61 @@ public void move(M source, String targetPath, String moveType) {

//移动到目标节点之前
if("prev".equals(moveType)) {
List<M> siblings = findSelfAndNextSiblings(target.getPath(), target.getChildPathSuffix());

List<M> siblings = findSelfAndNextSiblings(target.getParentIds(), target.getWeight());
//兄弟节点中包含源节点
if(siblings.contains(source)) {
// 001 002 [003 source] 004
// 1 2 [3 source] 4
siblings = siblings.subList(0, siblings.indexOf(source) + 1);
String firstPath = siblings.get(0).getPath();
int firstWeight = siblings.get(0).getWeight();
for(int i = 0; i < siblings.size() - 1; i++) {
siblings.get(i).setPath(siblings.get(i + 1).getPath());
siblings.get(i).setWeight(siblings.get(i + 1).getWeight());
}
siblings.get(siblings.size() - 1).setPath(firstPath);
siblings.get(siblings.size() - 1).setWeight(firstWeight);
} else {
// 001 002 003 004 [005 new]
String nextTargetChildPath = nextChildPath(target.getParentPath(), target.getChildPathSuffix());
String firstPath = siblings.get(0).getPath();
// 1 2 3 4 [5 new]
int nextWeight = nextWeight(target.getParentId());
int firstWeight = siblings.get(0).getWeight();
for(int i = 0; i < siblings.size() - 1; i++) {
siblings.get(i).setPath(siblings.get(i + 1).getPath());
siblings.get(i).setWeight(siblings.get(i + 1).getWeight());
}
siblings.get(siblings.size() - 1).setPath(nextTargetChildPath);
source.setPath(firstPath);
siblings.get(siblings.size() - 1).setWeight(nextWeight);
source.setWeight(firstWeight);
updateSelftAndChild(source, target.getParentId(), target.getParentIds(), source.getWeight());
}

return;
}
//否则作为最后孩子节点
String nextTargetChildPath = nextChildPath(target.getPath(), target.getChildPathSuffix());
updateSelftAndChild(source.getPath(), nextTargetChildPath);
int nextWeight = nextWeight(target.getId());
updateSelftAndChild(source, target.getId(), target.makeSelfAsNewParentIds(), nextWeight);
}


/**
* 把源节点全部变更为目标节点
* @param sourcePath
* @param nextTargetChildPath
* @param source
* @param newParentIds
*/
@Transactional
private void updateSelftAndChild(String sourcePath, String nextTargetChildPath) {
baseRepositoryImpl.batchUpdate(UPDATE_SELF_AND_CHILD_QL, sourcePath, nextTargetChildPath);
private void updateSelftAndChild(M source, ID newParentId, String newParentIds, int newWeight) {
String oldSourceChildrenParentIds = source.makeSelfAsNewParentIds();
source.setParentId(newParentId);
source.setParentIds(newParentIds);
source.setWeight(newWeight);
update(source);
String newSourceChildrenParentIds = source.makeSelfAsNewParentIds();
baseRepositoryImpl.batchUpdate(UPDATE_CHILDREN_PARENT_IDS_QL, newSourceChildrenParentIds, oldSourceChildrenParentIds);
}

/**
* 查找目标节点及之后的兄弟
* @param selfPath
* @param childPathSuffix
* 查找目标节点及之后的兄弟 注意:值与越小 越排在前边
* @param parentIds
* @param currentWeight
* @return
*/
protected List<M> findSelfAndNextSiblings(String selfPath, String childPathSuffix) {
return baseRepositoryImpl.findAll(FIND_SELF_AND_NEXT_SIBLINGS_QL, selfPath, childPathSuffix);
protected List<M> findSelfAndNextSiblings(String parentIds, int currentWeight) {
return baseRepositoryImpl.findAll(FIND_SELF_AND_NEXT_SIBLINGS_QL, parentIds, currentWeight);
}


Expand Down
Loading

0 comments on commit bd85ac3

Please sign in to comment.