소스 검색

优化查询条件

zhouhao 6 년 전
부모
커밋
ed39ea8abe
12개의 변경된 파일556개의 추가작업 그리고 36개의 파일을 삭제
  1. 20 5
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/AbstractSqlTermCustomer.java
  2. 16 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/ChangedTermValue.java
  3. 6 2
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/TreeStructureSqlTermCustomer.java
  4. 10 1
      hsweb-system/hsweb-system-organizational/README.md
  5. 9 2
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/SimplePositionService.java
  6. 197 4
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/CustomSqlTermConfiguration.java
  7. 5 3
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/PersonInPositionSqlTerm.java
  8. 58 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInDepartmentSqlTerm.java
  9. 58 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInDistSqlTerm.java
  10. 58 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInOrgSqlTerm.java
  11. 32 19
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInPositionSqlTerm.java
  12. 87 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInSqlTerm.java

+ 20 - 5
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/AbstractSqlTermCustomer.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.dao.mybatis.mapper;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;
+import org.hswebframework.ezorm.core.param.Term;
 import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
 import org.hswebframework.ezorm.rdb.render.SqlAppender;
 import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
@@ -24,23 +25,37 @@ public abstract class AbstractSqlTermCustomer implements SqlTermCustomer {
     }
 
     protected String createColumnName(RDBColumnMetaData column, String tableAlias) {
-        return column.getTableMetaData().getDatabaseMetaData().getDialect().buildColumnName(tableAlias, column.getName());
+        return column.getTableMetaData()
+                .getDatabaseMetaData()
+                .getDialect()
+                .buildColumnName(tableAlias, column.getName());
     }
 
-    protected void appendCondition(List<Object> values, String wherePrefix, SqlAppender appender) {
+
+    protected ChangedTermValue createChangedTermValue(Term term) {
+        if (term.getValue() instanceof ChangedTermValue) {
+            return ((ChangedTermValue) term.getValue());
+        } else {
+            ChangedTermValue termValue = new ChangedTermValue(term.getValue(), term.getValue());
+            term.setValue(termValue);
+            return termValue;
+        }
+    }
+
+    protected Object appendCondition(List<Object> values, String wherePrefix, SqlAppender appender) {
         int len = values.size();
         if (len == 1) {
-            appender.add("=#{", wherePrefix, ".value[0]}");
+            appender.add("=#{", wherePrefix, ".value.value[0]}");
         } else {
             appender.add("in(");
             for (int i = 0; i < len; i++) {
                 if (i > 0) {
                     appender.add(",");
                 }
-                appender.add("#{", wherePrefix, ".value[" + i + "]}");
+                appender.add("#{", wherePrefix, ".value.value[" + i + "]}");
             }
             appender.add(")");
         }
-
+        return values;
     }
 }

+ 16 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/ChangedTermValue.java

@@ -0,0 +1,16 @@
+package org.hswebframework.web.dao.mybatis.mapper;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+@Data
+@AllArgsConstructor
+public class ChangedTermValue {
+    private Object old;
+
+    private Object value;
+}

+ 6 - 2
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/TreeStructureSqlTermCustomer.java

@@ -26,13 +26,17 @@ public abstract class TreeStructureSqlTermCustomer extends AbstractSqlTermCustom
 
     @Override
     public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
-        List<Object> value = BoostTermTypeMapper.convertList(column, term.getValue());
+        ChangedTermValue termValue = createChangedTermValue(term);
+
+        List<Object> value = BoostTermTypeMapper.convertList(column, termValue.getOld());
+
         List<String> paths = getTreePathByTerm(value)
                 .stream()
                 .map(path -> path.concat("%"))
                 .collect(Collectors.toList());
 
-        term.setValue(paths);
+        termValue.setValue(paths);
+
         SqlAppender termCondition = new SqlAppender();
 
         termCondition.add(not ? "not " : "", "exists(select 1 from ", getTableName(), " tmp where tmp.u_id = ", createColumnName(column, tableAlias));

+ 10 - 1
hsweb-system/hsweb-system-organizational/README.md

@@ -18,4 +18,13 @@ createQuery().where("orgId","org-child-in","1234").list();
 3. dept-child`(-not)`-in: 参数`(不)`在指定的部门以及子节点中
 3. pos-child`(-not)`-in: 参数`(不)`在指定的岗位以及子节点中
 4. person`(-not)`-in-position: 人员ID`(不)`在岗位中
-5. user`(-not)`-in-position: 用户ID`(不)`在岗位中
+5. user`(-not)`-in-position`(-child)`: 用户ID`(不)`在岗位中`(包含子级岗位)`
+6. user`(-not)`-in-department`(-child)`: 用户ID`(不)`在部门中`(包含子级岗位)`
+7. user`(-not)`-in-org`(-child)`: 用户ID`(不)`在机构中`(包含子级岗位)`
+8. user`(-not)`-in-dist`(-child)`: 用户ID`(不)`在行政区域中`(包含子级岗位)`
+9. person`(-not)`-in-position`(-child)`: 人员ID`(不)`在岗位中`(包含子级岗位)`
+10. person`(-not)`-in-department`(-child)`: 人员ID`(不)`在部门中`(包含子级岗位)`
+11. person`(-not)`-in-org`(-child)`: 人员ID`(不)`在机构中`(包含子级岗位)`
+12. person`(-not)`-in-dist`(-child)`: 人员ID`(不)`在行政区域中`(包含子级岗位)`
+
+注意: 括号中的内容是可选的

+ 9 - 2
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/SimplePositionService.java

@@ -22,9 +22,12 @@ import org.hswebframework.web.dao.organizational.PositionDao;
 import org.hswebframework.web.entity.organizational.PositionEntity;
 import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.web.service.AbstractTreeSortService;
+import org.hswebframework.web.service.EnableCacheAllEvictTreeSortService;
 import org.hswebframework.web.service.organizational.PositionService;
 import org.hswebframework.web.service.organizational.event.ClearPersonCacheEvent;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheConfig;
+import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
@@ -35,7 +38,8 @@ import org.springframework.util.CollectionUtils;
  * @author hsweb-generator-online
  */
 @Service("positionService")
-public class SimplePositionService extends AbstractTreeSortService<PositionEntity, String>
+@CacheConfig(cacheNames = "hsweb-position")
+public class SimplePositionService extends EnableCacheAllEvictTreeSortService<PositionEntity, String>
         implements PositionService {
 
     @Autowired
@@ -58,8 +62,9 @@ public class SimplePositionService extends AbstractTreeSortService<PositionEntit
     }
 
     @Override
+    @CacheEvict(allEntries = true)
     public int deleteByPk(String id) {
-        if(!CollectionUtils.isEmpty(personDao.selectByPositionId(id))){
+        if (!CollectionUtils.isEmpty(personDao.selectByPositionId(id))) {
             throw new BusinessException("岗位中还有人员,无法删除!");
         }
         publisher.publishEvent(new ClearPersonCacheEvent());
@@ -67,12 +72,14 @@ public class SimplePositionService extends AbstractTreeSortService<PositionEntit
     }
 
     @Override
+    @CacheEvict(allEntries = true)
     public int updateByPk(String id, PositionEntity entity) {
         publisher.publishEvent(new ClearPersonCacheEvent());
         return super.updateByPk(id, entity);
     }
 
     @Override
+    @CacheEvict(allEntries = true)
     public String insert(PositionEntity entity) {
         publisher.publishEvent(new ClearPersonCacheEvent());
         return super.insert(entity);

+ 197 - 4
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/CustomSqlTermConfiguration.java

@@ -65,14 +65,207 @@ public class CustomSqlTermConfiguration {
         return new PersonInPositionSqlTerm(true);
     }
 
+    /*====================================================================================*/
+
+    @Bean
+    public UserInPositionSqlTerm userInPositionSqlTerm(PositionService positionService) {
+
+        return new UserInPositionSqlTerm(false, false, "user-in-position", positionService);
+    }
+
+    @Bean
+    public UserInPositionSqlTerm userNotInPositionSqlTerm(PositionService positionService) {
+
+        return new UserInPositionSqlTerm(true, false, "user-not-in-position", positionService);
+    }
+
+    @Bean
+    public UserInPositionSqlTerm userInPositionChildSqlTerm(PositionService positionService) {
+
+        return new UserInPositionSqlTerm(false, true, "user-in-position-child", positionService);
+    }
+
+    @Bean
+    public UserInPositionSqlTerm userNotInPositionChildSqlTerm(PositionService positionService) {
+
+        return new UserInPositionSqlTerm(true, true, "user-not-in-position-child", positionService);
+    }
+ /*====================================================================================*/
+
+    @Bean
+    public UserInSqlTerm personInPositionSqlTerm(PositionService positionService) {
+
+        return new UserInPositionSqlTerm(false, false, "person-in-position", positionService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personNotInPositionSqlTerm(PositionService positionService) {
+
+        return new UserInPositionSqlTerm(true, false, "person-not-in-position", positionService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personInPositionChildSqlTerm(PositionService positionService) {
+
+        return new UserInPositionSqlTerm(false, true, "person-in-position-child", positionService).forPerson();
+    }
+
     @Bean
-    public UserInPositionSqlTerm userInPositionSqlTerm() {
-        return new UserInPositionSqlTerm(false);
+    public UserInSqlTerm personNotInPositionChildSqlTerm(PositionService positionService) {
+
+        return new UserInPositionSqlTerm(true, true, "person-not-in-position-child", positionService).forPerson();
     }
 
+    /*====================================================================================*/
     @Bean
-    public UserInPositionSqlTerm userNotInPositionSqlTerm() {
-        return new UserInPositionSqlTerm(true);
+    public UserInSqlTerm userInDepartmentSqlTerm(DepartmentService departmentService) {
+
+        return new UserInDepartmentSqlTerm(false, false, "user-in-department", departmentService);
+    }
+
+    @Bean
+    public UserInSqlTerm userNotInDepartmentSqlTerm(DepartmentService departmentService) {
+
+        return new UserInDepartmentSqlTerm(true, false, "user-not-in-department", departmentService);
+    }
+
+    @Bean
+    public UserInSqlTerm userInDepartmentChildSqlTerm(DepartmentService departmentService) {
+
+        return new UserInDepartmentSqlTerm(false, true, "user-in-department-child", departmentService);
+    }
+
+    @Bean
+    public UserInSqlTerm userNotInDepartmentChildSqlTerm(DepartmentService departmentService) {
+
+        return new UserInDepartmentSqlTerm(true, true, "user-not-in-department-child", departmentService);
+    }
+
+    /*====================================================================================*/
+    @Bean
+    public UserInSqlTerm personInDepartmentSqlTerm(DepartmentService departmentService) {
+
+        return new UserInDepartmentSqlTerm(false, false, "person-in-department", departmentService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personNotInDepartmentSqlTerm(DepartmentService departmentService) {
+
+        return new UserInDepartmentSqlTerm(true, false, "person-not-in-department", departmentService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personInDepartmentChildSqlTerm(DepartmentService departmentService) {
+
+        return new UserInDepartmentSqlTerm(false, true, "person-in-department-child", departmentService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personNotInDepartmentChildSqlTerm(DepartmentService departmentService) {
+
+        return new UserInDepartmentSqlTerm(true, true, "person-not-in-department-child", departmentService).forPerson();
+    }
+
+    /*====================================================================================*/
+    @Bean
+    public UserInSqlTerm userInOrgSqlTerm(OrganizationalService organizationalService) {
+
+        return new UserInOrgSqlTerm(false, false, "user-in-org", organizationalService);
+    }
+
+    @Bean
+    public UserInSqlTerm userNotInOrgSqlTerm(OrganizationalService organizationalService) {
+
+        return new UserInOrgSqlTerm(true, false, "user-not-in-org", organizationalService);
+    }
+
+    @Bean
+    public UserInSqlTerm userInOrgChildSqlTerm(OrganizationalService organizationalService) {
+
+        return new UserInOrgSqlTerm(false, true, "user-in-org-child", organizationalService);
+    }
+
+    @Bean
+    public UserInSqlTerm userNotInOrgChildSqlTerm(OrganizationalService organizationalService) {
+
+        return new UserInOrgSqlTerm(true, true, "user-not-in-org-child", organizationalService);
+    }
+
+
+    /*====================================================================================*/
+    @Bean
+    public UserInSqlTerm personInOrgSqlTerm(OrganizationalService organizationalService) {
+
+        return new UserInOrgSqlTerm(false, false, "person-in-org", organizationalService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personNotInOrgSqlTerm(OrganizationalService organizationalService) {
+
+        return new UserInOrgSqlTerm(true, false, "person-not-in-org", organizationalService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personInOrgChildSqlTerm(OrganizationalService organizationalService) {
+
+        return new UserInOrgSqlTerm(false, true, "person-in-org-child", organizationalService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personNotInOrgChildSqlTerm(OrganizationalService organizationalService) {
+
+        return new UserInOrgSqlTerm(true, true, "person-not-in-org-child", organizationalService).forPerson();
+    }
+
+
+    /*====================================================================================*/
+    @Bean
+    public UserInSqlTerm userInDistSqlTerm(DistrictService districtService) {
+
+        return new UserInDistSqlTerm(false, false, "user-in-dist", districtService);
+    }
+
+    @Bean
+    public UserInSqlTerm userNotInDistSqlTerm(DistrictService districtService) {
+
+        return new UserInDistSqlTerm(true, false, "user-not-in-dist", districtService);
+    }
+
+    @Bean
+    public UserInSqlTerm userInDistChildSqlTerm(DistrictService districtService) {
+
+        return new UserInDistSqlTerm(false, true, "user-in-dist-child", districtService);
+    }
+
+    @Bean
+    public UserInSqlTerm userNotInDistChildSqlTerm(DistrictService districtService) {
+
+        return new UserInDistSqlTerm(true, true, "user-not-in-dist-child", districtService);
+    }
+
+    /*====================================================================================*/
+    @Bean
+    public UserInSqlTerm personInDistSqlTerm(DistrictService districtService) {
+
+        return new UserInDistSqlTerm(false, false, "person-in-dist", districtService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personNotInDistSqlTerm(DistrictService districtService) {
+
+        return new UserInDistSqlTerm(true, false, "person-not-in-dist", districtService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personInDistChildSqlTerm(DistrictService districtService) {
+
+        return new UserInDistSqlTerm(false, true, "person-in-dist-child", districtService).forPerson();
+    }
+
+    @Bean
+    public UserInSqlTerm personNotInDistChildSqlTerm(DistrictService districtService) {
+
+        return new UserInDistSqlTerm(true, true, "person-not-in-dist-child", districtService).forPerson();
     }
 
 

+ 5 - 3
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/PersonInPositionSqlTerm.java

@@ -5,6 +5,7 @@ import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
 import org.hswebframework.ezorm.rdb.render.SqlAppender;
 import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
 import org.hswebframework.web.dao.mybatis.mapper.AbstractSqlTermCustomer;
+import org.hswebframework.web.dao.mybatis.mapper.ChangedTermValue;
 
 import java.util.List;
 
@@ -26,15 +27,16 @@ public class PersonInPositionSqlTerm extends AbstractSqlTermCustomer {
 
     @Override
     public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        ChangedTermValue termValue = createChangedTermValue(term);
+
         SqlAppender appender = new SqlAppender();
         //exists(select 1 from s_person_position tmp where tmp.person_id = t.owner_id and position_id =?)
         appender.add(not ? "not " : "", "exists(select 1 from s_person_position tmp where tmp.person_id =", createColumnName(column, tableAlias));
 
-        List<Object> positionIdList = BoostTermTypeMapper.convertList(column, term.getValue());
+        List<Object> positionIdList = BoostTermTypeMapper.convertList(column, termValue.getOld());
         if (!positionIdList.isEmpty()) {
             appender.add(" and tmp.position_id");
-            appendCondition(positionIdList, wherePrefix, appender);
-            term.setValue(positionIdList);
+            termValue.setValue(appendCondition(positionIdList, wherePrefix, appender));
         }
 
         appender.add(")");

+ 58 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInDepartmentSqlTerm.java

@@ -0,0 +1,58 @@
+package org.hswebframework.web.service.organizational.simple.terms;
+
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
+import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.ChangedTermValue;
+import org.hswebframework.web.service.organizational.DepartmentService;
+
+import java.util.List;
+
+
+/**
+ * 查询岗位中的用户
+ *
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+public class UserInDepartmentSqlTerm extends UserInSqlTerm {
+
+    private boolean not;
+
+    public UserInDepartmentSqlTerm(boolean not, boolean child, String term, DepartmentService departmentService) {
+        super(term, departmentService);
+        setChild(child);
+        this.not = not;
+    }
+
+    @Override
+    public String getTableName() {
+        return "_dept";
+    }
+
+    @Override
+    public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        ChangedTermValue termValue = createChangedTermValue(term);
+
+        SqlAppender appender = new SqlAppender();
+        appender.addSpc(not ? "not" : "", "exists(select 1 from s_person_position _tmp,s_position _pos,s_person _person");
+        if (isChild()) {
+            appender.addSpc(",s_department _dept");
+        }
+        appender.addSpc("where _person.u_id=_tmp.person_id and _tmp.position_id = _pos.u_id and _person.u_id=_tmp.person_id"
+                , "and", createColumnName(column, tableAlias), "=_person.user_id");
+        if (isChild()) {
+            appender.addSpc("and _dept.u_id=_pos.department_id");
+        }
+
+        List<Object> positionIdList = BoostTermTypeMapper.convertList(column, termValue.getOld());
+        if (!positionIdList.isEmpty()) {
+            appender.addSpc("and");
+            termValue.setValue(appendCondition(positionIdList, wherePrefix, appender, "_pos.department_id"));
+        }
+
+        appender.add(")");
+        return appender;
+    }
+}

+ 58 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInDistSqlTerm.java

@@ -0,0 +1,58 @@
+package org.hswebframework.web.service.organizational.simple.terms;
+
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
+import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.ChangedTermValue;
+import org.hswebframework.web.service.organizational.DistrictService;
+import org.hswebframework.web.service.organizational.PositionService;
+
+import java.util.List;
+
+
+/**
+ * 查询岗位中的用户
+ *
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+public class UserInDistSqlTerm extends UserInSqlTerm {
+
+    private boolean not;
+
+    public UserInDistSqlTerm(boolean not, boolean child, String term, DistrictService service) {
+        super(term, service);
+        setChild(child);
+        this.not = not;
+    }
+
+    @Override
+    public String getTableName() {
+        return "_dist";
+    }
+
+    @Override
+    public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        ChangedTermValue termValue = createChangedTermValue(term);
+
+        SqlAppender appender = new SqlAppender();
+        appender.addSpc(not ? "not" : "", "exists(select 1 from s_person_position _tmp,s_position _pos,s_person _person,s_department _dept,s_organization _org");
+        if (isChild()) {
+            appender.addSpc(",s_district _dist");
+        }
+        appender.addSpc("where _person.u_id=_tmp.person_id and _tmp.position_id = _pos.u_id and _person.u_id=_tmp.person_id and _dept.u_id=_pos.department_id and _org.u_id=_dept.org_id"
+                , "and", createColumnName(column, tableAlias), "=", isForPerson() ? "_tmp.person_id" : "_person.user_id");
+        if (isChild()) {
+            appender.addSpc("and _org.district_id=_dist.u_id");
+        }
+        List<Object> positionIdList = BoostTermTypeMapper.convertList(column, termValue.getOld());
+        if (!positionIdList.isEmpty()) {
+            appender.addSpc("and");
+            termValue.setValue(appendCondition(positionIdList, wherePrefix, appender, "_org.district_id"));
+        }
+
+        appender.add(")");
+        return appender;
+    }
+}

+ 58 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInOrgSqlTerm.java

@@ -0,0 +1,58 @@
+package org.hswebframework.web.service.organizational.simple.terms;
+
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
+import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.ChangedTermValue;
+import org.hswebframework.web.service.organizational.OrganizationalService;
+import org.hswebframework.web.service.organizational.PositionService;
+
+import java.util.List;
+
+
+/**
+ * 查询岗位中的用户
+ *
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+public class UserInOrgSqlTerm extends UserInSqlTerm {
+
+    private boolean not;
+
+    public UserInOrgSqlTerm(boolean not,boolean child, String term, OrganizationalService service) {
+        super(term, service);
+        setChild(child);
+        this.not = not;
+    }
+
+    @Override
+    public String getTableName() {
+        return "_org";
+    }
+
+    @Override
+    public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        ChangedTermValue termValue = createChangedTermValue(term);
+
+        SqlAppender appender = new SqlAppender();
+        appender.addSpc(not ? "not" : "", "exists(select 1 from s_person_position _tmp,s_position _pos,s_department _dept,s_person _person");
+        if (isChild()) {
+            appender.addSpc(",s_organization _org");
+        }
+        appender.addSpc("where _person.u_id=_tmp.person_id and _tmp.position_id = _pos.u_id and _person.u_id=_tmp.person_id and _dept.u_id=_pos.department_id"
+                , "and", createColumnName(column, tableAlias), "=",  isForPerson() ? "_tmp.person_id" : "_person.user_id");
+        if (isChild()) {
+            appender.addSpc("and _org.u_id=_dept.org_id");
+        }
+        List<Object> positionIdList = BoostTermTypeMapper.convertList(column, termValue.getOld());
+        if (!positionIdList.isEmpty()) {
+            appender.addSpc("and");
+            termValue.setValue(appendCondition(positionIdList, wherePrefix, appender, "_dept.org_id"));
+        }
+
+        appender.add(")");
+        return appender;
+    }
+}

+ 32 - 19
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInPositionSqlTerm.java

@@ -4,7 +4,8 @@ import org.hswebframework.ezorm.core.param.Term;
 import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
 import org.hswebframework.ezorm.rdb.render.SqlAppender;
 import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
-import org.hswebframework.web.dao.mybatis.mapper.AbstractSqlTermCustomer;
+import org.hswebframework.web.dao.mybatis.mapper.ChangedTermValue;
+import org.hswebframework.web.service.organizational.PositionService;
 
 import java.util.List;
 
@@ -15,34 +16,46 @@ import java.util.List;
  * @author zhouhao
  * @since 3.0.0-RC
  */
-public class UserInPositionSqlTerm extends AbstractSqlTermCustomer {
+public class UserInPositionSqlTerm extends UserInSqlTerm {
 
     private boolean not;
 
-    public UserInPositionSqlTerm(boolean not) {
-        super("user-" + (not ? "not-" : "") + "in-position");
+    public UserInPositionSqlTerm(boolean not, boolean child, String term, PositionService positionService) {
+        super(term, positionService);
+        setChild(child);
         this.not = not;
     }
 
+    @Override
+    public String getTableName() {
+        return "_pos";
+    }
+
     @Override
     public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        ChangedTermValue termValue = createChangedTermValue(term);
+
         SqlAppender appender = new SqlAppender();
-        //exists(
-        // select 1 from s_person_position tmp,s_person u
-        // where
-        // u.u_id=tmp.person_id
-        // and {column}=u.user_id
-        // and position_id =?
-        // )
-        appender.addSpc(not ? "not" : "", "exists(select 1 from s_person_position tmp,s_person u"
-                , "where u.u_id=tmp.person_id"
-                , "and", createColumnName(column, tableAlias), "=u.user_id");
-
-        List<Object> positionIdList = BoostTermTypeMapper.convertList(column, term.getValue());
+        appender.addSpc(not ? "not" : "", "exists(select 1 from s_person_position tmp_");
+        if (isChild()) {
+            appender.addSpc(",s_position _pos");
+        }
+        if (!isForPerson()) {
+            appender.addSpc(",s_person _person");
+        }
+
+        appender.addSpc("where ",
+                createColumnName(column, tableAlias), "=",
+                isForPerson() ? "_person.u_id=tmp_.person_id and _tmp.person_id" : "_person.user_id");
+
+        if (isChild()) {
+            appender.addSpc("and _pos.u_id=tmp_.position_id");
+        }
+
+        List<Object> positionIdList = BoostTermTypeMapper.convertList(column, termValue.getOld());
         if (!positionIdList.isEmpty()) {
-            appender.addSpc("and tmp.position_id");
-            appendCondition(positionIdList, wherePrefix, appender);
-            term.setValue(positionIdList);
+            appender.addSpc("and");
+            termValue.setValue(appendCondition(positionIdList, wherePrefix, appender, "tmp_.position_id"));
         }
 
         appender.add(")");

+ 87 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-local/src/main/java/org/hswebframework/web/service/organizational/simple/terms/UserInSqlTerm.java

@@ -0,0 +1,87 @@
+package org.hswebframework.web.service.organizational.simple.terms;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
+import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
+import org.hswebframework.web.commons.entity.TreeSupportEntity;
+import org.hswebframework.web.dao.mybatis.mapper.AbstractSqlTermCustomer;
+import org.hswebframework.web.service.QueryService;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+
+/**
+ * 查询岗位中的用户
+ *
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+public abstract class UserInSqlTerm<PK> extends AbstractSqlTermCustomer {
+
+
+    @Setter
+    @Getter
+    private boolean child;
+    @Getter
+    @Setter
+    private boolean forPerson;
+
+    QueryService<? extends TreeSupportEntity<PK>, PK> treeService;
+
+
+    public UserInSqlTerm<PK> forPerson() {
+        this.forPerson = true;
+        return this;
+    }
+
+    public UserInSqlTerm(String term, QueryService<? extends TreeSupportEntity<PK>, PK> treeService) {
+        super(term);
+        this.treeService = treeService;
+    }
+
+    public abstract String getTableName();
+
+    protected Object appendCondition(List<Object> values, String wherePrefix, SqlAppender appender, String column) {
+        if (!child) {
+            appender.addSpc(column);
+            return super.appendCondition(values, wherePrefix, appender);
+        } else {
+            List<String> paths = getTreePathByTerm(values)
+                    .stream()
+                    .map(path -> path.concat("%"))
+                    .collect(Collectors.toList());
+            int len = paths.size();
+            if (len == 0) {
+                appender.add("1=2");
+            } else {
+                appender.add("(");
+                for (int i = 0; i < len; i++) {
+                    if (i > 0) {
+                        appender.addSpc("or");
+                    }
+                    appender.add(getTableName() + ".path like #{", wherePrefix, ".value.value[", i, "]}");
+                }
+                appender.add(")");
+            }
+            return paths;
+        }
+    }
+
+
+    protected List<String> getTreePathByTerm(List<Object> termValue) {
+
+        List<PK> idList = ((List) termValue);
+
+        return treeService.selectByPk(idList)
+                .stream()
+                .map(TreeSupportEntity::getPath)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+
+    }
+}