feat(REQ-2106): 临时提交

This commit is contained in:
chenwenjian 2024-04-10 15:16:57 +08:00
parent 8d7ce2f1ab
commit 693b420f12
12 changed files with 461 additions and 62 deletions

View File

@ -0,0 +1,29 @@
package cn.axzo.nanopart.api.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/4/9 17:45
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class JoinedWorkspaceOuJob {
/**
* 加入的项目部及在该项目部下担任的所有岗位
*/
private Map<Long, List<String>> workspaceJobMap;
/**
* 加入的单位及在该单位下担任的所有岗位
*/
private Map<Long, List<String>> ouJobMap;
}

View File

@ -0,0 +1,77 @@
package cn.axzo.nanopart.api.enums;
import cn.axzo.nanopart.api.dto.JoinedWorkspaceOuJob;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 投放目标用户类型
*
* @author chenwenjian
* @version 1.0
* @date 2024/4/9 16:46
*/
@Getter
@AllArgsConstructor
public enum MaterialTargetUserTypeEnum {
ALL("ALL_USER", "全部用户") {
@Override
public boolean isDeliverRequired(List<Long> workspaceIds, List<Long> ouIds, List<String> jobCodes, JoinedWorkspaceOuJob workspaceOuJob) {
return true;
}
},
PROJECT("PROJECT", "按照项目部") {
@Override
public boolean isDeliverRequired(List<Long> workspaceIds, List<Long> ouIds, List<String> jobCodes, JoinedWorkspaceOuJob workspaceOuJob) {
// 若workspaceIds和jobCodes都为空则表示不限制否则需要满足配置的workspaceIds和jobCodes与用户加入的workspaceJob的keyvalue均存在交集
Map<Long, List<String>> workspaceJobMap = workspaceOuJob.getWorkspaceJobMap();
return CollectionUtils.isEmpty(workspaceIds) ? CollectionUtils.isEmpty(jobCodes) || jobCodes.stream().anyMatch(jobCode -> workspaceJobMap.values().stream().flatMap(List::stream).distinct().collect(Collectors.toList()).contains(jobCode))
: workspaceIds.stream().anyMatch(workspaceId -> workspaceJobMap.get(workspaceId).stream().anyMatch(jobCodes::contains));
}
},
UNIT("UNIT", "按照企业") {
@Override
public boolean isDeliverRequired(List<Long> workspaceIds, List<Long> ouIds, List<String> jobCodes, JoinedWorkspaceOuJob workspaceOuJob) {
// 若workspaceIds和jobCodes都为空则表示不限制否则需要满足配置的workspaceIds和jobCodes与用户加入的workspaceJob的keyvalue均存在交集
Map<Long, List<String>> ouJobMap = workspaceOuJob.getOuJobMap();
return CollectionUtils.isEmpty(ouIds) ? CollectionUtils.isEmpty(jobCodes) || jobCodes.stream().anyMatch(jobCode -> ouJobMap.values().stream().flatMap(List::stream).distinct().collect(Collectors.toList()).contains(jobCode))
: ouIds.stream().anyMatch(ouId -> ouJobMap.get(ouId).stream().anyMatch(jobCodes::contains));
}
};
private final String code;
private final String desc;
/**
* 是否需要投放
*
* @param workspaceIds 配置的投放项目部
* @param ouIds 配置的投放单位
* @param jobCodes 配置的投放岗位
* @param workspaceOuJob 用户参与的项目部和单位及其岗位
* @return 是否需要投放
*/
public abstract boolean isDeliverRequired(List<Long> workspaceIds, List<Long> ouIds, List<String> jobCodes, JoinedWorkspaceOuJob workspaceOuJob);
public static MaterialTargetUserTypeEnum getByCode(String code) {
if (StringUtils.isEmpty(code)) {
return null;
}
return Arrays.stream(values())
.filter(item -> item.code.equals(code))
.findFirst()
.orElse(null);
}
}

View File

@ -1,6 +1,7 @@
package cn.axzo.nanopart.api.request;
import cn.axzo.nanopart.api.enums.MaterialDisplayFrequencyTypeEnum;
import cn.axzo.nanopart.api.enums.MaterialTargetUserTypeEnum;
import cn.axzo.nanopart.api.enums.StatusEnum;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
@ -91,22 +92,28 @@ public class CreateMaterialReq {
/**
* 跳转地址
* eg: {
* "APP": {
* "Android": "http://www.baidu.com/defalut.html",
* "iOS": "http://www.baidu.com/defalut.html",
* "h5": "http://www.baidu.com/defalut.html"
* },
* "Applet": {
* "applet": "http://www.baidu.com/defalut.html",
* "h5": "http://www.baidu.com/defalut.html"
* },
* "PC": {
* "h5": "http://www.baidu.com/defalut.html"
* }
* "APP": {
* "Android": "http://www.baidu.com/defalut.html",
* "iOS": "http://www.baidu.com/defalut.html",
* "h5": "http://www.baidu.com/defalut.html"
* },
* "Applet": {
* "applet": "http://www.baidu.com/defalut.html",
* "h5": "http://www.baidu.com/defalut.html"
* },
* "PC": {
* "h5": "http://www.baidu.com/defalut.html"
* }
* }
*/
private JSONObject jumpUrl;
/**
* 目标投放对象类型呢取值ALL_USER, PROJECT, UNIT
* {@link MaterialTargetUserTypeEnum}
*/
private MaterialTargetUserTypeEnum targetUserType;
/**
* 岗位编码搭配workspaceIds和ouIds使用用于筛选用户
*/

View File

@ -1,6 +1,7 @@
package cn.axzo.nanopart.api.response;
import cn.axzo.nanopart.api.enums.MaterialDisplayFrequencyTypeEnum;
import cn.axzo.nanopart.api.enums.MaterialTargetUserTypeEnum;
import cn.axzo.nanopart.api.enums.MaterialTypeEnum;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
@ -68,6 +69,13 @@ public class MaterialResp extends PageMaterialResp {
* }
*/
private JSONObject jumpUrl;
/**
* 目标投放对象类型呢取值ALL_USER, PROJECT, UNIT
* {@link MaterialTargetUserTypeEnum}
*/
private MaterialTargetUserTypeEnum targetUserType;
/**
* 岗位编码
* ["coTheprojectmanager","coSecretaryoftheproject","coBudgetmember"]

View File

@ -55,6 +55,11 @@
<artifactId>axzo-logger-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.pokonyan</groupId>
<artifactId>pokonyan</artifactId>
@ -64,5 +69,10 @@
<groupId>cn.axzo.nanopart</groupId>
<artifactId>banner-api</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.maokai</groupId>
<artifactId>maokai-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,10 +1,11 @@
package cn.axzo.nanopart.server.domain;
import cn.axzo.nanopart.api.enums.MaterialDisplayFrequencyTypeEnum;
import cn.axzo.nanopart.api.enums.MaterialTargetUserTypeEnum;
import cn.axzo.nanopart.api.enums.MaterialTypeEnum;
import cn.axzo.nanopart.api.enums.StatusEnum;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import com.alibaba.fastjson.JSONArray;
import cn.axzo.pokonyan.config.mybatisplus.type.LongListTypeHandler;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
@ -16,6 +17,7 @@ import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
/**
* 素材实体
@ -119,23 +121,30 @@ public class Material extends BaseEntity<Material> {
@TableField(value = "jump_url", typeHandler = FastjsonTypeHandler.class)
private JSONObject jumpUrl;
/**
* 目标投放对象类型呢取值ALL_USER, PROJECT, UNIT
* {@link MaterialTargetUserTypeEnum}
*/
@TableField(value = "target_user_type")
private MaterialTargetUserTypeEnum targetUserType;
/**
* 岗位编码"0"表示所有岗位
*/
@TableField(value = "job_codes", typeHandler = FastjsonTypeHandler.class)
private JSONArray jobCodes;
private List<String> jobCodes;
/**
* 项目部id0表示所有项目部
*/
@TableField(value = "workspace_ids", typeHandler = FastjsonTypeHandler.class)
private JSONArray workspaceIds;
@TableField(value = "workspace_ids", typeHandler = LongListTypeHandler.class)
private List<Long> workspaceIds;
/**
* 单位id0表示所有单位
*/
@TableField(value = "ou_ids", typeHandler = FastjsonTypeHandler.class)
private JSONArray ouIds;
@TableField(value = "ou_ids", typeHandler = LongListTypeHandler.class)
private List<Long> ouIds;
/**
* 显示频次类型有效期内:VALIDITY_PERIOD,每天:EVERY_DAY,每周:EVERY_WEEK,每月:EVERY_MONTH

View File

@ -0,0 +1,35 @@
package cn.axzo.nanopart.server.rpc;
import cn.axzo.framework.domain.web.result.ApiListResult;
import cn.axzo.maokai.api.client.CooperateShipQueryApi;
import cn.axzo.maokai.api.vo.request.CooperateShipQueryReq;
import cn.axzo.maokai.api.vo.response.CooperateShipResp;
import cn.azxo.framework.common.logger.MethodAroundLog;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/4/9 11:20
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CooperateShipGateway {
private final CooperateShipQueryApi cooperateShipQueryApi;
@MethodAroundLog(target = "maokai", source = "nanopart", value = "查询协同关系")
public List<CooperateShipResp> genericQuery(CooperateShipQueryReq req) {
ApiListResult<CooperateShipResp> genericQueryResp = cooperateShipQueryApi.genericQuery(req);
if (Objects.nonNull(genericQueryResp) && genericQueryResp.isSuccess()) {
return genericQueryResp.getData();
}
return null;
}
}

View File

@ -0,0 +1,34 @@
package cn.axzo.nanopart.server.rpc;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.maokai.api.client.OrganizationalJobApi;
import cn.axzo.maokai.api.vo.response.OrganizationalJobResp;
import cn.azxo.framework.common.logger.MethodAroundLog;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/4/8 20:41
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class OrganizationalJobGateway {
private final OrganizationalJobApi organizationalJobApi;
@MethodAroundLog(target = "maokai", source = "nanopart", value = "通过岗位id岗位列表")
public List<OrganizationalJobResp> getByIds(List<Long> ids) {
ApiResult<List<OrganizationalJobResp>> jobResp = organizationalJobApi.getByIds(ids);
if (Objects.nonNull(jobResp) && jobResp.isSuccess()) {
return jobResp.getData();
}
return null;
}
}

View File

@ -0,0 +1,33 @@
package cn.axzo.nanopart.server.rpc;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.maokai.api.client.OrganizationalNodeUserApi;
import cn.axzo.maokai.api.vo.request.OrganizationalNodeUserSearchReq;
import cn.axzo.maokai.api.vo.response.OrganizationalNodeUserVO;
import cn.azxo.framework.common.logger.MethodAroundLog;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/4/8 20:40
*/
@Service
@RequiredArgsConstructor
public class OrganizationalNodeUserGateway {
private final OrganizationalNodeUserApi organizationalNodeUserApi;
@MethodAroundLog(target = "maokai", source = "nanopart", value = "获取用户列表")
public List<OrganizationalNodeUserVO> list(OrganizationalNodeUserSearchReq req) {
ApiResult<List<OrganizationalNodeUserVO>> listResp = organizationalNodeUserApi.list(req);
if (Objects.nonNull(listResp) && listResp.isSuccess()) {
return listResp.getData();
}
return null;
}
}

View File

@ -1,6 +1,13 @@
package cn.axzo.nanopart.server.service.impl;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.maokai.api.vo.request.CooperateShipQueryReq;
import cn.axzo.maokai.api.vo.request.OrganizationalNodeUserSearchReq;
import cn.axzo.maokai.api.vo.response.CooperateShipResp;
import cn.axzo.maokai.api.vo.response.OrganizationalJobResp;
import cn.axzo.maokai.api.vo.response.OrganizationalNodeUserVO;
import cn.axzo.nanopart.api.dto.JoinedWorkspaceOuJob;
import cn.axzo.nanopart.api.enums.MaterialDisplayFrequencyTypeEnum;
import cn.axzo.nanopart.api.enums.RecodeTypeEnum;
import cn.axzo.nanopart.api.enums.StatusEnum;
import cn.axzo.nanopart.api.request.CreateBannerOperationLogReq;
@ -15,6 +22,9 @@ import cn.axzo.nanopart.api.response.PageMaterialResp;
import cn.axzo.nanopart.server.domain.Banner;
import cn.axzo.nanopart.server.domain.Material;
import cn.axzo.nanopart.server.mapper.MaterialDao;
import cn.axzo.nanopart.server.rpc.CooperateShipGateway;
import cn.axzo.nanopart.server.rpc.OrganizationalJobGateway;
import cn.axzo.nanopart.server.rpc.OrganizationalNodeUserGateway;
import cn.axzo.nanopart.server.service.BannerOperationLogService;
import cn.axzo.nanopart.server.service.BannerService;
import cn.axzo.nanopart.server.service.MaterialService;
@ -31,9 +41,14 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author chenwenjian
@ -49,6 +64,14 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialDao, Material> impl
private final BannerOperationLogService bannerOperationLogService;
private final OrganizationalNodeUserGateway organizationalNodeUserGateway;
private final OrganizationalJobGateway organizationalJobGateway;
private final CooperateShipGateway cooperateShipGateway;
// private final
/**
* 根据广告位编码bannerCode查询素材
* <p>
@ -60,14 +83,66 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialDao, Material> impl
*/
@Override
public List<MaterialResp> listMaterialByBannerCode(ListMaterialByBannerCodeReq req) {
LambdaQueryChainWrapper<Material> queryChainWrapper = buildListByBannerCodeQueryWrapper(req);
List<Material> list = queryChainWrapper.list();
if (CollectionUtils.isEmpty(list)) {
// 获取广告位并校验
Banner banner = bannerService.selectByCode(req.getBannerCode());
if (Objects.isNull(banner)) {
throw new ServiceException("广告位不存在");
}
if (banner.getStatus() != StatusEnum.ONLINE) {
throw new ServiceException("广告位已停用");
}
// 获取该广告位下已上架且在有效期内的所有素材
List<Material> materialList = list(buildListByBannerCodeQueryWrapper(req));
if (CollectionUtils.isEmpty(materialList)) {
return Collections.emptyList();
}
// 获取当前登录用户加入的所有项目部单位及其在项目部或在单位下担任的岗位
JoinedWorkspaceOuJob personJoinedWorkspaceOuJob = getPersonJoinedWorkspaceOuJob(req.getPersonId());
if (Objects.isNull(personJoinedWorkspaceOuJob)) {
// 理论上不会走到这里因为登录用户必然加入了一个项目部或单位
throw new ServiceException("数据异常");
}
// 根据素材投放人群和投放规则频次进行过滤
List<Material> list = materialList.stream()
.filter(m -> {
m.getTargetUserType().isDeliverRequired(m.getWorkspaceIds(), m.getOuIds(), m.getJobCodes(), personJoinedWorkspaceOuJob);
// 频次过滤这个人
// RedisClient.KeyOps.hasKey();
return false;
})
.collect(Collectors.toList());
return BeanUtil.copyToList(list, MaterialResp.class);
}
/**
* 构建素材投放频次记录缓存key
*
* <p>
* 1.含义指定素材给指定人按照投放频次类型投放次数
* 2.组成namespace:bannerCode:materialId:personId:频次类型转换后的值
* 3.频次类型转换规则示例投放频次类型参考{@link MaterialDisplayFrequencyTypeEnum}
* 有效期内:VALIDITY_PERIOD -> 有效期
* 每天:EVERY_DAY -> 当天
* 每周:EVERY_WEEK -> 当周第一天
* 每月:EVERY_MONTH -> 当月第一天
* </p>
*
* @param material 素材信息
* @param personId 投放人Id
* @return key
*/
public static String buildMaterialDisplayFrequencyKey(Material material, Long personId) {
LocalDateTime now = LocalDateTime.now();
// return String.format("nanopart:%s:%s", materialId, bannerId);
return null;
}
/**
* 分页查询
*
@ -79,7 +154,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialDao, Material> impl
LambdaQueryChainWrapper<Material> pageQueryLambdaWrapper = buildPageQueryLambdaWrapper(req);
Page<Material> materialPage = page(new Page<>(req.getPageNumber(), req.getPageSize()), pageQueryLambdaWrapper);
if (materialPage.getTotal() == 0){
if (materialPage.getTotal() == 0) {
return new Page<>();
}
return PageConverter.convert(materialPage, record -> BeanUtil.copyProperties(record, PageMaterialResp.class));
@ -96,10 +171,10 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialDao, Material> impl
public Long create(CreateMaterialReq req) {
// 校验广告位
Banner banner = bannerService.selectByCode(req.getBannerCode());
if (Objects.isNull(banner)){
if (Objects.isNull(banner)) {
throw new ServiceException("广告位不存在");
}
if (StatusEnum.OFFLINE.getStatus().equals(banner.getStatus().getStatus())){
if (StatusEnum.OFFLINE.getStatus().equals(banner.getStatus().getStatus())) {
throw new ServiceException("广告位已下架");
}
@ -127,13 +202,13 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialDao, Material> impl
@Transactional(rollbackFor = Exception.class)
@Override
public void update(UpdateMaterialReq req) {
Material oldMaterial = this.getById(req.getId());
if (Objects.isNull(oldMaterial) || oldMaterial.getIsDelete() == 0 ){
Material oldMaterial = this.getById(req.getId());
if (Objects.isNull(oldMaterial) || oldMaterial.getIsDelete() == 0) {
throw new ServiceException("素材不存在");
}
// 更新操作
BeanUtil.copyProperties(req,oldMaterial);
BeanUtil.copyProperties(req, oldMaterial);
updateById(oldMaterial);
Material newMaterial = getById(req.getId());
@ -176,6 +251,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialDao, Material> impl
.setUpdateBy(req.getUpdateBy());
bannerOperationLogService.create(updateLogReq);
}
/**
* 详情
*
@ -184,7 +260,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialDao, Material> impl
*/
@Override
public MaterialResp detail(DetailMaterialReq req) {
if (Objects.isNull(req.getId()) || req.getId() == 0){
if (Objects.isNull(req.getId()) || req.getId() == 0) {
return null;
}
return BeanUtil.copyProperties(getById(req.getId()), MaterialResp.class);
@ -199,11 +275,11 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialDao, Material> impl
private LambdaQueryChainWrapper<Material> buildPageQueryLambdaWrapper(PageMaterialReq req) {
return lambdaQuery()
.eq(Material::getIsDelete, 0)
.eq(StringUtils.isNotEmpty(req.getBannerCode()),Material::getBannerCode,req.getBannerCode())
.like(StringUtils.isNotEmpty(req.getName()),Material::getName,req.getName())
.eq(Objects.nonNull(req.getStatus()),Material::getStatus,req.getStatus())
.le(Objects.nonNull(req.getStartTime()),Material::getStartTime,req.getStartTime())
.ge(Objects.nonNull(req.getEndTime()),Material::getEndTime,req.getEndTime())
.eq(StringUtils.isNotEmpty(req.getBannerCode()), Material::getBannerCode, req.getBannerCode())
.like(StringUtils.isNotEmpty(req.getName()), Material::getName, req.getName())
.eq(Objects.nonNull(req.getStatus()), Material::getStatus, req.getStatus())
.le(Objects.nonNull(req.getStartTime()), Material::getStartTime, req.getStartTime())
.ge(Objects.nonNull(req.getEndTime()), Material::getEndTime, req.getEndTime())
.orderByDesc(Material::getStatus)
.orderByAsc(Material::getPriority)
.orderByDesc(Material::getCreateAt);
@ -216,35 +292,96 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialDao, Material> impl
* @return {@link LambdaQueryChainWrapper}
*/
private LambdaQueryChainWrapper<Material> buildListByBannerCodeQueryWrapper(ListMaterialByBannerCodeReq req) {
// // jobCodes必须搭配workspaceId是和ouId使用
// if (CollectionUtils.isEmpty(req.getWorkspaceIds()) && CollectionUtils.isEmpty(req.getOuIds())
// && !CollectionUtils.isEmpty(req.getJobCodes())) {
// throw new ServiceException("请指定需要查询的项目部或单位");
// }
// if (!CollectionUtils.isEmpty(req.getWorkspaceIds()) && !req.getWorkspaceIds().contains(0L)) {
// req.getWorkspaceIds().add(0L);
// }
// if (!CollectionUtils.isEmpty(req.getOuIds()) && !req.getOuIds().contains(0L)) {
// req.getOuIds().add(0L);
// }
// if (!CollectionUtils.isEmpty(req.getJobCodes()) && !req.getJobCodes().contains("0")) {
// req.getJobCodes().add("0");
// }
LambdaQueryChainWrapper<Material> chainWrapper = lambdaQuery()
Date now = new Date(System.currentTimeMillis());
return lambdaQuery()
.eq(Material::getIsDelete, 0)
.eq(Material::getBannerCode, req.getBannerCode())
// .in(Material::getWorkspaceIds, req.getWorkspaceIds())
// .in(Material::getOuIds, req.getOuIds())
// .in(Material::getJobCodes, req.getJobCodes())
// .eq(Objects.nonNull(req.getStatus()), Material::getStatus, req.getStatus())
.eq(Material::getStatus, StatusEnum.ONLINE)
.ge(Material::getStartTime, now)
.le(Material::getEndTime, now)
.orderByAsc(Material::getPriority)
.orderByDesc(Material::getCreateAt);
// 查询有效期内的素材
// if (Objects.nonNull(req.getIsValid()) && req.getIsValid()) {
// LocalDateTime now = LocalDateTime.now();
// chainWrapper
// .ge(Material::getStartTime, now)
// .le(Material::getEndTime, now);
// }
return chainWrapper;
}
/**
* 获取人员参与的项目部单位及其在该项目部单位下担任的岗位
*
* @param personId 人员的personId
* @return {@link JoinedWorkspaceOuJob}
*/
private JoinedWorkspaceOuJob getPersonJoinedWorkspaceOuJob(Long personId) {
if (Objects.isNull(personId)) {
return null;
}
// 获取用户参与的组织架构
List<OrganizationalNodeUserVO> nodeUserList = organizationalNodeUserGateway.list(OrganizationalNodeUserSearchReq.builder().personId(personId).build());
if (CollectionUtils.isEmpty(nodeUserList)) {
return null;
}
// Map<topNodeId, List<jobId>
Map<Long, List<Long>> topNodeToJobIdMap = nodeUserList.stream()
.collect(Collectors.groupingBy(OrganizationalNodeUserVO::getTopNodeId,
Collectors.mapping(OrganizationalNodeUserVO::getOrganizationalJobId, Collectors.toList())));
// 获取相关的jobCode
List<Long> allJobIdList = topNodeToJobIdMap.values()
.stream()
.flatMap(List::stream)
.distinct()
.collect(Collectors.toList());
List<OrganizationalJobResp> allJobList = organizationalJobGateway.getByIds(allJobIdList);
// Map<jobId, jobCode>
Map<Long, String> jobIdToCodeMap = allJobList.stream()
.collect(Collectors.toMap(OrganizationalJobResp::getId, OrganizationalJobResp::getCode));
// Map<topNodeId, List<jobCode>>
Map<Long, List<String>> topNodeToJobCodeMap = topNodeToJobIdMap.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().stream()
.map(jobIdToCodeMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList())));
// 获取相关的项目部和单位
List<CooperateShipResp> genericQuery = cooperateShipGateway.genericQuery(CooperateShipQueryReq.builder()
.organizationNodeIds(topNodeToJobIdMap.keySet())
.workspaceTypes(Arrays.asList(1, 2, 4, 6))
.build());
// Map<workspaceId, List<topNodeId>>
Map<Long, List<Long>> workspaceToTopNodeIdMap = genericQuery.stream()
.filter(c -> c.getWorkspaceType() == 2)
.collect(Collectors.groupingBy(CooperateShipResp::getWorkspaceId,
Collectors.mapping(CooperateShipResp::getOrganizationalNodeId, Collectors.toList())));
// Map<ouId, List<topNodeId>>
Map<Long, List<Long>> ouIdToTopNodeIdMap = genericQuery.stream()
.filter(c -> c.getWorkspaceId() == 1)
.collect(Collectors.groupingBy(CooperateShipResp::getOrganizationalUnitId,
Collectors.mapping(CooperateShipResp::getOrganizationalNodeId, Collectors.toList())));
// Map<workspaceId, List<jobCode>
Map<Long, List<String>> workspaceToJobCodeMap = workspaceToTopNodeIdMap.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().stream()
.map(topNodeToJobCodeMap::get)
.filter(Objects::nonNull)
.flatMap(List::stream)
.distinct()
.collect(Collectors.toList())));
// Map<ouId, List<jobCode>
Map<Long, List<String>> ouIdToJobCodeMap = ouIdToTopNodeIdMap.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().stream()
.map(topNodeToJobCodeMap::get)
.filter(Objects::nonNull)
.flatMap(List::stream)
.distinct()
.collect(Collectors.toList())));
return new JoinedWorkspaceOuJob(workspaceToJobCodeMap, ouIdToJobCodeMap);
}
}

View File

@ -1,11 +1,15 @@
package cn.axzo.nanopart;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.env.Environment;
@Slf4j
@MapperScan(value = {"cn.axzo.**.mapper"})
@SpringBootApplication
@EnableFeignClients(basePackages = {
@ -14,6 +18,22 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy;
@EnableAspectJAutoProxy()
public class NanopartApplication {
public static void main(String[] args) {
SpringApplication.run(NanopartApplication.class, args);
ConfigurableApplicationContext run = SpringApplication.run(NanopartApplication.class, args);
Environment env = run.getEnvironment();
log.info(
"--------------------------------------------------------------------------------------------------------------------\n" +
"Application 【{}】 is running on 【{}】 environment!\n" +
"Api Local: \thttp://127.0.0.1:{}\n" +
"Mysql: \t{}\t username:{}\n" +
"Redis: \t{}:{}\t database:{}\n",
env.getProperty("spring.application.name"),
env.getProperty("spring.profiles.active"),
env.getProperty("server.port"),
env.getProperty("spring.datasource.url"),
env.getProperty("spring.datasource.username"),
env.getProperty("spring.redis.host"),
env.getProperty("spring.redis.port"),
env.getProperty("spring.redis.database") +
"\n----------------------------------------------------------");
}
}

View File

@ -123,7 +123,7 @@ public class NanopartApplicationTests {
return JSONUtil.toJsonStr(body);
}).forEach(body -> {
// 构建参数
String result = HttpRequest.post(envMap.get(env) + SpringUtil.getApplicationName() + "/api/black-white-list/create")
String result = HttpRequest.post(envMap.get(env) + SpringUtil.getApplicationName() + "/api/black-white-genericQuery/create")
.body(body, "application/json")
.execute().body();
log.info("请求结果:{}", result);