diff --git a/coolstore-partner-common/coolstore-partner-common.iml b/coolstore-partner-common/coolstore-partner-common.iml
index 6ae94a6ff..4c0e16f82 100644
--- a/coolstore-partner-common/coolstore-partner-common.iml
+++ b/coolstore-partner-common/coolstore-partner-common.iml
@@ -71,5 +71,6 @@
+
\ No newline at end of file
diff --git a/coolstore-partner-common/pom.xml b/coolstore-partner-common/pom.xml
index af73c2d2a..9ba4384f6 100644
--- a/coolstore-partner-common/pom.xml
+++ b/coolstore-partner-common/pom.xml
@@ -70,6 +70,10 @@
com.coolstore
coolstore-base
+
+ com.google.guava
+ guava
+
\ No newline at end of file
diff --git a/coolstore-partner-common/src/main/java/com/cool/store/constants/CommonConstants.java b/coolstore-partner-common/src/main/java/com/cool/store/constants/CommonConstants.java
index bc8072e4a..8473b81f4 100644
--- a/coolstore-partner-common/src/main/java/com/cool/store/constants/CommonConstants.java
+++ b/coolstore-partner-common/src/main/java/com/cool/store/constants/CommonConstants.java
@@ -24,6 +24,13 @@ public class CommonConstants {
public static final int THREE_DAY_SECONDS = 60*60*24*3;
+ /**
+ * 企业开通锁存活时间
+ */
+ public static final int ENTERPRISE_OPEN_LOCK_TIMES = 4 * 60 * 60 * 1000;
+
+ public static final int ONE_DAY_SECONDS = 24 * 60 * 60;
+
/**
* 系统用户id
*/
@@ -34,6 +41,33 @@ public class CommonConstants {
public static final String WX_APP_SECRET_KEY = "wx_app_secret_key:{0}";
public static final String MINI_PROGRAM_SESSION_KEY = "mini_program_session_key:{0}:{1}";
+ public static final String MaxReconsumeTimes = "2";
+ public static final String ENTERPRISE_OPEN_STATUS_KEY = "enterprise_open_status:{0}_{1}";
+
+ public static final String ROOT_DEPT_ID_STR = "1";
+
+ public static final Integer DEAL_RECORD_MAX_SIZE = 1000;
+
+ /**
+ * 未分组区域id
+ */
+ public static final Long UNGROUPED_DEPT_ID = -2L;
+
+ /**
+ * 未分组区域名称
+ */
+ public static final String UNGROUPED_DEPT_NAME = "默认分组";
+
+ /**
+ * 拼接符 [
+ */
+ public static final String SQUAREBRACKETSLEFT = "[";
+
+ /**
+ * 拼接符 ]
+ */
+ public static final String SQUAREBRACKETSRIGHT = "]";
+
public static final int ZERO = 0;
public static final int ONE = 1;
diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/AIEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/AIEnum.java
new file mode 100644
index 000000000..e977c71e2
--- /dev/null
+++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/AIEnum.java
@@ -0,0 +1,26 @@
+package com.cool.store.enums;
+
+public enum AIEnum {
+
+ AI_NAME("AI用户"),
+ AI_USERID("a100000001"),
+ AI_ID("a100000000"),
+ AI_DEPARTMENT("[1]"),
+ AI_ROLES("20000000"),
+ AI_UUID("a100000002"),
+ AI_MOBILE("AIAdminUser");
+
+
+
+ private void setCode(String code) {
+ this.code = code;
+ }
+
+ private String code;
+ AIEnum(String code){
+ this.code=code;
+ }
+ public String getCode() {
+ return code;
+ }
+}
diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/EnterpriseStatusEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/EnterpriseStatusEnum.java
new file mode 100644
index 000000000..f94b7cd1f
--- /dev/null
+++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/EnterpriseStatusEnum.java
@@ -0,0 +1,52 @@
+package com.cool.store.enums;
+
+import java.util.Objects;
+
+/**
+ * @author zhangchenbiao
+ * @FileName: EnterpriseStatusEnum
+ * @Description:
+ * @date 2021-09-17 15:53
+ */
+public enum EnterpriseStatusEnum {
+
+ /**
+ * 状态-1 已删除 0初始 1正常 100冻结 88创建失败
+ */
+
+ DELETED(-1,"已删除"),
+ INIT(0,"初始"),
+ NORMAL(1,"正常"),
+ FREEZE(100,"冻结"),
+ CREATE_FAIL(88,"创建失败"),
+ ;
+
+
+ private int code;
+ private String message;
+
+ EnterpriseStatusEnum(int code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public static String getMessage(Integer code){
+ if(Objects.isNull(code)){
+ return "";
+ }
+ for (EnterpriseStatusEnum value : EnterpriseStatusEnum.values()) {
+ if(code.equals(value.code)){
+ return value.message;
+ }
+ }
+ return "";
+ }
+}
diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java
index f06982755..6f1461753 100644
--- a/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java
+++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java
@@ -39,7 +39,8 @@ public enum ErrorCodeEnum {
GET_APP_SECRET_ERROR(1021020, "获取secret异常", null),
WX_SERVICE_ERROR(1021021, "调用微信服务异常", null),
SESSION_KEY_ERROR(1021022, "sessionKey过期", null),
- GET_WECHAT_USER_INFO_FAIL(1021023,"获取小程序用户信息失败", null)
+ GET_WECHAT_USER_INFO_FAIL(1021023,"获取小程序用户信息失败", null),
+ FEISHU_SERVICE_ERROR(1021024,"飞书服务调用异常", null),
;
diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/RegionTypeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/RegionTypeEnum.java
new file mode 100644
index 000000000..b4b3b1c0b
--- /dev/null
+++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/RegionTypeEnum.java
@@ -0,0 +1,39 @@
+package com.cool.store.enums;
+
+/**
+ * @author Aaron
+ * @Description 业务统一返回码
+ * @date 2019/12/20
+ */
+public enum RegionTypeEnum {
+ /**
+ *
+ */
+ ROOT("root", "根节点"),
+
+
+ PATH("path", "区域"),
+
+
+ STORE("store", "门店");
+
+
+ private String type;
+
+
+ private String desc;
+
+ RegionTypeEnum(String type, String desc) {
+ this.type = type;
+ this.desc = desc;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+}
diff --git a/coolstore-partner-common/src/main/java/com/cool/store/utils/ListOptUtils.java b/coolstore-partner-common/src/main/java/com/cool/store/utils/ListOptUtils.java
new file mode 100644
index 000000000..9550aa4c1
--- /dev/null
+++ b/coolstore-partner-common/src/main/java/com/cool/store/utils/ListOptUtils.java
@@ -0,0 +1,42 @@
+package com.cool.store.utils;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.collections4.CollectionUtils;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author zhangchenbiao
+ * @FileName: ListUtils
+ * @Description: 集合处理
+ * @date 2022-03-04 20:04
+ */
+public class ListOptUtils {
+
+ public static List getIntersection(List listA, List listB){
+ if(CollectionUtils.isEmpty(listA) || CollectionUtils.isEmpty(listB)){
+ return Lists.newArrayList();
+ }
+ return listA.stream().filter(item -> listB.contains(item)).collect(Collectors.toList());
+ }
+
+
+ /**
+ * long集合转Stirng集合
+ * @param listA
+ * @return
+ */
+ public static List longListConvertStringList(List listA){
+ List result = Lists.newArrayList();
+ if(CollectionUtils.isEmpty(listA)){
+ return result;
+ }
+ for (Long temp:listA) {
+ result.add(String.valueOf(temp));
+ }
+ return result;
+ }
+
+
+}
diff --git a/coolstore-partner-dao/coolstore-partner-dao.iml b/coolstore-partner-dao/coolstore-partner-dao.iml
index 73fd10ece..751490130 100644
--- a/coolstore-partner-dao/coolstore-partner-dao.iml
+++ b/coolstore-partner-dao/coolstore-partner-dao.iml
@@ -28,7 +28,6 @@
-
@@ -94,6 +93,7 @@
+
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseDAO.java
index 26606d068..d049a40ca 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseDAO.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseDAO.java
@@ -1,7 +1,7 @@
package com.cool.store.dao;
+import com.cool.store.entity.EnterpriseDO;
import com.cool.store.mapper.EnterpriseMapper;
-import com.cool.store.model.entity.EnterpriseDO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseUserDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseUserDAO.java
index 3eaa573fd..198d34852 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseUserDAO.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseUserDAO.java
@@ -2,6 +2,7 @@ package com.cool.store.dao;
import com.cool.store.entity.EnterpriseUserDO;
import com.cool.store.mapper.EnterpriseUserMapper;
+import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@@ -41,4 +42,10 @@ public class EnterpriseUserDAO {
enterpriseUserMapper.batchInsertOrUpdate(eid, result);
}
+ public void batchUpdateDiffUserDiffRegionIds(String enterpriseId, List enterpriseUserList) {
+ if(StringUtils.isBlank(enterpriseId) || CollectionUtils.isEmpty(enterpriseUserList)){
+ return;
+ }
+ enterpriseUserMapper.batchUpdateDiffUserDiffRegionIds(enterpriseId, enterpriseUserList);
+ }
}
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/LoginRecordDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/LoginRecordDAO.java
index 271540ce0..504297226 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/LoginRecordDAO.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/LoginRecordDAO.java
@@ -1,7 +1,7 @@
package com.cool.store.dao;
+import com.cool.store.entity.LoginRecordDO;
import com.cool.store.mapper.LoginRecordMapper;
-import com.cool.store.model.entity.LoginRecordDO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/RegionDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/RegionDAO.java
index c2cdc0bb4..95cf4d128 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/RegionDAO.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/RegionDAO.java
@@ -1,7 +1,17 @@
package com.cool.store.dao;
+import com.cool.store.constants.CommonConstants;
+import com.cool.store.entity.RegionDO;
+import com.cool.store.enums.RegionTypeEnum;
+import com.cool.store.mapper.RegionMapper;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.ListUtils;
import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
/**
* @author zhangchenbiao
* @date 2023-05-19 02:59
@@ -9,4 +19,56 @@ import org.springframework.stereotype.Service;
@Service
public class RegionDAO {
+ @Resource
+ private RegionMapper regionMapper;
+
+ public List getRegionIdsBySynDingDeptIds(String eid, List synDingDeptIds) {
+ if (CollectionUtils.isEmpty(synDingDeptIds)) {
+ return new ArrayList<>();
+ }
+ return regionMapper.selectRegionIdsBySynDingDeptIds(eid, synDingDeptIds);
+ }
+
+ public List getRegionByRegionIds(String eid, List regionIds) {
+ if(CollectionUtils.isEmpty(regionIds)){
+ return Collections.emptyList();
+ }
+ return regionMapper.getRegionByRegionIds(eid, regionIds);
+ }
+
+ public RegionDO getUnclassifiedRegionDO(String enterpriseId) {
+ //先查询是否存在未分组区域
+ RegionDO unclassified = regionMapper.getUnclassifiedRegionDO(enterpriseId, CommonConstants.UNGROUPED_DEPT_NAME);
+ if (Objects.isNull(unclassified)) {
+ RegionDO regionDO = new RegionDO();
+ regionDO.setId(CommonConstants.UNGROUPED_DEPT_ID);
+ regionDO.setParentId(CommonConstants.ROOT_DEPT_ID_STR);
+ regionDO.setName(CommonConstants.UNGROUPED_DEPT_NAME);
+ regionDO.setRegionType(RegionTypeEnum.PATH.getType());
+ regionDO.setCreateName(CommonConstants.SYSTEM_USER_ID);
+ regionDO.setCreateTime(Calendar.getInstance().getTimeInMillis());
+ regionDO.setRegionPath("/" + CommonConstants.ROOT_DEPT_ID_STR + "/");
+ regionDO.setUnclassifiedFlag(CommonConstants.ONE);
+ insertRoot(enterpriseId, regionDO);
+ regionDO.setRegionId(regionDO.getId().toString());
+ return regionDO;
+ }
+ return unclassified;
+ }
+
+ public Long insertRoot(String eid, RegionDO regionDO) {
+ return regionMapper.insertRoot(eid, regionDO);
+ }
+
+ public void batchInsertRegions(List regionDOList, String eid){
+ regionMapper.batchInsertRegionsByDepartments(eid, regionDOList);
+ }
+
+
+ public Map getRegionSynDeptIdAndIdMapping(String eid, List syncDeptIds){
+ List regionDOS = regionMapper.selectRegionBySynDingDeptIds(eid, syncDeptIds);
+ return ListUtils.emptyIfNull(regionDOS)
+ .stream()
+ .collect(Collectors.toMap(RegionDO::getSynDingDeptId, RegionDO::getId, (r, e) -> r));
+ }
}
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/SysDepartmentDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/SysDepartmentDAO.java
index d552a2b05..2c86d7f3c 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/SysDepartmentDAO.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/SysDepartmentDAO.java
@@ -1,7 +1,16 @@
package com.cool.store.dao;
+import com.cool.store.dto.enterprise.QueryDeptChildDTO;
+import com.cool.store.entity.SysDepartmentDO;
+import com.cool.store.mapper.SysDepartmentMapper;
+import com.google.common.collect.Lists;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import java.util.List;
+
/**
* @author zhangchenbiao
* @date 2023-05-19 03:00
@@ -9,4 +18,21 @@ import org.springframework.stereotype.Service;
@Service
public class SysDepartmentDAO {
+ @Resource
+ private SysDepartmentMapper sysDepartmentMapper;
+
+ public void batchInsertOrUpdate(String enterpriseId, List deptList){
+ if(StringUtils.isBlank(enterpriseId) || CollectionUtils.isEmpty(deptList)){
+ return;
+ }
+ sysDepartmentMapper.batchInsertOrUpdate(deptList, enterpriseId);
+ }
+
+ public List getDeptChildListByParentId(String eid, String parentId){
+ if(StringUtils.isAnyBlank(eid, parentId)){
+ return Lists.newArrayList();
+ }
+ return sysDepartmentMapper.getDeptChildListByParentId(eid, parentId);
+ }
+
}
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/UserRegionMappingDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/UserRegionMappingDAO.java
index fa85070a7..4a6a488aa 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/UserRegionMappingDAO.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/UserRegionMappingDAO.java
@@ -1,7 +1,16 @@
package com.cool.store.dao;
+import com.cool.store.entity.UserRegionMappingDO;
+import com.cool.store.mapper.UserRegionMappingMapper;
+import com.google.common.collect.Lists;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.stream.Collectors;
+
/**
* @author zhangchenbiao
* @date 2023-05-19 03:00
@@ -9,4 +18,36 @@ import org.springframework.stereotype.Service;
@Service
public class UserRegionMappingDAO {
+ @Resource
+ private UserRegionMappingMapper userRegionMappingMapper;
+
+
+ public void deletedByUserIds(String enterpriseId, List userIds){
+ if (CollectionUtils.isEmpty(userIds)) {
+ return;
+ }
+ List distinctData = userIds.stream()
+ .distinct()
+ .collect(Collectors.toList());
+ userRegionMappingMapper.deletedByUserIds(enterpriseId, distinctData);
+ }
+
+ public void batchInsertRegionMapping(String enterpriseId, List userRegionMappingDOS){
+ if (CollectionUtils.isEmpty(userRegionMappingDOS)) {
+ return;
+ }
+ List distinctData = userRegionMappingDOS.stream()
+ .distinct()
+ .collect(Collectors.toList());
+ userRegionMappingMapper.batchInsertRegionMapping(enterpriseId, distinctData);
+ }
+
+
+ public List listUserRegionMappingByUserId(String enterpriseId, List userIds){
+ if(StringUtils.isBlank(enterpriseId) || CollectionUtils.isEmpty(userIds)){
+ return Lists.newArrayList();
+ }
+ return userRegionMappingMapper.listUserRegionMappingByUserId(enterpriseId, userIds);
+ }
+
}
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseMapper.java
index 1e0c7543b..27aa1c6b3 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseMapper.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseMapper.java
@@ -1,6 +1,6 @@
package com.cool.store.mapper;
-import com.cool.store.model.entity.EnterpriseDO;
+import com.cool.store.entity.EnterpriseDO;
import org.apache.ibatis.annotations.Param;
/**
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java
index d37a776c6..2046db8c0 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java
@@ -40,4 +40,12 @@ public interface EnterpriseUserMapper {
*/
void batchInsertOrUpdate(@Param("enterpriseId") String enterpriseId, @Param("list") List users);
+ /**
+ * 批量更新不同用户 不同的userRegionids
+ * @param eid
+ * @param enterpriseUserDOList
+ * @return
+ */
+ Boolean batchUpdateDiffUserDiffRegionIds(@Param("eid") String eid, @Param("list") List enterpriseUserDOList);
+
}
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/LoginRecordMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/LoginRecordMapper.java
index 31ae001cb..7455d5688 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/LoginRecordMapper.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/LoginRecordMapper.java
@@ -1,6 +1,6 @@
package com.cool.store.mapper;
-import com.cool.store.model.entity.LoginRecordDO;
+import com.cool.store.entity.LoginRecordDO;
import org.apache.ibatis.annotations.Param;
/**
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/RegionMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/RegionMapper.java
index f09f9f91b..b55de54c6 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/RegionMapper.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/RegionMapper.java
@@ -3,6 +3,8 @@ package com.cool.store.mapper;
import com.cool.store.entity.RegionDO;
import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
/**
* @author zhangchenbiao
* @date 2023-05-19 02:59
@@ -22,4 +24,17 @@ public interface RegionMapper {
* dateTime:2023-05-19 02:59
*/
int updateByPrimaryKeySelective(@Param("record") RegionDO record, @Param("enterpriseId") String enterpriseId);
+
+ List selectRegionIdsBySynDingDeptIds(@Param("eid") String eid, @Param("synDingDeptIds") List synDingDeptIds);
+
+ List getRegionByRegionIds(@Param("eid") String eid, @Param("regionIds") List regionIds);
+
+
+ RegionDO getUnclassifiedRegionDO(@Param("enterpriseId") String enterpriseId, @Param("name")String name);
+
+ Long insertRoot(@Param("eid") String eid, @Param("region") RegionDO regionDO);
+
+ Integer batchInsertRegionsByDepartments(@Param("eid") String eid, @Param("regions") List regions);
+
+ List selectRegionBySynDingDeptIds(@Param("eid") String eid, @Param("synDingDeptIds") List synDingDeptIds);
}
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/SysDepartmentMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/SysDepartmentMapper.java
index aba1c9ea7..271a755f0 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/SysDepartmentMapper.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/SysDepartmentMapper.java
@@ -1,8 +1,11 @@
package com.cool.store.mapper;
+import com.cool.store.dto.enterprise.QueryDeptChildDTO;
import com.cool.store.entity.SysDepartmentDO;
import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
/**
* @author zhangchenbiao
* @date 2023-05-19 03:00
@@ -22,4 +25,8 @@ public interface SysDepartmentMapper {
* dateTime:2023-05-19 03:00
*/
int updateByPrimaryKeySelective(@Param("record") SysDepartmentDO record, @Param("enterpriseId") String enterpriseId);
+
+ void batchInsertOrUpdate(@Param("list") List sysDepartmentDOList, @Param("eid") String eid);
+
+ List getDeptChildListByParentId(@Param("eid") String eid, @Param("parentId") String parentId);
}
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/UserRegionMappingMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/UserRegionMappingMapper.java
index 63e34ca52..424168bbb 100644
--- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/UserRegionMappingMapper.java
+++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/UserRegionMappingMapper.java
@@ -3,6 +3,8 @@ package com.cool.store.mapper;
import com.cool.store.entity.UserRegionMappingDO;
import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
/**
* @author zhangchenbiao
* @date 2023-05-19 03:00
@@ -22,4 +24,10 @@ public interface UserRegionMappingMapper {
* dateTime:2023-05-19 03:00
*/
int updateByPrimaryKeySelective(@Param("record") UserRegionMappingDO record, @Param("enterpriseId") String enterpriseId);
+
+ void batchInsertRegionMapping(@Param("enterpriseId") String enterpriseId,@Param("userRegionMappingDOS") List userRegionMappingDOS);
+
+ void deletedByUserIds(@Param("enterpriseId") String enterpriseId,@Param("userIds") List userIds);
+
+ List listUserRegionMappingByUserId(@Param("enterpriseId") String enterpriseId, @Param("userIds") List userIds);
}
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/resources/mapper/EnterpriseMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/EnterpriseMapper.xml
index 26b1e8e48..cbe1d41d1 100644
--- a/coolstore-partner-dao/src/main/resources/mapper/EnterpriseMapper.xml
+++ b/coolstore-partner-dao/src/main/resources/mapper/EnterpriseMapper.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml
index 35fab65d4..36012708d 100644
--- a/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml
+++ b/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml
@@ -467,4 +467,17 @@
roles=values(roles),
jobnumber=values(jobnumber)
+
+
+
+ update enterprise_user_${eid}
+ set user_region_ids =
+
+ when #{item.userId} then #{item.userRegionIds}
+
+ where user_id in
+
+ #{item.userId}
+
+
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/resources/mapper/LoginRecordMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/LoginRecordMapper.xml
index 867fcb26e..b7494922b 100644
--- a/coolstore-partner-dao/src/main/resources/mapper/LoginRecordMapper.xml
+++ b/coolstore-partner-dao/src/main/resources/mapper/LoginRecordMapper.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/coolstore-partner-dao/src/main/resources/mapper/RegionMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/RegionMapper.xml
index 6a1680ad9..4cee3973a 100644
--- a/coolstore-partner-dao/src/main/resources/mapper/RegionMapper.xml
+++ b/coolstore-partner-dao/src/main/resources/mapper/RegionMapper.xml
@@ -202,4 +202,142 @@
where id = #{record.id}
+
+
+
+
+
+
+
+
+
+ insert ignore into region_${eid}
+ (
+ id,
+ region_id,
+ name,
+ parent_id,
+ group_id,
+ create_time,
+ syn_ding_dept_id,
+ create_name,
+ region_type,
+ region_path,
+ store_num,
+ unclassified_flag)
+ values
+ (
+ #{region.id, jdbcType=BIGINT},
+ #{region.regionId, jdbcType=VARCHAR},
+ #{region.name, jdbcType=VARCHAR},
+ #{region.parentId, jdbcType=VARCHAR},
+ #{region.groupId, jdbcType=VARCHAR},
+ #{region.createTime, jdbcType=BIGINT},
+ #{region.synDingDeptId, jdbcType=VARCHAR},
+ #{region.createName, jdbcType=VARCHAR},
+ #{region.regionType, jdbcType=VARCHAR},
+ #{region.regionPath},
+ #{region.storeNum},
+ #{region.unclassifiedFlag}
+ )
+
+
+
+ insert into region_${eid}
+ (
+ id,
+ name,
+ parent_id,
+ group_id,
+ create_time,
+ syn_ding_dept_id,
+ region_path,
+ region_type,
+ order_num,
+ create_name,
+ store_id
+ )
+ values
+
+ (
+ #{region.id},
+ #{region.name},
+ #{region.parentId},
+ #{region.groupId},
+ #{region.createTime},
+ #{region.synDingDeptId},
+ #{region.regionPath},
+ #{region.regionType},
+ #{region.orderNum},
+ #{region.createName},
+ #{region.storeId}
+ )
+
+ ON DUPLICATE KEY UPDATE
+ name=values(name), parent_id=values(parent_id), region_path=values(region_path),region_type=values(region_type),order_num=values(order_num)
+
+
+
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/resources/mapper/SysDepartmentMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/SysDepartmentMapper.xml
index 62368939b..7b6359ba9 100644
--- a/coolstore-partner-dao/src/main/resources/mapper/SysDepartmentMapper.xml
+++ b/coolstore-partner-dao/src/main/resources/mapper/SysDepartmentMapper.xml
@@ -197,4 +197,36 @@
where id = #{record.id}
+
+
+ insert into sys_department_${eid}
+ (
+ id,
+ name,
+ parent_id,
+ depart_order,
+ auto_add_user
+ ) values
+
+ (
+ #{it.id, jdbcType=BIGINT},
+ #{it.name, jdbcType=VARCHAR},
+ #{it.parentId, jdbcType=BIGINT},
+ #{it.departOrder, jdbcType=INTEGER},
+ #{it.autoAddUser, jdbcType=BOOLEAN}
+ )
+
+ ON DUPLICATE KEY UPDATE name=values(name), parent_id=values(parent_id)
+
+
+
\ No newline at end of file
diff --git a/coolstore-partner-dao/src/main/resources/mapper/UserRegionMappingMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/UserRegionMappingMapper.xml
index b487250f1..258e36805 100644
--- a/coolstore-partner-dao/src/main/resources/mapper/UserRegionMappingMapper.xml
+++ b/coolstore-partner-dao/src/main/resources/mapper/UserRegionMappingMapper.xml
@@ -80,4 +80,46 @@
where id = #{record.id}
+
+
+ delete from user_region_mapping_${enterpriseId} where user_id in
+
+ #{userId}
+
+
+
+
+ insert into user_region_mapping_${enterpriseId}
+ (
+ region_id,
+ user_id,
+ create_time,
+ update_time,
+ create_id,
+ update_id
+ )
+ values
+
+ (
+ #{entity.regionId},
+ #{entity.userId},
+ #{entity.createTime},
+ #{entity.updateTime},
+ #{entity.createId},
+ #{entity.updateId}
+ )
+
+
+
+
\ No newline at end of file
diff --git a/coolstore-partner-model/coolstore-partner-model.iml b/coolstore-partner-model/coolstore-partner-model.iml
index 90f710f02..7a1866b79 100644
--- a/coolstore-partner-model/coolstore-partner-model.iml
+++ b/coolstore-partner-model/coolstore-partner-model.iml
@@ -72,6 +72,7 @@
+
@@ -87,7 +88,6 @@
-
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AgentInfoDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AgentInfoDTO.java
new file mode 100644
index 000000000..c186905e0
--- /dev/null
+++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AgentInfoDTO.java
@@ -0,0 +1,39 @@
+package com.cool.store.dto.enterprise;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+public class AgentInfoDTO {
+
+ @JSONField(name = "agentid")
+ private Long agentId;
+
+ @JSONField(name = "appid")
+ private Long appId;
+
+ @JSONField(name = "auth_mode")
+ private Integer authMode;
+
+ public Long getAgentId() {
+ return agentId;
+ }
+
+ public void setAgentId(Long agentId) {
+ this.agentId = agentId;
+ }
+
+ public Long getAppId() {
+ return appId;
+ }
+
+ public void setAppId(Long appId) {
+ this.appId = appId;
+ }
+
+ public Integer getAuthMode() {
+ return authMode;
+ }
+
+ public void setAuthMode(Integer authMode) {
+ this.authMode = authMode;
+ }
+}
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthAgentInfoDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthAgentInfoDTO.java
new file mode 100644
index 000000000..fc4044aff
--- /dev/null
+++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthAgentInfoDTO.java
@@ -0,0 +1,22 @@
+package com.cool.store.dto.enterprise;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+import java.util.List;
+
+/**
+ * 企业标识信息
+ */
+public class AuthAgentInfoDTO {
+
+ @JSONField(name = "agent")
+ private List agentInfos;
+
+ public List getAgentInfos() {
+ return agentInfos;
+ }
+
+ public void setAgentInfos(List agentInfos) {
+ this.agentInfos = agentInfos;
+ }
+}
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthCorpInfoDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthCorpInfoDTO.java
new file mode 100644
index 000000000..3e43d84c2
--- /dev/null
+++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthCorpInfoDTO.java
@@ -0,0 +1,42 @@
+package com.cool.store.dto.enterprise;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+
+/**
+ * 授权企业信息
+ * @author zhangchenbiao
+ * @date 2022-01-18 04:40
+ */
+@Data
+public class AuthCorpInfoDTO {
+
+ @JSONField(name = "corp_logo_url")
+ private String corpLogoUrl;
+
+ @JSONField(name = "corp_name")
+ private String corpName;
+
+ @JSONField(name = "corpid")
+ private String corpId;
+
+ private String industry;
+
+ @JSONField(name = "auth_channel")
+ private String authChannel;
+
+ @JSONField(name = "auth_channel_type")
+ private String authChannelType;
+
+ @JSONField(name = "is_authenticated")
+ private boolean isAuthenticated;
+
+ @JSONField(name = "auth_level")
+ private int authLevel;
+
+ @JSONField(name = "corp_province")
+ private String corpProvince;
+ @JSONField(name = "corp_city")
+ private String corpCity;
+
+}
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthInfoDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthInfoDTO.java
new file mode 100644
index 000000000..88bb956d6
--- /dev/null
+++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthInfoDTO.java
@@ -0,0 +1,45 @@
+package com.cool.store.dto.enterprise;
+
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+/**
+ * 企业开通授权信息
+ * @author zhangchenbiao
+ * @date 2022-01-18 04:40
+ */
+public class AuthInfoDTO {
+
+ @JSONField(name = "auth_corp_info")
+ private AuthCorpInfoDTO authCorpInfo;
+
+ @JSONField(name = "auth_user_info")
+ private AuthUserInfoDTO authUserInfo;
+
+ @JSONField(name = "auth_info")
+ private AuthAgentInfoDTO authAgentInfo;
+
+ public AuthCorpInfoDTO getAuthCorpInfo() {
+ return authCorpInfo;
+ }
+
+ public void setAuthCorpInfo(AuthCorpInfoDTO authCorpInfo) {
+ this.authCorpInfo = authCorpInfo;
+ }
+
+ public AuthUserInfoDTO getAuthUserInfo() {
+ return authUserInfo;
+ }
+
+ public void setAuthUserInfo(AuthUserInfoDTO authUserInfo) {
+ this.authUserInfo = authUserInfo;
+ }
+
+ public AuthAgentInfoDTO getAuthAgentInfo() {
+ return authAgentInfo;
+ }
+
+ public void setAuthAgentInfo(AuthAgentInfoDTO authAgentInfo) {
+ this.authAgentInfo = authAgentInfo;
+ }
+}
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthScopeDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthScopeDTO.java
new file mode 100644
index 000000000..b6b3b6ada
--- /dev/null
+++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthScopeDTO.java
@@ -0,0 +1,36 @@
+package com.cool.store.dto.enterprise;
+
+import java.util.List;
+
+/**
+ * 钉钉通讯录授权范围
+ * @author zhangchenbiao
+ * @date 2022-01-18 04:40
+ */
+public class AuthScopeDTO {
+
+ /**
+ * 部门id
+ */
+ private List deptIdList;
+ /**
+ * 用户id
+ */
+ private List userIdList;
+
+ public List getDeptIdList() {
+ return deptIdList;
+ }
+
+ public void setDeptIdList(List deptIdList) {
+ this.deptIdList = deptIdList;
+ }
+
+ public List getUserIdList() {
+ return userIdList;
+ }
+
+ public void setUserIdList(List userIdList) {
+ this.userIdList = userIdList;
+ }
+}
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthUserInfoDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthUserInfoDTO.java
new file mode 100644
index 000000000..f4d868f06
--- /dev/null
+++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/AuthUserInfoDTO.java
@@ -0,0 +1,22 @@
+package com.cool.store.dto.enterprise;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+/**
+ * 授权用户信息
+ * @author zhangchenbiao
+ * @date 2022-01-18 04:40
+ */
+public class AuthUserInfoDTO {
+
+ @JSONField(name = "userId")
+ private String userId;
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+}
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/EnterpriseUserDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/EnterpriseUserDTO.java
index ad9c8295d..b5a341022 100644
--- a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/EnterpriseUserDTO.java
+++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/EnterpriseUserDTO.java
@@ -153,4 +153,44 @@ public class EnterpriseUserDTO implements Serializable {
return enterpriseUserDO;
}
+
+ public static EnterpriseUserDO convertEnterpriseUserDTO2EnterpriseUserDO(EnterpriseUserDTO dto){
+ if(dto == null){
+ return null;
+ }
+ EnterpriseUserDO enterpriseUserDO = new EnterpriseUserDO();
+ enterpriseUserDO.setName(dto.getName());
+ enterpriseUserDO.setId(dto.getId());
+ enterpriseUserDO.setUserId(dto.getUserId());
+ enterpriseUserDO.setTel(dto.getTel());
+ enterpriseUserDO.setWorkPlace(dto.getWorkPlace());
+ enterpriseUserDO.setRemark(dto.getRemark());
+ enterpriseUserDO.setMobile(dto.getMobile());
+ enterpriseUserDO.setEmail(dto.getEmail());
+ enterpriseUserDO.setOrgEmail(dto.getOrgEmail());
+ enterpriseUserDO.setActive(dto.getActive());
+ enterpriseUserDO.setOrderInDepts(dto.getOrderInDepts());
+ enterpriseUserDO.setIsAdmin(dto.getIsAdmin());
+ enterpriseUserDO.setIsBoss(dto.getIsBoss());
+ enterpriseUserDO.setDingid(dto.getDingid());
+ enterpriseUserDO.setUnionid(dto.getUnionid());
+ enterpriseUserDO.setIsHide(dto.getIsHide());
+ enterpriseUserDO.setPosition(dto.getPosition());
+ enterpriseUserDO.setAvatar(dto.getAvatar());
+ enterpriseUserDO.setExtattr(dto.getExtattr());
+ enterpriseUserDO.setIsEnterprise(dto.getIsEnterprise());
+ enterpriseUserDO.setRoles(dto.getRoles());
+ enterpriseUserDO.setIsLeader(dto.getIsLeader());
+ enterpriseUserDO.setCreateTime(dto.getCreateTime());
+ enterpriseUserDO.setLanguage(dto.getLanguage());
+ enterpriseUserDO.setIsLeaderInDepts(JSONObject.toJSONString(dto.getIsLeaderInDepts()));
+ enterpriseUserDO.setJobnumber(dto.getJobnumber());
+ enterpriseUserDO.setMonitoredDepartments(dto.getMonitoredDepartments());
+ /*enterpriseUserDO.setAppType(dto.getAppType());
+ enterpriseUserDO.setPassword(dto.getPassword());*/
+ enterpriseUserDO.setThirdOaUniqueFlag(dto.getThirdOaUniqueFlag());
+ return enterpriseUserDO;
+
+ }
+
}
\ No newline at end of file
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/QueryDeptChildDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/QueryDeptChildDTO.java
new file mode 100644
index 000000000..92006bcc1
--- /dev/null
+++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/QueryDeptChildDTO.java
@@ -0,0 +1,23 @@
+package com.cool.store.dto.enterprise;
+
+import lombok.Data;
+
+/**
+ * @author 邵凌志
+ * @date 2020/12/9 16:29
+ */
+@Data
+public class QueryDeptChildDTO {
+
+ private String id;
+
+ private String parentId;
+
+ private String name;
+ /**
+ * 部门次序
+ */
+ private Integer departOrder;
+
+ private String path;
+}
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/SysDepartmentDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/SysDepartmentDTO.java
new file mode 100644
index 000000000..94c996b8e
--- /dev/null
+++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/enterprise/SysDepartmentDTO.java
@@ -0,0 +1,185 @@
+package com.cool.store.dto.enterprise;
+
+import com.cool.store.constants.CommonConstants;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Objects;
+
+
+/**
+ * @ClassName SysDepartmentDO
+ * @Description
+ * @author 王春辉
+ */
+@Data
+public class SysDepartmentDTO {
+ /**
+ * 部门id
+ */
+ private String id;
+
+ /**
+ * 部门名称
+ */
+ private String name;
+
+ /**
+ * 父部门id,根部门为1
+ */
+ private String parentId;
+
+ /**
+ * 在父部门中的次序值
+ */
+ private Integer departOrder;
+
+ /**
+ * 是否同步创建一个关联此部门的企业群, true表示是, false表示不是
+ */
+ private Boolean createDeptGroup;
+
+ /**
+ * 当群已经创建后,是否有新人加入部门会自动加入该群, true表示是, false表示不是
+ */
+ private Boolean autoAddUser;
+
+ /**
+ * 是否隐藏部门, true表示隐藏, false表示显示
+ */
+ private Boolean depHiding;
+
+ /**
+ * 可以查看指定隐藏部门的其他部门列表,如果部门隐藏,则此值生效,取值为其他的部门id组成的的字符串,使用|符号进行分割
+ */
+ private String deptPerimits;
+
+ /**
+ * 可以查看指定隐藏部门的其他人员列表,如果部门隐藏,则此值生效,取值为其他的人员userid组成的的字符串,使用|符号进行分割
+ */
+ private String userPerimits;
+
+ /**
+ * 是否本部门的员工仅可见员工自己, 为true时,本部门员工默认只能看到员工自己
+ */
+ private Boolean outerDept;
+
+ /**
+ * 本部门的员工仅可见员工自己为true时,可以配置额外可见部门,值为部门id组成的的字符串,使用|符号进行分割
+ */
+ private String outerPermitDepts;
+
+ /**
+ * 本部门的员工仅可见员工自己为true时,可以配置额外可见人员,值为userid组成的的字符串,使用| 符号进行分割
+ */
+ private String outerPermitUsers;
+
+ /**
+ * 企业群群主
+ */
+ private String orgDeptOwner;
+
+ /**
+ * 部门的主管列表,取值为由主管的userid组成的字符串,不同的userid使用|符号进行分割
+ */
+ private String deptManagerUseridList;
+
+
+ /**
+ * 该部门下所有的用户数,包括子部门
+ */
+ private Integer userCount;
+
+ /**
+ * 部门下所有未激活的用户数,包括子部门
+ */
+ private Integer unactiveUserCount;
+
+ /**
+ * 父级部门ids
+ */
+ private String parentIds;
+
+ /**
+ * 子部门ids
+ */
+ private String subIds;
+
+
+ public SysDepartmentDTO() {
+
+ }
+
+ /**
+ * 构造函数
+ *
+ * @param nodeId 节点Id
+ */
+ public SysDepartmentDTO(String nodeId) {
+ this.id = nodeId;
+ }
+
+ /**
+ * 构造函数
+ *
+ * @param nodeId 节点Id
+ * @param parentId 父节点Id
+ */
+
+ public SysDepartmentDTO(String nodeId, String parentId) {
+ this.id = nodeId;
+ this.parentId = parentId;
+ }
+
+
+ /**
+ * 设置部门名称
+ *
+ * @param name 部门名称
+ */
+ public void setName(String name) {
+ if (StringUtils.isNotBlank(name)) {
+ this.name = name.replaceAll("[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]", "");
+ if (StringUtils.isBlank(this.name)) {
+ this.name = "空";
+ }
+ }
+ }
+
+ /**
+ * 获取父部门id,根部门为1
+ *
+ * @return parent_id - 父部门id,根部门为1
+ */
+ public String getParentId() {
+ if (id.equals(CommonConstants.ROOT_DEPT_ID_STR)) {
+ return null;
+ }
+ return parentId;
+ }
+
+ @Override
+ public String toString() {
+ return "SysDepartment{" +
+ "id=" + id +
+ ", parentId=" + parentId + ",name='" + name + '\'' +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ SysDepartmentDTO that = (SysDepartmentDTO) o;
+ return Objects.equals(id, that.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id);
+ }
+}
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/EnterpriseDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/EnterpriseDO.java
similarity index 98%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/EnterpriseDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/EnterpriseDO.java
index 0e99d6836..a94dd78fc 100644
--- a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/EnterpriseDO.java
+++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/EnterpriseDO.java
@@ -1,13 +1,14 @@
-package com.cool.store.model.entity;
+package com.cool.store.entity;
import io.swagger.annotations.ApiModelProperty;
-import java.io.Serializable;
-import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+import java.io.Serializable;
+import java.util.Date;
+
/**
*
* @author zhangchenbiao
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyAdvancedSettingDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyAdvancedSettingDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyAdvancedSettingDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyAdvancedSettingDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyContentInfoDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyContentInfoDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyContentInfoDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyContentInfoDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyIntendDevZoneInfoDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyIntendDevZoneInfoDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyIntendDevZoneInfoDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyIntendDevZoneInfoDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyIntendDevelopementMappingDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyIntendDevelopementMappingDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyIntendDevelopementMappingDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyIntendDevelopementMappingDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyOpenAreaInfoDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyOpenAreaInfoDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyOpenAreaInfoDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyOpenAreaInfoDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerBaseInfoDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerBaseInfoDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerBaseInfoDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerBaseInfoDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerCertificationInfoDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerCertificationInfoDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerCertificationInfoDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerCertificationInfoDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerClerkDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerClerkDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerClerkDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerClerkDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerIntentInfoDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerIntentInfoDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerIntentInfoDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerIntentInfoDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerInterviewDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerInterviewDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerInterviewDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerInterviewDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerInterviewLogDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerInterviewLogDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerInterviewLogDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerInterviewLogDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerInterviewPlanDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerInterviewPlanDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerInterviewPlanDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerInterviewPlanDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerLineInfoDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerLineInfoDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerLineInfoDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerLineInfoDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerTaskInfoLogDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerTaskInfoLogDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerTaskInfoLogDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerTaskInfoLogDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerUserInfoDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerUserInfoDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerUserInfoDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerUserInfoDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerUserPlatformBindDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerUserPlatformBindDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyPartnerUserPlatformBindDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerUserPlatformBindDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyWorkflowStageDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyWorkflowStageDO.java
similarity index 100%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/HyWorkflowStageDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/HyWorkflowStageDO.java
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/LoginRecordDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/LoginRecordDO.java
similarity index 93%
rename from coolstore-partner-model/src/main/java/com/cool/store/model/entity/LoginRecordDO.java
rename to coolstore-partner-model/src/main/java/com/cool/store/entity/LoginRecordDO.java
index bbba5c6ec..9f589d97f 100644
--- a/coolstore-partner-model/src/main/java/com/cool/store/model/entity/LoginRecordDO.java
+++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/LoginRecordDO.java
@@ -1,12 +1,13 @@
-package com.cool.store.model.entity;
+package com.cool.store.entity;
import io.swagger.annotations.ApiModelProperty;
-import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+import java.io.Serializable;
+
/**
*
* @author zhangchenbiao
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/RegionDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/RegionDO.java
index ade3f4e7e..1c016688d 100644
--- a/coolstore-partner-model/src/main/java/com/cool/store/entity/RegionDO.java
+++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/RegionDO.java
@@ -6,6 +6,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
/**
*
@@ -28,7 +29,7 @@ public class RegionDO implements Serializable {
private String name;
@ApiModelProperty("父区域id")
- private Long parentId;
+ private String parentId;
@ApiModelProperty("阿里云分组id")
private String groupId;
@@ -74,4 +75,15 @@ public class RegionDO implements Serializable {
@ApiModelProperty("第三方唯一id")
private String thirdDeptId;
+
+ public String getFullRegionPath() {
+ if(id != null && id == 1L){
+ return "/1/";
+ }
+ if (StringUtils.isNotBlank(regionPath)) {
+ return regionPath + id + "/";
+ } else {
+ return "/" + id + "/";
+ }
+ }
}
\ No newline at end of file
diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/EnterpriseUserRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/EnterpriseUserRequest.java
new file mode 100644
index 000000000..cf5dbe0b7
--- /dev/null
+++ b/coolstore-partner-model/src/main/java/com/cool/store/request/EnterpriseUserRequest.java
@@ -0,0 +1,26 @@
+package com.cool.store.request;
+
+
+import com.cool.store.entity.EnterpriseUserDO;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @ClassName EnterpriseUserDO
+ * @Description 用于封装EnterpriseUserDO和部门字段
+ * @author 首亮
+ */
+@Data
+public class EnterpriseUserRequest {
+
+ private EnterpriseUserDO enterpriseUserDO;
+
+ private String department;
+
+ private String departments;
+
+ private List departmentLists;
+
+ private List leaderInDepts;
+}
diff --git a/coolstore-partner-service/coolstore-partner-service.iml b/coolstore-partner-service/coolstore-partner-service.iml
index 60ef29dc3..714241593 100644
--- a/coolstore-partner-service/coolstore-partner-service.iml
+++ b/coolstore-partner-service/coolstore-partner-service.iml
@@ -67,6 +67,7 @@
+
@@ -93,7 +94,6 @@
-
diff --git a/coolstore-partner-service/src/main/java/com/cool/store/consumer/EnterpriseInitListener.java b/coolstore-partner-service/src/main/java/com/cool/store/consumer/EnterpriseInitListener.java
new file mode 100644
index 000000000..dfe443392
--- /dev/null
+++ b/coolstore-partner-service/src/main/java/com/cool/store/consumer/EnterpriseInitListener.java
@@ -0,0 +1,80 @@
+package com.cool.store.consumer;
+
+import com.alibaba.fastjson.JSONObject;
+import com.aliyun.openservices.ons.api.Action;
+import com.aliyun.openservices.ons.api.ConsumeContext;
+import com.aliyun.openservices.ons.api.Message;
+import com.aliyun.openservices.ons.api.MessageListener;
+import com.cool.store.constants.CommonConstants;
+import com.cool.store.dto.enterprise.EnterpriseInitDTO;
+import com.cool.store.enums.EnterpriseStatusEnum;
+import com.cool.store.service.EnterpriseInitService;
+import com.cool.store.utils.RedisUtilPool;
+import com.coolstore.base.enums.AppTypeEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.text.MessageFormat;
+import java.util.Arrays;
+
+/**
+ * 企业开通初始化
+ *
+ * @author chenyupeng
+ * @since 2022/1/26
+ */
+@Slf4j
+@Service
+public class EnterpriseInitListener implements MessageListener {
+ @Resource
+ private EnterpriseInitService enterpriseInitService;
+ @Autowired
+ private RedisUtilPool redisUtilPool;
+
+ @Override
+ public Action consume(Message message, ConsumeContext consumeContext) {
+ if(message.getReconsumeTimes() + 1 >= Integer.parseInt(CommonConstants.MaxReconsumeTimes)){
+ //超过最大消费次数
+ return Action.CommitMessage;
+ }
+ String text = new String(message.getBody());
+ if(StringUtils.isBlank(text)){
+ return Action.CommitMessage;
+ }
+ String lockKey = "EnterpriseInitDataSync:" + message.getMsgID();
+ EnterpriseInitDTO enterpriseInitDTO = JSONObject.parseObject(text, EnterpriseInitDTO.class);
+ log.info("EnterpriseInitListener messageId:{},try times:{}, receive data :{}", message.getMsgID(), message.getReconsumeTimes(), JSONObject.toJSONString(enterpriseInitDTO));
+ boolean lock = redisUtilPool.setNxExpire(lockKey, message.getMsgID(), CommonConstants.ENTERPRISE_OPEN_LOCK_TIMES);
+ if (lock) {
+ try {
+ String appType = enterpriseInitDTO.getAppType();
+ String enterpriseStatusKey = MessageFormat.format(CommonConstants.ENTERPRISE_OPEN_STATUS_KEY, enterpriseInitDTO.getCorpId(), enterpriseInitDTO.getAppType());
+ enterpriseInitService.enterpriseInit(enterpriseInitDTO.getCorpId(), AppTypeEnum.getAppType(enterpriseInitDTO.getAppType()),
+ enterpriseInitDTO.getEid(), enterpriseInitDTO.getDbName(), enterpriseInitDTO.getUserId());
+ enterpriseInitService.sendOpenSucceededMsg(enterpriseInitDTO.getCorpId(), enterpriseInitDTO.getAppType(), Arrays.asList(enterpriseInitDTO.getUserId()));
+ //更新企业开通缓存状态
+ redisUtilPool.setString(enterpriseStatusKey, String.valueOf(EnterpriseStatusEnum.NORMAL.getCode()), CommonConstants.ONE_DAY_SECONDS);
+ return Action.CommitMessage;
+ } catch (Exception e) {
+ log.error("has exception", e);
+ } finally {
+ redisUtilPool.delKey(lockKey);
+ }
+ }
+ return Action.CommitMessage;
+ }
+
+
+}
+
+
+
+
+
+
+
+
+
diff --git a/coolstore-partner-service/src/main/java/com/cool/store/consumer/EnterpriseScriptListener.java b/coolstore-partner-service/src/main/java/com/cool/store/consumer/EnterpriseScriptListener.java
new file mode 100644
index 000000000..91d2faf8b
--- /dev/null
+++ b/coolstore-partner-service/src/main/java/com/cool/store/consumer/EnterpriseScriptListener.java
@@ -0,0 +1,52 @@
+package com.cool.store.consumer;
+
+import com.alibaba.fastjson.JSON;
+import com.aliyun.openservices.ons.api.Action;
+import com.aliyun.openservices.ons.api.ConsumeContext;
+import com.aliyun.openservices.ons.api.Message;
+import com.aliyun.openservices.ons.api.MessageListener;
+import com.cool.store.dto.enterprise.EnterpriseOpenMsg;
+import com.cool.store.service.EnterpriseInitService;
+import com.coolstore.base.enums.RocketMqTagEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * 执行企业端脚本消息监听
+ * @author :xugangkun
+ * @date :2022/2/11 15:32
+ */
+@Service
+@Slf4j
+public class EnterpriseScriptListener implements MessageListener {
+
+ @Resource
+ private EnterpriseInitService enterpriseInitService;
+
+ @Override
+ public Action consume(Message message, ConsumeContext consumeContext) {
+ String text = new String(message.getBody());
+ log.info("EnterpriseScriptListener messageId:{}, msg:{}", message.getMsgID(), text);
+ if(StringUtils.isBlank(text)){
+ return Action.CommitMessage;
+ }
+ switch (RocketMqTagEnum.getByTag(message.getTag())){
+ case ENTERPRISE_OPEN_ENTERPRISE_RUN_SCRIPT:
+ log.info("run Enterprise Script start");
+ EnterpriseOpenMsg msg = null;
+ try {
+ msg = JSON.parseObject(text, EnterpriseOpenMsg.class);
+ } catch (Exception e) {
+ log.error("invalid auth msg={}", text);
+ }
+ enterpriseInitService.runEnterpriseScript(msg);
+ break;
+ default:
+ break;
+ }
+ return Action.CommitMessage;
+ }
+}
diff --git a/coolstore-partner-service/src/main/java/com/cool/store/http/ISVHttpRequest.java b/coolstore-partner-service/src/main/java/com/cool/store/http/ISVHttpRequest.java
index 5f2462cd0..95ac9483b 100644
--- a/coolstore-partner-service/src/main/java/com/cool/store/http/ISVHttpRequest.java
+++ b/coolstore-partner-service/src/main/java/com/cool/store/http/ISVHttpRequest.java
@@ -1,7 +1,10 @@
package com.cool.store.http;
import com.alibaba.fastjson.JSONObject;
+import com.cool.store.dto.enterprise.AuthInfoDTO;
+import com.cool.store.dto.enterprise.AuthScopeDTO;
import com.cool.store.dto.enterprise.EnterpriseUserDTO;
+import com.cool.store.dto.enterprise.SysDepartmentDTO;
import com.cool.store.dto.login.UserIdInfoDTO;
import com.cool.store.utils.RestTemplateUtil;
import com.coolstore.base.dto.ResultDTO;
@@ -10,6 +13,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
+import java.util.HashMap;
+import java.util.List;
import java.util.Objects;
/**
@@ -46,9 +51,13 @@ public class ISVHttpRequest {
public EnterpriseUserDTO getUserDetailByUserId(String corpId, String userId, String appType){
String url = isvDomain + "/isv/user/getUserDetail";
+ HashMap requestMap = new HashMap();
+ requestMap.put("corpId", corpId);
+ requestMap.put("userId", userId);
+ requestMap.put("appType", appType);
ResponseEntity responseEntity = null;
try {
- responseEntity = RestTemplateUtil.loadGet(url, ResultDTO.class);
+ responseEntity = RestTemplateUtil.get(url, ResultDTO.class, requestMap);
log.info("url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
if(Objects.nonNull(responseEntity.getBody()) && responseEntity.getBody().isSuccess()){
return JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getBody().getData()), EnterpriseUserDTO.class);
@@ -58,4 +67,115 @@ public class ISVHttpRequest {
}
return null;
}
+
+ public List getAdminUserList(String corpId, String appType){
+ String url = isvDomain + "/isv/corp/getAdminUserList";
+ HashMap requestMap = new HashMap();
+ requestMap.put("corpId", corpId);
+ requestMap.put("appType", appType);
+ ResponseEntity responseEntity = null;
+ try {
+ responseEntity = RestTemplateUtil.get(url, ResultDTO.class, requestMap);
+ log.info("url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
+ if(Objects.nonNull(responseEntity.getBody()) && responseEntity.getBody().isSuccess()){
+ return JSONObject.parseArray(JSONObject.toJSONString(responseEntity.getBody().getData()), String.class);
+ }
+ } catch (Exception e) {
+ log.info("调用isv出错{}", e);
+ }
+ return null;
+ }
+
+ public AuthInfoDTO getAuthInfo(String corpId, String appType){
+ String url = isvDomain + "/isv/corp/getAuthInfo";
+ HashMap requestMap = new HashMap();
+ requestMap.put("corpId", corpId);
+ requestMap.put("appType", appType);
+ ResponseEntity responseEntity = null;
+ try {
+ responseEntity = RestTemplateUtil.get(url, ResultDTO.class, requestMap);
+ log.info("url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
+ if(Objects.nonNull(responseEntity.getBody()) && responseEntity.getBody().isSuccess()){
+ return JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getBody().getData()), AuthInfoDTO.class);
+ }
+ } catch (Exception e) {
+ log.info("调用isv出错{}", e);
+ }
+ return null;
+ }
+
+ public List getDepartments(String corpId, String appType, String parentId){
+ String url = isvDomain + "/isv/corp/getDepartments";
+ HashMap requestMap = new HashMap();
+ requestMap.put("corpId", corpId);
+ requestMap.put("appType", appType);
+ requestMap.put("parentId", parentId);
+ ResponseEntity responseEntity = null;
+ try {
+ responseEntity = RestTemplateUtil.get(url, ResultDTO.class, requestMap);
+ log.info("url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
+ if(Objects.nonNull(responseEntity.getBody()) && responseEntity.getBody().isSuccess()){
+ return JSONObject.parseArray(JSONObject.toJSONString(responseEntity.getBody().getData()), SysDepartmentDTO.class);
+ }
+ } catch (Exception e) {
+ log.info("调用isv出错{}", e);
+ }
+ return null;
+ }
+
+ public AuthScopeDTO getAuthScope(String corpId, String appType){
+ String url = isvDomain + "/isv/corp/getAuthScope";
+ HashMap requestMap = new HashMap();
+ requestMap.put("corpId", corpId);
+ requestMap.put("appType", appType);
+ ResponseEntity responseEntity = null;
+ try {
+ responseEntity = RestTemplateUtil.get(url, ResultDTO.class, requestMap);
+ log.info("url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
+ if(Objects.nonNull(responseEntity.getBody()) && responseEntity.getBody().isSuccess()){
+ return JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getBody().getData()), AuthScopeDTO.class);
+ }
+ } catch (Exception e) {
+ log.info("调用isv出错{}", e);
+ }
+ return null;
+ }
+
+ public List getDepartmentUsers(String corpId, String appType, String deptId){
+ String url = isvDomain + "/isv/corp/getDepartmentUsers";
+ HashMap requestMap = new HashMap();
+ requestMap.put("corpId", corpId);
+ requestMap.put("appType", appType);
+ requestMap.put("deptId", deptId);
+ ResponseEntity responseEntity = null;
+ try {
+ responseEntity = RestTemplateUtil.get(url, ResultDTO.class, requestMap);
+ log.info("url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
+ if(Objects.nonNull(responseEntity.getBody()) && responseEntity.getBody().isSuccess()){
+ return JSONObject.parseArray(JSONObject.toJSONString(responseEntity.getBody().getData()), EnterpriseUserDTO.class);
+ }
+ } catch (Exception e) {
+ log.info("调用isv出错{}", e);
+ }
+ return null;
+ }
+
+ public List getUserDetailByUserIds(String corpId, List userIdList, String appType) {
+ String url = isvDomain + "/isv/corp/getDepartmentUsers";
+ HashMap requestMap = new HashMap();
+ requestMap.put("corpId", corpId);
+ requestMap.put("appType", appType);
+ requestMap.put("userIds", userIdList);
+ ResponseEntity responseEntity = null;
+ try {
+ responseEntity = RestTemplateUtil.get(url, ResultDTO.class, requestMap);
+ log.info("url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
+ if(Objects.nonNull(responseEntity.getBody()) && responseEntity.getBody().isSuccess()){
+ return JSONObject.parseArray(JSONObject.toJSONString(responseEntity.getBody().getData()), EnterpriseUserDTO.class);
+ }
+ } catch (Exception e) {
+ log.info("调用isv出错{}", e);
+ }
+ return null;
+ }
}
diff --git a/coolstore-partner-service/src/main/java/com/cool/store/http/WechatRest.java b/coolstore-partner-service/src/main/java/com/cool/store/http/WechatRest.java
index 99eb8ba81..6019d9ac1 100644
--- a/coolstore-partner-service/src/main/java/com/cool/store/http/WechatRest.java
+++ b/coolstore-partner-service/src/main/java/com/cool/store/http/WechatRest.java
@@ -8,9 +8,12 @@ import com.cool.store.exception.ServiceException;
import com.cool.store.utils.RestTemplateUtil;
import com.coolstore.base.dto.ResultDTO;
import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.crypto.hash.Hash;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
/**
@@ -25,9 +28,13 @@ public class WechatRest {
public CodeSessionDTO miniProgramJsCodeSession(String appId, String secret, String jsCode){
String url = "https://api.weixin.qq.com/sns/jscode2session";
+ Map requestMap = new HashMap();
+ requestMap.put("appId", appId);
+ requestMap.put("secret", secret);
+ requestMap.put("jsCode", jsCode);
ResponseEntity responseEntity = null;
try {
- responseEntity = RestTemplateUtil.loadGet(url, CodeSessionDTO.class);
+ responseEntity = RestTemplateUtil.get(url, CodeSessionDTO.class);
log.info("url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
if(Objects.nonNull(responseEntity.getBody()) && responseEntity.getBody().isSuccess()){
return responseEntity.getBody();
diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseInitService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseInitService.java
new file mode 100644
index 000000000..be372b20e
--- /dev/null
+++ b/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseInitService.java
@@ -0,0 +1,22 @@
+package com.cool.store.service;
+
+import com.cool.store.dto.enterprise.EnterpriseOpenMsg;
+import com.coolstore.base.enums.AppTypeEnum;
+
+import java.util.List;
+
+/**
+ * @author zhangchenbiao
+ * @FileName: EnterpriseInitService
+ * @Description:
+ * @date 2023-05-29 15:43
+ */
+public interface EnterpriseInitService {
+
+ void runEnterpriseScript(EnterpriseOpenMsg msg);
+
+
+ void enterpriseInit(String cropId, AppTypeEnum appType, String eid, String dbName, String openUserId);
+
+ void sendOpenSucceededMsg(String corpId, String appType, List userList);
+}
diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseUserService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseUserService.java
new file mode 100644
index 000000000..189f438fc
--- /dev/null
+++ b/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseUserService.java
@@ -0,0 +1,15 @@
+package com.cool.store.service;
+
+import java.util.List;
+
+/**
+ * @author zhangchenbiao
+ * @FileName: EnterpriseUserService
+ * @Description: 用户service
+ * @date 2023-05-29 19:58
+ */
+public interface EnterpriseUserService {
+
+ void updateUserRegionPathList(String enterpriseId, List userIds);
+
+}
diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseInitServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseInitServiceImpl.java
index b767a2343..2eb683cf6 100644
--- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseInitServiceImpl.java
+++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseInitServiceImpl.java
@@ -2,22 +2,32 @@ package com.cool.store.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
-import com.cool.store.dao.EnterpriseUserDAO;
-import com.cool.store.dao.EnterpriseUserRoleDAO;
-import com.cool.store.dao.SysRoleDAO;
-import com.cool.store.dto.enterprise.EnterpriseInitDTO;
-import com.cool.store.dto.enterprise.EnterpriseOpenMsg;
-import com.cool.store.dto.enterprise.EnterpriseUserDTO;
-import com.cool.store.dto.enterprise.EnterpriseUserRole;
+import com.cool.store.dao.*;
+import com.cool.store.dto.enterprise.*;
import com.cool.store.entity.EnterpriseUserDO;
+import com.cool.store.entity.RegionDO;
+import com.cool.store.entity.SysDepartmentDO;
+import com.cool.store.entity.UserRegionMappingDO;
+import com.cool.store.enums.AIEnum;
+import com.cool.store.enums.ErrorCodeEnum;
+import com.cool.store.enums.RegionTypeEnum;
import com.cool.store.enums.RoleEnum;
+import com.cool.store.exception.ServiceException;
import com.cool.store.http.ISVHttpRequest;
import com.cool.store.mq.SimpleMessageService;
+import com.cool.store.request.EnterpriseUserRequest;
+import com.cool.store.service.EnterpriseInitService;
+import com.cool.store.service.EnterpriseUserService;
import com.cool.store.utils.DataSourceHelper;
+import com.cool.store.utils.ListOptUtils;
import com.cool.store.utils.ScriptUtil;
import com.cool.store.utils.UUIDUtils;
+import com.coolstore.base.enums.AppTypeEnum;
import com.coolstore.base.enums.RocketMqTagEnum;
+import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.EncodedResource;
@@ -25,6 +35,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
+import java.util.stream.Collectors;
/**
* @author zhangchenbiao
@@ -34,7 +45,7 @@ import java.util.*;
*/
@Slf4j
@Service
-public class EnterpriseInitServiceImpl {
+public class EnterpriseInitServiceImpl implements EnterpriseInitService {
@Resource
protected ScriptUtil scriptUtil;
@@ -48,7 +59,16 @@ public class EnterpriseInitServiceImpl {
private SimpleMessageService simpleMessageService;
@Resource
private ISVHttpRequest isvHttpRequest;
+ @Resource
+ private UserRegionMappingDAO userRegionMappingDAO;
+ @Resource
+ private RegionDAO regionDAO;
+ @Resource
+ private SysDepartmentDAO sysDepartmentDAO;
+ @Resource
+ private EnterpriseUserService enterpriseUserService;
+ @Override
public void runEnterpriseScript(EnterpriseOpenMsg msg) {
runEnterpriseScriptAndInitAuthUser(msg);
//抛出开始数据同步消息
@@ -62,6 +82,406 @@ public class EnterpriseInitServiceImpl {
simpleMessageService.send(JSONObject.toJSONString(enterpriseInitDTO), RocketMqTagEnum.ENTERPRISE_OPEN_DATA_SYNC);
}
+ @Override
+ public void enterpriseInit(String corpId, AppTypeEnum appTypeEnum, String eid, String dbName, String openUserId) {
+ try {
+ String appType = appTypeEnum.getValue();
+ //优先处理ai用户 保证能够超登
+ List authUsers = new ArrayList<>();
+ List adminUserList = isvHttpRequest.getAdminUserList(corpId, appType);
+ //添加ai用户
+ authUsers.add(getAIUser());
+ authUsers.addAll(getAdminList(adminUserList));
+ DataSourceHelper.changeToSpecificDataSource(dbName);
+ //获取开通授权信息
+ AuthInfoDTO authInfo = isvHttpRequest.getAuthInfo(corpId, appType);
+ //记录此次处理的用户的id,
+ Set handlerUserIds = new HashSet<>();
+ //处理ai用户
+ dealUsers(authUsers, eid, corpId, dbName, new HashMap<>(), null, authInfo, handlerUserIds);
+ //初始化部门
+ List sysDepartmentDTOS = initDept(corpId, eid, appType, dbName);
+ if(CollectionUtils.isEmpty(sysDepartmentDTOS)){
+ //构建跟部门
+ SysDepartmentDTO root = new SysDepartmentDTO();
+ root.setId(CommonConstants.ROOT_DEPT_ID_STR);
+ root.setName(authInfo.getAuthCorpInfo().getCorpName());
+ sysDepartmentDTOS.add(root);
+ }
+ //初始化根区域
+ initRootRegion(sysDepartmentDTOS, eid, dbName);
+ //初始化用户
+ initUser(sysDepartmentDTOS,corpId,eid,appType,dbName, adminUserList, authInfo, handlerUserIds);
+ } catch (Exception e) {
+ log.error("enterpriseInit enterpriseInit error,corpId:{},appType:{}", corpId, appTypeEnum.getValue(), e);
+ throw new ServiceException(ErrorCodeEnum.FEISHU_SERVICE_ERROR);
+ }
+ }
+
+ @Override
+ public void sendOpenSucceededMsg(String corpId, String appType, List userList) {
+ if(CollectionUtils.isEmpty(userList)){
+ return;
+ }
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("userList", userList);
+ jsonObject.put("appType", appType);
+ jsonObject.put("corpId", corpId);
+ simpleMessageService.send(jsonObject.toJSONString(), RocketMqTagEnum.OPEN_SUCCEEDED_MSG_QUEUE);
+ }
+
+ public void dealUsers(List users, String eid, String corpId, String dbName,
+ Map deptIdMap, Long unclassifiedRegionId, AuthInfoDTO authInfo, Set handlerUserIds) {
+
+ DataSourceHelper.changeToSpecificDataSource(dbName);
+ try {
+ insertUserRelatedInfo(users, eid, dbName, authInfo, handlerUserIds);
+ //处理用户和区域的关系
+ handlerUserRegionMapping(eid, users, unclassifiedRegionId);
+ } catch (Exception e) {
+ log.error("dealUsers insertUserRelatedInfo error, corpId={}", corpId, e);
+ }
+ }
+
+ public void insertUserRelatedInfo(List deptUsers, String eid, String dbName, AuthInfoDTO authInfo, Set handlerUserIds) {
+
+ if (CollectionUtils.isEmpty(deptUsers)) {
+ log.info("insertUserRelatedInfo deptUsers is empty,eid:{}",eid);
+ return;
+ }
+ log.info("insertUserRelatedInfo-{}, deptUsersSize:{}",eid, deptUsers.size());
+ DataSourceHelper.reset();
+ //提取enterpriseUserDO
+ List collect = ListUtils.emptyIfNull(deptUsers).stream()
+ .map(EnterpriseUserRequest::getEnterpriseUserDO)
+ .collect(Collectors.toList());
+ DataSourceHelper.changeToSpecificDataSource(dbName);
+ enterpriseUserDAO.batchInsertOrUpdate(eid, collect);
+ // 同步用户与角色的关系
+ Long masterRoleId = sysRoleDAO.getRoleIdByRoleEnum(eid, RoleEnum.MASTER.getRoleEnum());
+ Long employeeRoleId = sysRoleDAO.getRoleIdByRoleEnum(eid, RoleEnum.EMPLOYEE.getRoleEnum());
+ Long subMaster = sysRoleDAO.getRoleIdByRoleEnum(eid, RoleEnum.SUB_MASTER.getRoleEnum());
+ Long shopOwner = sysRoleDAO.getRoleIdByRoleEnum(eid, RoleEnum.SHOPOWNER.getRoleEnum());
+ List userRoles = new ArrayList<>();
+ collect.forEach(f -> {
+ if (Objects.nonNull(f)) {
+ //记录此次操作的用户
+ handlerUserIds.add(f.getUserId());
+ if (Objects.nonNull(f.getIsAdmin()) && f.getIsAdmin()) {
+ log.info("绑定管理员角色,{}", f.getUserId());
+ userRoles.add(new EnterpriseUserRole(masterRoleId.toString(), f.getUserId()));
+ //如果是开通人,再给子管理员权限
+ if (authInfo.getAuthUserInfo()!=null){
+ if (f.getUserId().equals(authInfo.getAuthUserInfo().getUserId())) {
+ userRoles.add(new EnterpriseUserRole(subMaster.toString(), f.getUserId()));
+ userRoles.add(new EnterpriseUserRole(shopOwner.toString(), f.getUserId()));
+ }
+ }
+ } else {
+ userRoles.add(new EnterpriseUserRole(employeeRoleId.toString(), f.getUserId()));
+ }
+ }
+ });
+ if (CollectionUtils.isNotEmpty(userRoles)) {
+ enterpriseUserRoleDAO.insertBatchUserRole(eid, userRoles);
+ }
+ }
+
+ /**
+ * 处理用户和区域的关系
+ * @param eid
+ * @param enterpriseUserRequests
+ */
+ public void handlerUserRegionMapping(String eid, List enterpriseUserRequests, Long unclassifiedRegionId) {
+ //用户区域映射关系
+ List userRegionMappings = new ArrayList<>();
+ List userIds = new ArrayList<>();
+ List regionIds = new ArrayList<>();
+ enterpriseUserRequests.forEach(user -> {
+ if (Objects.isNull(user.getEnterpriseUserDO())) {
+ return;
+ }
+ //移除不在授权范围内的部门
+ List deptIds = user.getDepartmentLists();
+ if (CollectionUtils.isEmpty(deptIds)) {
+ if (Objects.isNull(unclassifiedRegionId)) {
+ return;
+ }
+ //如果所属的部门未在授权部门内,挂在未分组
+ regionIds.add(unclassifiedRegionId);
+ } else {
+ //db查询区域表的数据,找到映射的区域
+ List regionIdsBySynDingDeptIds = regionDAO.getRegionIdsBySynDingDeptIds(eid, deptIds.stream().map(a -> a).collect(Collectors.toList()));
+ if (CollectionUtils.isNotEmpty(regionIdsBySynDingDeptIds)) {
+ regionIds.addAll(regionIdsBySynDingDeptIds);
+ } else {
+ //未找到映射关系
+ regionIds.add(unclassifiedRegionId);
+ }
+ }
+ //构建用户和区域的关系
+ ListUtils.emptyIfNull(regionIds)
+ .stream()
+ .forEach(item -> {
+ userRegionMappings.add(buildUserRegionMappingDO(user.getEnterpriseUserDO().getUserId(), item));
+
+ });
+ //清除用户区域的关系的regionIds用来存储下属映射的区域regionIds
+ regionIds.clear();
+ //构建我的下属
+ //移除不在授权范围内的部门的主管部门
+ List leaderDeptIds = user.getLeaderInDepts();
+ if (CollectionUtils.isNotEmpty(leaderDeptIds)) {
+ List regionIdsBySynDingDeptIds = regionDAO.getRegionIdsBySynDingDeptIds(eid, leaderDeptIds.stream().map(a->a).collect(Collectors.toList()));
+ if (CollectionUtils.isNotEmpty(regionIdsBySynDingDeptIds)) {
+ regionIds.addAll(regionIdsBySynDingDeptIds);
+ }
+ }
+ //用完即清除
+ regionIds.clear();
+ userIds.add(user.getEnterpriseUserDO().getUserId());
+ //触发条件,满足一个,就开始进行处理落库
+ if (userRegionMappings.size() > CommonConstants.DEAL_RECORD_MAX_SIZE) {
+ //先删除 后新增
+ //用户和区域的映射关系
+ userRegionMappingDAO.deletedByUserIds(eid, userIds);
+ userRegionMappingDAO.batchInsertRegionMapping(eid, userRegionMappings);
+ //调用订正用户表字段user_region_ids
+ enterpriseUserService.updateUserRegionPathList(eid, userIds);
+ userRegionMappings.clear();
+ userIds.clear();
+ }
+ });
+ if (CollectionUtils.isNotEmpty(userRegionMappings)) {
+ //先删除 后新增
+ //用户和区域的映射关系
+ userRegionMappingDAO.deletedByUserIds(eid, userIds);
+ userRegionMappingDAO.batchInsertRegionMapping(eid, userRegionMappings);
+ //调用订正用户表字段user_region_ids
+ enterpriseUserService.updateUserRegionPathList(eid, userIds);
+ }
+ }
+
+ public UserRegionMappingDO buildUserRegionMappingDO(String userId, Long regionId) {
+ UserRegionMappingDO userRegionMappingDO = new UserRegionMappingDO();
+ userRegionMappingDO.setUserId(userId);
+ userRegionMappingDO.setRegionId(String.valueOf(regionId));
+ return userRegionMappingDO;
+ }
+
+ public void initRootRegion(List sysDepartmentDTOS, String eid, String dbName) {
+
+ try {
+ Optional first = sysDepartmentDTOS.stream()
+ .filter(s -> Objects.equals(CommonConstants.ROOT_DEPT_ID_STR, s.getId())).findFirst();
+
+ if (first.isPresent()) {
+ DataSourceHelper.changeToSpecificDataSource(dbName);
+ SysDepartmentDTO sysDepartmentDTO = first.get();
+ RegionDO regionDO = new RegionDO();
+ regionDO.setId(1L);
+ regionDO.setRegionType(RegionTypeEnum.ROOT.getType());
+ regionDO.setName(sysDepartmentDTO.getName());
+ regionDO.setCreateName(CommonConstants.SYSTEM_USER_ID);
+ regionDO.setCreateTime(Calendar.getInstance().getTimeInMillis());
+ regionDO.setSynDingDeptId(CommonConstants.ROOT_DEPT_ID_STR);
+ regionDO.setUnclassifiedFlag(CommonConstants.ZERO);
+ regionDO.setRegionPath(null);
+ regionDO.setStoreNum(CommonConstants.ONE);
+ regionDAO.insertRoot(eid, regionDO);
+ //同步部门为区域节点
+ initRegionByDepartment(eid, CommonConstants.ROOT_DEPT_ID_STR);
+ }
+ } catch (Exception e) {
+ log.error("enterpriseInit initRootRegion error,eid:{}", eid, e);
+ throw new ServiceException(ErrorCodeEnum.FEISHU_SERVICE_ERROR);
+ }
+ }
+
+ public void initRegionByDepartment(String eid, String deptId) {
+ //首次获取 获取根部门下一级的所有数据
+ List queryDeptChildDTOS = sysDepartmentDAO.getDeptChildListByParentId(eid, deptId);
+ if (CollectionUtils.isEmpty(queryDeptChildDTOS)) {
+ return;
+ }
+ List regionDOS = new ArrayList<>();
+ List syncDingDeptIds = new ArrayList<>();
+ for (QueryDeptChildDTO deptChildDTO : queryDeptChildDTOS) {
+ //设置上级区域的path,方便后续的追溯
+ deptChildDTO.setPath("/" + deptId + "/");
+ RegionDO regionDO = new RegionDO();
+ regionDO.setParentId(String.valueOf(deptId));
+ regionDO.setName(deptChildDTO.getName());
+ regionDO.setCreateTime(System.currentTimeMillis());
+ regionDO.setUpdateTime(System.currentTimeMillis());
+ regionDO.setSynDingDeptId(String.valueOf(deptChildDTO.getId()));
+ regionDO.setRegionType(RegionTypeEnum.PATH.getType());
+ //次序值
+ regionDO.setOrderNum(deptChildDTO.getDepartOrder());
+ regionDO.setRegionPath("/" + CommonConstants.ROOT_DEPT_ID_STR + "/");
+ regionDO.setDeleted(Boolean.FALSE);
+ regionDOS.add(regionDO);
+ syncDingDeptIds.add(String.valueOf(deptChildDTO.getId()));
+ if (regionDOS.size() > CommonConstants.DEAL_RECORD_MAX_SIZE) {
+ //批量插入或更新
+ regionDAO.batchInsertRegions(regionDOS, eid);
+ regionDOS.clear();
+ }
+ }
+ if (CollectionUtils.isNotEmpty(regionDOS)) {
+ //批量插入或更新
+ regionDAO.batchInsertRegions(regionDOS, eid);
+ }
+ //递归调用,接着获取下一层级的数据进行处理
+ //获取region的id和部门id映射关系
+ Map regionIdMap = regionDAO.getRegionSynDeptIdAndIdMapping(eid, syncDingDeptIds);
+ handlerSubRegions(eid, queryDeptChildDTOS, regionIdMap);
+ }
+
+ public void initUser(List sysDepartmentDTOS, String corpId, String eid, String appType, String dbName,
+ List adminList, AuthInfoDTO authInfo, Set handlerUserIds) {
+ try {
+ //先查询是否存在未分组区域
+ RegionDO unclassifiedRegionDO = regionDAO.getUnclassifiedRegionDO(eid);
+ //获取通讯录授权范围
+ AuthScopeDTO authScope = isvHttpRequest.getAuthScope(corpId, appType);
+ List enterpriseUserDTOS = null;
+ if (CollectionUtils.isNotEmpty(authScope.getUserIdList())) {
+ //通过授权范围获取授权用户
+ enterpriseUserDTOS = isvHttpRequest.getUserDetailByUserIds(corpId, authScope.getUserIdList(), appType);
+ }
+ List deptIdLists = ListUtils.emptyIfNull(sysDepartmentDTOS).stream().map(SysDepartmentDTO::getId).collect(Collectors.toList());
+ //判断授权范围内是否有根节点,没有则移除
+ if (CollectionUtils.isNotEmpty(authScope.getDeptIdList()) && !authScope.getDeptIdList().contains(CommonConstants.ROOT_DEPT_ID_STR)) {
+ deptIdLists.remove(CommonConstants.ROOT_DEPT_ID_STR);
+ sysDepartmentDTOS = ListUtils.emptyIfNull(sysDepartmentDTOS)
+ .stream()
+ .filter(a -> !a.getId().equals(CommonConstants.ROOT_DEPT_ID_STR))
+ .collect(Collectors.toList());
+ }
+ Map deptIdMap = ListUtils.emptyIfNull(sysDepartmentDTOS).stream()
+ .filter(d -> d.getParentId() != null)
+ .collect(Collectors.toMap(SysDepartmentDTO::getId, SysDepartmentDTO::getParentId));
+ List authUsers = new ArrayList<>();
+
+ if (CollectionUtils.isNotEmpty(enterpriseUserDTOS)) {
+ EnterpriseUserRequest tempRequest;
+ EnterpriseUserDO tempDo;
+ for (EnterpriseUserDTO enterpriseUserDTO : enterpriseUserDTOS) {
+ tempDo = EnterpriseUserDTO.convertEnterpriseUserDTO2EnterpriseUserDO(enterpriseUserDTO);
+ tempRequest = new EnterpriseUserRequest();
+ tempRequest.setEnterpriseUserDO(tempDo);
+ tempRequest.setDepartmentLists(ListOptUtils.getIntersection(enterpriseUserDTO.getDepartmentLists(), deptIdLists));
+ tempRequest.setLeaderInDepts(ListOptUtils.getIntersection(enterpriseUserDTO.getIsLeaderInDepts(), deptIdLists));
+ authUsers.add(tempRequest);
+ }
+ }
+ dealUsers(authUsers,eid,corpId,dbName, deptIdMap, unclassifiedRegionDO.getId(), authInfo, handlerUserIds);
+ List deptUsers;
+ if (CollectionUtils.isNotEmpty(sysDepartmentDTOS)) {
+
+ for (SysDepartmentDTO sysDepartmentDTO : sysDepartmentDTOS) {
+ //通过授权部门获取授权用户
+ List departmentUsersQw = isvHttpRequest.getDepartmentUsers(corpId, sysDepartmentDTO.getId(), appType);
+ deptUsers = ListUtils.emptyIfNull(departmentUsersQw).stream().map(e -> {
+ EnterpriseUserRequest enterpriseUserRequest = new EnterpriseUserRequest();
+ enterpriseUserRequest.setEnterpriseUserDO(EnterpriseUserDTO.convertEnterpriseUserDTO2EnterpriseUserDO(e));
+ enterpriseUserRequest.setDepartmentLists(ListOptUtils.getIntersection(e.getDepartmentLists(), deptIdLists));
+ enterpriseUserRequest.setLeaderInDepts(ListOptUtils.getIntersection(e.getIsLeaderInDepts(), deptIdLists));
+ return enterpriseUserRequest;
+ }).collect(Collectors.toList());
+
+ if (CollectionUtils.isNotEmpty(deptUsers)) {
+ log.info("enterpriseInit initUser deptUsersInfo, corpId={}, deptId={}, userSize={}", corpId, sysDepartmentDTO.getId(), deptUsers.size());
+ dealUsers(deptUsers, eid, corpId, dbName, deptIdMap, unclassifiedRegionDO.getId(), authInfo, handlerUserIds);
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error("enterpriseInit initUser error,eid:{},appType:{}", eid, appType, e);
+ throw new ServiceException(ErrorCodeEnum.FEISHU_SERVICE_ERROR);
+ }
+ }
+
+ public void handlerSubRegions(String eid, List depts, Map regionIdMap) {
+ List regionDOS = new ArrayList<>();
+ //暂存一层级的数据
+ List results = new ArrayList<>();
+ List syncDingDeptIds = new ArrayList<>();
+ for (QueryDeptChildDTO dept : depts) {
+ //获取该层级的子节点处理
+ List childDTOS = sysDepartmentDAO.getDeptChildListByParentId(eid, String.valueOf(dept.getId()));
+ for (QueryDeptChildDTO deptChildDTO : childDTOS) {
+ //设置上级区域的path,方便后续的追溯
+ deptChildDTO.setPath(dept.getPath() + regionIdMap.get(deptChildDTO.getParentId()) + "/");
+ RegionDO regionDO = new RegionDO();
+ regionDO.setParentId(String.valueOf(regionIdMap.get(deptChildDTO.getParentId())));
+ regionDO.setCreateTime(System.currentTimeMillis());
+ regionDO.setName(deptChildDTO.getName());
+ regionDO.setSynDingDeptId(String.valueOf(deptChildDTO.getId()));
+ regionDO.setUpdateTime(System.currentTimeMillis());
+ regionDO.setOrderNum(deptChildDTO.getDepartOrder());
+ regionDO.setRegionType(RegionTypeEnum.PATH.getType());
+ //次序值
+ regionDO.setRegionPath(dept.getPath() + regionIdMap.get(deptChildDTO.getParentId()) + "/");
+ regionDO.setDeleted(Boolean.FALSE);
+ regionDOS.add(regionDO);
+ syncDingDeptIds.add(String.valueOf(deptChildDTO.getId()));
+ }
+ //暂存该层级的子节点数据
+ if (CollectionUtils.isNotEmpty(childDTOS)) {
+ results.addAll(childDTOS);
+ }
+ if (regionDOS.size() > CommonConstants.DEAL_RECORD_MAX_SIZE) {
+ //批量插入或更新
+ regionDAO.batchInsertRegions(regionDOS, eid);
+ regionDOS.clear();
+ }
+ }
+ if (CollectionUtils.isNotEmpty(regionDOS)) {
+ //批量插入或更新
+ regionDAO.batchInsertRegions(regionDOS, eid);
+ }
+ //递归调用
+ if (CollectionUtils.isNotEmpty(results)) {
+ //一次用完即清理
+ regionIdMap.clear();
+ //添加这一层的region的id和部门id映射关系
+ regionIdMap.putAll(regionDAO.getRegionSynDeptIdAndIdMapping(eid, syncDingDeptIds));
+ handlerSubRegions(eid, results, regionIdMap);
+ }
+ }
+
+
+ public List initDept(String corpId, String eid, String appType, String dbName) {
+ List departments = null;
+ try {
+ //获取所有部门
+ departments = isvHttpRequest.getDepartments(corpId, appType, null);
+ if (CollectionUtils.isEmpty(departments)) {
+ log.info("enterpriseInit initDept getDepartments is empty,corpId:{},appType:{}", corpId, appType);
+ return departments;
+ }
+ List sysDepartmentDOS = new ArrayList<>();
+ for (SysDepartmentDTO department : departments) {
+ sysDepartmentDOS.add(convertSysDepartmentDTO2SysDepartmentDO(department, appType));
+ if(sysDepartmentDOS.size() > CommonConstants.DEAL_RECORD_MAX_SIZE){
+ sysDepartmentDAO.batchInsertOrUpdate(eid, sysDepartmentDOS);
+ sysDepartmentDOS.clear();
+ }
+ }
+
+ DataSourceHelper.changeToSpecificDataSource(dbName);
+ if(CollectionUtils.isNotEmpty(sysDepartmentDOS)){
+ sysDepartmentDAO.batchInsertOrUpdate(eid, sysDepartmentDOS);
+ }
+ } catch (Exception e) {
+ log.error("enterpriseInit initDept error,corpId:{},appType:{}", corpId, appType, e);
+ throw new ServiceException(ErrorCodeEnum.FEISHU_SERVICE_ERROR);
+ }
+ return departments;
+ }
+
public void runEnterpriseScriptAndInitAuthUser(EnterpriseOpenMsg msg) {
DataSourceHelper.changeToSpecificDataSource(msg.getDbName());
//执行脚本代码
@@ -107,4 +527,74 @@ public class EnterpriseInitServiceImpl {
enterpriseUserRoleDAO.insertBatchUserRole(eid, userRoles);
}
+
+ private List getAdminList(List adminList) {
+ if(CollectionUtils.isEmpty(adminList)){
+ return Lists.newArrayList();
+ }
+ List resultList = new ArrayList<>();
+ if(CollectionUtils.isNotEmpty(adminList)){
+ for (String userId : adminList) {
+ EnterpriseUserRequest enterpriseUserRequest = new EnterpriseUserRequest();
+ EnterpriseUserDO enterpriseUserDO = new EnterpriseUserDO();
+ enterpriseUserDO.setId(userId);
+ enterpriseUserDO.setName(userId);
+ enterpriseUserDO.setUserId(userId);
+ enterpriseUserDO.setUnionid(userId);
+ enterpriseUserDO.setRoles(RoleEnum.MASTER.getId());
+ enterpriseUserDO.setIsAdmin(Boolean.TRUE);
+ enterpriseUserDO.setActive(Boolean.TRUE);
+ enterpriseUserRequest.setEnterpriseUserDO(enterpriseUserDO);
+ enterpriseUserRequest.setDepartment("[1]");
+ enterpriseUserRequest.setDepartments("[1]");
+ resultList.add(enterpriseUserRequest);
+ }
+ }
+ return resultList;
+ }
+
+ private EnterpriseUserRequest getAIUser() {
+ EnterpriseUserRequest enterpriseUserRequest = new EnterpriseUserRequest();
+ EnterpriseUserDO enterpriseUserDO = new EnterpriseUserDO();
+ enterpriseUserDO.setId(AIEnum.AI_ID.getCode());
+ enterpriseUserDO.setName(AIEnum.AI_NAME.getCode());
+ enterpriseUserDO.setUserId(AIEnum.AI_USERID.getCode());
+ enterpriseUserDO.setMobile(AIEnum.AI_MOBILE.getCode());
+ enterpriseUserDO.setRoles(AIEnum.AI_ROLES.getCode());
+ enterpriseUserDO.setUnionid(AIEnum.AI_UUID.getCode());
+ enterpriseUserDO.setIsAdmin(Boolean.TRUE);
+ enterpriseUserDO.setActive(Boolean.TRUE);
+ enterpriseUserRequest.setEnterpriseUserDO(enterpriseUserDO);
+ enterpriseUserRequest.setDepartment(AIEnum.AI_DEPARTMENT.getCode());
+ enterpriseUserRequest.setDepartments(AIEnum.AI_DEPARTMENT.getCode());
+ return enterpriseUserRequest;
+ }
+
+ public SysDepartmentDO convertSysDepartmentDTO2SysDepartmentDO(SysDepartmentDTO dto, String appType) {
+ if (dto == null) {
+ return null;
+ }
+ SysDepartmentDO sysDepartmentDO = new SysDepartmentDO();
+ sysDepartmentDO.setName(dto.getName());
+ sysDepartmentDO.setId(dto.getId());
+ sysDepartmentDO.setParentId(dto.getParentId());
+ sysDepartmentDO.setDepartOrder(dto.getDepartOrder());
+ sysDepartmentDO.setCreateDeptGroup(dto.getCreateDeptGroup());
+ sysDepartmentDO.setAutoAddUser(dto.getAutoAddUser());
+ sysDepartmentDO.setDepHiding(dto.getDepHiding());
+ sysDepartmentDO.setDeptPerimits(dto.getDeptPerimits());
+ sysDepartmentDO.setUserPerimits(dto.getUserPerimits());
+ sysDepartmentDO.setOuterDept(dto.getOuterDept());
+ sysDepartmentDO.setOuterPermitDepts(dto.getOuterPermitDepts());
+ sysDepartmentDO.setOuterPermitUsers(dto.getOuterPermitUsers());
+ sysDepartmentDO.setOrgDeptOwner(dto.getOrgDeptOwner());
+ sysDepartmentDO.setDeptManagerUseridList(dto.getDeptManagerUseridList());
+ sysDepartmentDO.setUserCount(dto.getUserCount());
+ sysDepartmentDO.setUnactiveUserCount(dto.getUnactiveUserCount());
+ sysDepartmentDO.setParentIds(dto.getParentIds());
+ sysDepartmentDO.setSubIds(dto.getSubIds());
+ return sysDepartmentDO;
+ }
+
+
}
diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseUserServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseUserServiceImpl.java
new file mode 100644
index 000000000..acdf4705c
--- /dev/null
+++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseUserServiceImpl.java
@@ -0,0 +1,105 @@
+package com.cool.store.service.impl;
+
+import com.cool.store.constants.CommonConstants;
+import com.cool.store.context.CurrentUser;
+import com.cool.store.dao.EnterpriseUserDAO;
+import com.cool.store.dao.RegionDAO;
+import com.cool.store.dao.UserRegionMappingDAO;
+import com.cool.store.entity.EnterpriseUserDO;
+import com.cool.store.entity.RegionDO;
+import com.cool.store.entity.UserRegionMappingDO;
+import com.cool.store.service.EnterpriseUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.ListUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author zhangchenbiao
+ * @FileName: EnterpriseUserServiceImpl
+ * @Description:
+ * @date 2023-05-29 19:58
+ */
+@Slf4j
+@Service
+public class EnterpriseUserServiceImpl implements EnterpriseUserService {
+
+ @Resource
+ private UserRegionMappingDAO userRegionMappingDAO;
+ @Resource
+ private RegionDAO regionDAO;
+ @Resource
+ private EnterpriseUserDAO enterpriseUserDAO;
+
+ @Override
+ public void updateUserRegionPathList(String enterpriseId, List userIds) {
+ if (CollectionUtils.isEmpty(userIds)) {
+ return;
+ }
+ //查询该人员的最新部门情况 同步到enterpriseUser 表usereginIds表中
+ List userRegionMappingDOS = userRegionMappingDAO.listUserRegionMappingByUserId(enterpriseId, userIds);
+ Map> userRegionMappingMap = ListUtils.emptyIfNull(userRegionMappingDOS)
+ .stream()
+ .collect(Collectors.groupingBy(UserRegionMappingDO::getUserId));
+ List regionIds = userRegionMappingDOS.stream()
+ .map(UserRegionMappingDO::getRegionId).distinct().collect(Collectors.toList());
+ List regionDOS = regionDAO.getRegionByRegionIds(enterpriseId, regionIds);
+ Map regionMap = regionDOS.stream()
+ .collect(Collectors.toMap(RegionDO::getRegionId, data -> data));
+
+ List enterpriseUserList= new ArrayList<>();
+ for (String userId:userIds) {
+ EnterpriseUserDO enterpriseUserDO = new EnterpriseUserDO();
+ enterpriseUserDO.setUserId(userId);
+ String regionPathString = "";
+ List regionDOList = new ArrayList<>();
+ //如果没有对应部门 默认未null 正常情况下不会出现userRegionId不为null的情况
+ enterpriseUserDO.setUserRegionIds(null);
+ List userRegionMappingList = userRegionMappingMap.get(userId);
+
+ //异常情况下处理
+ if (CollectionUtils.isEmpty(userRegionMappingList)){
+ log.info("getUserRegionPathListStr exception 该人员没有任何部门");
+ //查询未分组
+ RegionDO unclassifiedRegionDO = regionDAO.getUnclassifiedRegionDO(enterpriseId);
+ //将人添加到未分组中
+ addUserRegionMappingDO(enterpriseId,userId,unclassifiedRegionDO.getRegionId(),new CurrentUser());
+ regionDOList.add(unclassifiedRegionDO);
+ }
+
+ ListUtils.emptyIfNull(userRegionMappingList)
+ .stream()
+ .forEach(userRegionMappingDO -> {
+ RegionDO regionDO = regionMap.get(userRegionMappingDO.getRegionId());
+ if (Objects.nonNull(regionDO)){
+ regionDOList.add(regionDO);
+ }
+ });
+
+ regionPathString = regionDOList.stream()
+ .map(e -> e.getFullRegionPath()).collect(Collectors.joining(CommonConstants.COMMA));
+ if (StringUtils.isNotBlank(regionPathString)){
+ enterpriseUserDO.setUserRegionIds(CommonConstants.SQUAREBRACKETSLEFT+ regionPathString+ CommonConstants.SQUAREBRACKETSRIGHT);
+ }
+ enterpriseUserList.add(enterpriseUserDO);
+ }
+ enterpriseUserDAO.batchUpdateDiffUserDiffRegionIds(enterpriseId, enterpriseUserList);
+ }
+
+ private void addUserRegionMappingDO(String enterpriseId,String userId,String regionId,CurrentUser currentUser){
+ UserRegionMappingDO userRegionMappingDO = new UserRegionMappingDO();
+ userRegionMappingDO.setUserId(userId);
+ userRegionMappingDO.setRegionId(regionId);
+ userRegionMappingDO.setCreateId(currentUser.getUserId());
+ userRegionMappingDO.setUpdateId(currentUser.getUserId());
+ userRegionMappingDO.setCreateTime(System.currentTimeMillis());
+ userRegionMappingDO.setUpdateTime(System.currentTimeMillis());
+ //将用户添加到未分组
+ userRegionMappingDAO.batchInsertRegionMapping(enterpriseId, Arrays.asList(userRegionMappingDO));
+ }
+}
diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/LoginServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/LoginServiceImpl.java
index 6b0b8519a..6a1b502ae 100644
--- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/LoginServiceImpl.java
+++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/LoginServiceImpl.java
@@ -8,17 +8,14 @@ import com.cool.store.context.DataSourceContext;
import com.cool.store.dao.*;
import com.cool.store.dto.login.RefreshUser;
import com.cool.store.entity.EnterpriseConfigDO;
+import com.cool.store.entity.EnterpriseDO;
import com.cool.store.entity.EnterpriseUserDO;
import com.cool.store.entity.SysRoleDO;
-import com.cool.store.enums.AppTypeEnum;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.UserStatusEnum;
import com.cool.store.exception.ServiceException;
-import com.cool.store.model.entity.EnterpriseDO;
import com.cool.store.service.LoginService;
-import com.cool.store.utils.DataSourceHelper;
import com.cool.store.utils.RedisUtilPool;
-import com.github.xiaoymin.knife4j.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.RandomNumberGenerator;
@@ -27,7 +24,6 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Objects;
-import java.util.Optional;
/**
* @author zhangchenbiao
diff --git a/coolstore-partner-webb/coolstore-partner-webb.iml b/coolstore-partner-webb/coolstore-partner-webb.iml
index ffd8bbebe..6dda56531 100644
--- a/coolstore-partner-webb/coolstore-partner-webb.iml
+++ b/coolstore-partner-webb/coolstore-partner-webb.iml
@@ -33,6 +33,7 @@
+
@@ -58,7 +59,6 @@
-
diff --git a/coolstore-partner-webb/src/main/java/com/cool/store/config/TokenValidateFilter.java b/coolstore-partner-webb/src/main/java/com/cool/store/config/TokenValidateFilter.java
index 226c8648c..b03b49cae 100644
--- a/coolstore-partner-webb/src/main/java/com/cool/store/config/TokenValidateFilter.java
+++ b/coolstore-partner-webb/src/main/java/com/cool/store/config/TokenValidateFilter.java
@@ -40,7 +40,7 @@ public class TokenValidateFilter implements Filter {
private static List patternList =
- Lists.newArrayList("/web/check/ok","/check/ok", "/partner/doc.html","/**/test/**",
+ Lists.newArrayList("/web/check/ok","/check/ok", "/partner/pc/doc.html","/partner/pc/v2/api-docs","/**/test/**",
"/**/swagger*/**",
"/**/webjars/**");
diff --git a/coolstore-partner-webb/src/main/java/com/cool/store/controller/LoginController.java b/coolstore-partner-webb/src/main/java/com/cool/store/controller/LoginController.java
index 798e6ceed..249202bb8 100644
--- a/coolstore-partner-webb/src/main/java/com/cool/store/controller/LoginController.java
+++ b/coolstore-partner-webb/src/main/java/com/cool/store/controller/LoginController.java
@@ -1,6 +1,5 @@
package com.cool.store.controller;
-import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.dto.login.FeiShuLoginDTO;
import com.cool.store.dto.login.UserIdInfoDTO;
@@ -12,7 +11,6 @@ import com.cool.store.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@@ -35,7 +33,7 @@ public class LoginController {
private ISVHttpRequest isvHttpRequest;
- @PostMapping(value = "/v3/feiShuLogin")
+ @PostMapping(value = "/feiShuLogin")
public Object feiShuLogin(@RequestBody FeiShuLoginDTO param) {
log.info("feiShuLogin data={}", JSONObject.toJSONString(param));
String code = param.getCode();
diff --git a/coolstore-partner-webb/src/main/resources/application.properties b/coolstore-partner-webb/src/main/resources/application.properties
index a8be98017..dc6e86bd0 100644
--- a/coolstore-partner-webb/src/main/resources/application.properties
+++ b/coolstore-partner-webb/src/main/resources/application.properties
@@ -2,7 +2,7 @@ spring.application.name=coolstore-partner-webb
spring.profiles.active=@profileActive@
server.port=31000
-server.servlet.context-path=/partner
+server.servlet.context-path=/partner/pc
#logback
logging.config=classpath:logback-spring.xml
diff --git a/coolstore-partner-webc/coolstore-partner-webc.iml b/coolstore-partner-webc/coolstore-partner-webc.iml
index 558af1366..c63b946ff 100644
--- a/coolstore-partner-webc/coolstore-partner-webc.iml
+++ b/coolstore-partner-webc/coolstore-partner-webc.iml
@@ -33,6 +33,7 @@
+
@@ -58,7 +59,6 @@
-
diff --git a/coolstore-partner-webc/src/main/java/com/cool/store/config/TokenValidateFilter.java b/coolstore-partner-webc/src/main/java/com/cool/store/config/TokenValidateFilter.java
index 6d91370e4..8c12a2cb0 100644
--- a/coolstore-partner-webc/src/main/java/com/cool/store/config/TokenValidateFilter.java
+++ b/coolstore-partner-webc/src/main/java/com/cool/store/config/TokenValidateFilter.java
@@ -40,7 +40,7 @@ public class TokenValidateFilter implements Filter {
private static List patternList =
- Lists.newArrayList("/web/check/ok","/check/ok", "/partner/doc.html",
+ Lists.newArrayList("/web/check/ok","/check/ok", "/partner/mini/program/doc.html","/partner/mini/program/v2/api-docs",
"/**/swagger*/**",
"/**/webjars/**");
diff --git a/coolstore-partner-webc/src/main/java/com/cool/store/controller/MiniProgramAppController.java b/coolstore-partner-webc/src/main/java/com/cool/store/controller/MiniProgramAppController.java
index 67ccbddb6..8fd722852 100644
--- a/coolstore-partner-webc/src/main/java/com/cool/store/controller/MiniProgramAppController.java
+++ b/coolstore-partner-webc/src/main/java/com/cool/store/controller/MiniProgramAppController.java
@@ -23,7 +23,6 @@ import javax.validation.Valid;
@Api(tags = "微信小程序app接口")
@RestController
-@RequestMapping("/appApi/mini-program")
public class MiniProgramAppController {
@Resource
diff --git a/coolstore-partner-webc/src/main/resources/application.properties b/coolstore-partner-webc/src/main/resources/application.properties
index ab2696d52..7728a30a3 100644
--- a/coolstore-partner-webc/src/main/resources/application.properties
+++ b/coolstore-partner-webc/src/main/resources/application.properties
@@ -2,7 +2,7 @@ spring.application.name=coolstore-partner-webc
spring.profiles.active=@profileActive@
server.port=30900
-server.servlet.context-path=/partner
+server.servlet.context-path=/partner/mini/program
#logback
logging.config=classpath:logback-spring.xml
diff --git a/pom.xml b/pom.xml
index beef29113..e67c0a65f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -151,6 +151,11 @@
ons20190214
1.0.0
+
+ com.google.guava
+ guava
+ 20.0
+