Browse Source

修改专家详情接口

tags/24080901
WendyYang 10 months ago
parent
commit
f66da5fcf9
50 changed files with 1387 additions and 601 deletions
  1. +8
    -6
      hz-pm-api/src/main/java/com/hz/pm/api/common/helper/UserInfoHelper.java
  2. +14
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/common/helper/impl/UserInfoHelperImpl.java
  3. +47
    -45
      hz-pm-api/src/main/java/com/hz/pm/api/ding/task/EmployeeBatchGetTask.java
  4. +1
    -1
      hz-pm-api/src/main/java/com/hz/pm/api/expert/assembler/ExpertUserInfoAssembler.java
  5. +5
    -21
      hz-pm-api/src/main/java/com/hz/pm/api/expert/controller/ExpertController.java
  6. +22
    -8
      hz-pm-api/src/main/java/com/hz/pm/api/expert/entity/ExpertUserFullInfo.java
  7. +2
    -19
      hz-pm-api/src/main/java/com/hz/pm/api/expert/helper/ExpertManageHelper.java
  8. +32
    -105
      hz-pm-api/src/main/java/com/hz/pm/api/expert/manage/ExpertManage.java
  9. +24
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/expert/model/dto/DictionaryVO.java
  10. +180
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/expert/model/vo/ExpertDetailVO.java
  11. +6
    -16
      hz-pm-api/src/main/java/com/hz/pm/api/external/MhUserOrgClient.java
  12. +8
    -6
      hz-pm-api/src/main/java/com/hz/pm/api/external/controller/MhSyncController.java
  13. +1
    -1
      hz-pm-api/src/main/java/com/hz/pm/api/external/model/dto/MhUserDTO.java
  14. +4
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/meta/constant/ExpertDictTypeEnum.java
  15. +1
    -1
      hz-pm-api/src/main/java/com/hz/pm/api/meta/model/entity/ExpertDictionary.java
  16. +2
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/meta/service/IExpertDictionaryService.java
  17. +7
    -1
      hz-pm-api/src/main/java/com/hz/pm/api/meta/service/impl/ExpertDictionaryServiceImpl.java
  18. +1
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/constant/UserAvailableEnum.java
  19. +18
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/controller/MhUnitController.java
  20. +10
    -3
      hz-pm-api/src/main/java/com/hz/pm/api/user/controller/UserAuthController.java
  21. +42
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/entity/MhUnit.java
  22. +19
    -4
      hz-pm-api/src/main/java/com/hz/pm/api/user/entity/UserInfo.java
  23. +329
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/manage/SyncMhUserOrgManage.java
  24. +16
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/mapper/MhUnitMapper.java
  25. +5
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/mapper/MhUnitMapper.xml
  26. +2
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/AuthProperties.java
  27. +3
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/WebSecurityConfig.java
  28. +66
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhAuthFilter.java
  29. +38
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhAuthProvider.java
  30. +58
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhAuthSecurityConfig.java
  31. +78
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhAuthToken.java
  32. +55
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhLoginUserDetailService.java
  33. +29
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/service/IMhUnitService.java
  34. +12
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/service/IUserInfoService.java
  35. +20
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/service/impl/MhUnitServiceImpl.java
  36. +31
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhExpertProperties.java
  37. +38
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhExpertTask.java
  38. +28
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhUnitProperties.java
  39. +34
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhUnitTask.java
  40. +28
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhUserProperties.java
  41. +38
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhUserTask.java
  42. +6
    -2
      hz-pm-api/src/main/resources/application-dev.yml
  43. +0
    -248
      hz-pm-api/src/main/resources/application-pre.yml
  44. +0
    -12
      hz-pm-api/src/main/resources/integration/zwdd-pre.yml
  45. +1
    -0
      hz-pm-api/src/main/resources/security/auth-dev.yml
  46. +0
    -84
      hz-pm-api/src/main/resources/security/auth-pre.yml
  47. +1
    -0
      hz-pm-api/src/main/resources/security/auth-prod.yml
  48. +0
    -0
      hz-pm-gen/lib/kingbase8-8.2.0.jar
  49. +2
    -1
      hz-pm-gen/pom.xml
  50. +15
    -17
      hz-pm-gen/src/main/java/com/hz/pm/gen/config/CodeGen.java

+ 8
- 6
hz-pm-api/src/main/java/com/hz/pm/api/common/helper/UserInfoHelper.java View File

@@ -17,11 +17,13 @@ public interface UserInfoHelper {
/**
* 根据用户id 获取 用户所属组织code organizationCode
*
* @param userId
* @return
* @param userId \
* @return \
*/
String getOrganizationCode(Long userId);

UserFullInfoDTO getUserFullInfoByMhUserIdOrOpenId(String mhUserId);

UserFullInfoDTO getUserFullInfo(Long userId);

UserFullInfoDTO getUserFullInfo(UserInfo userInfo);
@@ -31,9 +33,9 @@ public interface UserInfoHelper {
String getUserName(Long userId);

/**
* 判断该用户是否是区管或者超管
* 判断该用户是否是区管或者超管 \
*
* @return
* @return \
*/
boolean isSuperOrRegionAdmin(Long userId);

@@ -42,9 +44,9 @@ public interface UserInfoHelper {
List<UserFullInfoDTO> getUserFullInfoByEmployeeCodes(Collection<String> employeeCodes);

/**
* 获取用户任职所在单位code
* 获取用户任职所在单位code \
*
* @return
* @return \
*/
String getUserEmpPosUnitCode(Long userId);



+ 14
- 0
hz-pm-api/src/main/java/com/hz/pm/api/common/helper/impl/UserInfoHelperImpl.java View File

@@ -2,6 +2,7 @@ package com.hz.pm.api.common.helper.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hz.pm.api.common.constant.BizConst;
@@ -48,6 +49,19 @@ public class UserInfoHelperImpl implements UserInfoHelper {
}

@Override
public UserFullInfoDTO getUserFullInfoByMhUserIdOrOpenId(String mhUserId) {
LambdaQueryWrapper<UserInfo> query = Wrappers.lambdaQuery(UserInfo.class)
.eq(UserInfo::getMhUserId, mhUserId)
.or(q1 -> q1.eq(UserInfo::getWechatOpenId,mhUserId));
UserInfo userInfo = userInfoService.getOne(query);
if (Objects.isNull(userInfo)) {
return null;
}
// 返回用户全量信息
return getUserFullInfo(userInfo);
}

@Override
public UserFullInfoDTO getUserFullInfo(Long userId) {
UserInfo userInfo = userInfoService.getById(userId);
if (Objects.isNull(userInfo)) {


+ 47
- 45
hz-pm-api/src/main/java/com/hz/pm/api/ding/task/EmployeeBatchGetTask.java View File

@@ -74,12 +74,12 @@ public class EmployeeBatchGetTask {
// 获取所有的组织列表用户获取组织下的 用户信息(暂时 只查 单位的类型)
List<DingOrganization> dingOrganizationList = iDingOrganizationService.list(Wrappers.lambdaQuery(DingOrganization.class)
.eq(DingOrganization::getTypeCode, DingOrganizationContant.UNIT_TYPE));
log.info("所有待更新员工的单位数:{}",dingOrganizationList.size());
log.info("所有待更新员工的单位数:{}", dingOrganizationList.size());
if (CollUtil.isNotEmpty(dingOrganizationList)) {
//记录任务 单位数
Integer index = 0;
for (DingOrganization dingOrganization : dingOrganizationList) {
log.info("当前单位:{},下标数,{}",dingOrganization.getOrganizationName(),index);
log.info("当前单位:{},下标数,{}", dingOrganization.getOrganizationName(), index);
index++;
List<OrganizationEmployeePosition> allOrganizationEmployeePositionList = new ArrayList<>();
String organizationCode = dingOrganization.getOrganizationCode();
@@ -95,8 +95,8 @@ public class EmployeeBatchGetTask {
// 查询组织下 用户信息
GenericResult<Page<OrganizationEmployeePosition>> firstPageGenericResult = zwddClient.pageOrganizationEmployeePositions(query);
Page<OrganizationEmployeePosition> data = firstPageGenericResult.getData();
if (Objects.isNull(data)){
log.info("响应为空:{}",organizationCode);
if (Objects.isNull(data)) {
log.info("响应为空:{}", organizationCode);
continue;
}
if (CollUtil.isNotEmpty(data.getData())) {
@@ -106,7 +106,7 @@ public class EmployeeBatchGetTask {

log.info("dingOrganization :{}", JSON.toJSONString(dingOrganization));

log.info("totalSize :{},{}", totalSize,dingOrganization.getOrganizationName());
log.info("totalSize :{},{}", totalSize, dingOrganization.getOrganizationName());
if (totalSize > PAGE_SIZE) {
if (totalSize > MAX_SIZE) {
//超过1万 按1万的处理
@@ -119,9 +119,9 @@ public class EmployeeBatchGetTask {
query.setPageNo(pageNo);
GenericResult<Page<OrganizationEmployeePosition>> pageGenericResult = zwddClient.pageOrganizationEmployeePositions(query);
// log.info("pageGenericResult :{}", JSON.toJSONString(pageGenericResult));
if(pageGenericResult.isSuccess()){
if (pageGenericResult.isSuccess()) {
allOrganizationEmployeePositionList.addAll(pageGenericResult.getData().getData());
}else{
} else {
log.error(pageGenericResult.getMsg());
}
}
@@ -231,38 +231,37 @@ public class EmployeeBatchGetTask {
dingEmployeeInfo.setId(employeeInfo.getId());
iDingEmployeeInfoService.saveOrUpdate(dingEmployeeInfo);
}
generateOrUpdateUserInfo(dingEmployeeInfo,organizationMap);
generateOrUpdateUserInfo(dingEmployeeInfo, organizationMap);
}
}

public void generateOrUpdateUserInfo(DingEmployeeInfo dingEmployeeInfo,Map<String, DingOrganization> organizationMap) {
public void generateOrUpdateUserInfo(DingEmployeeInfo dingEmployeeInfo, Map<String, DingOrganization> organizationMap) {
String employeeCode = dingEmployeeInfo.getEmployeeCode();
UserInfo userInfo = iUserInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class)
.eq(UserInfo::getEmployeeCode, employeeCode));
if (Objects.isNull(userInfo)) {
userInfo = UserInfo.builder()
.accountId(dingEmployeeInfo.getAccountId())
.username(dingEmployeeInfo.getEmployeeName())
.realName(dingEmployeeInfo.getEmployeeName())
.employeeCode(dingEmployeeInfo.getEmployeeCode())
.available(UserAvailableEnum.DISABLE.name())
.createBy(-1L)
.updateBy(-1L)
.createOn(LocalDateTime.now())
.updateOn(LocalDateTime.now())
.empPosUnitCode(dingEmployeeInfo.getEmpPosUnitCode())
.avatar(dingEmployeeInfo.getAvatar())
.build();
if(StringUtils.isNotBlank(userInfo.getEmpPosUnitCode()) && organizationMap.containsKey(userInfo.getEmpPosUnitCode())){
userInfo = new UserInfo();
userInfo.setAccountId(dingEmployeeInfo.getAccountId());
userInfo.setUsername(dingEmployeeInfo.getEmployeeName());
userInfo.setRealName(dingEmployeeInfo.getEmployeeName());
userInfo.setEmployeeCode(dingEmployeeInfo.getEmployeeCode());
userInfo.setAvailable(UserAvailableEnum.DISABLE.name());
userInfo.setCreateBy(-1L);
userInfo.setUpdateBy(-1L);
userInfo.setCreateOn(LocalDateTime.now());
userInfo.setUpdateOn(LocalDateTime.now());
userInfo.setEmpPosUnitCode(dingEmployeeInfo.getEmpPosUnitCode());
userInfo.setAvatar(dingEmployeeInfo.getAvatar());
if (StringUtils.isNotBlank(userInfo.getEmpPosUnitCode()) && organizationMap.containsKey(userInfo.getEmpPosUnitCode())) {
DingOrganization dingOrganization = organizationMap.get(userInfo.getEmpPosUnitCode());
userInfo.setEmpPosUnitName(dingOrganization.getOrganizationName());
userInfo.setRegionCode(dingOrganization.getDivisionCode());
}
iUserInfoService.save(userInfo);
}else{
} else {
userInfo.setAvatar(dingEmployeeInfo.getAvatar());
userInfo.setEmpPosUnitCode(dingEmployeeInfo.getEmpPosUnitCode());
if(StringUtils.isNotBlank(userInfo.getEmpPosUnitCode()) && organizationMap.containsKey(userInfo.getEmpPosUnitCode())){
if (StringUtils.isNotBlank(userInfo.getEmpPosUnitCode()) && organizationMap.containsKey(userInfo.getEmpPosUnitCode())) {
DingOrganization dingOrganization = organizationMap.get(userInfo.getEmpPosUnitCode());
userInfo.setEmpPosUnitName(dingOrganization.getOrganizationName());
userInfo.setRegionCode(dingOrganization.getDivisionCode());
@@ -273,6 +272,7 @@ public class EmployeeBatchGetTask {

/**
* 按区域 来更新员工
*
* @param regionCode
*/
public void batchGetEmployeeTaskByRegionCode(String regionCode) {
@@ -281,12 +281,12 @@ public class EmployeeBatchGetTask {
.eq(DingOrganization::getDivisionCode, regionCode));


log.info("所有地区 {} 待更新员工的单位数:{}",regionCode,units.size());
log.info("所有地区 {} 待更新员工的单位数:{}", regionCode, units.size());
if (CollUtil.isNotEmpty(units)) {
//记录任务 单位数
Integer index = 0;
for (DingOrganization dingOrganization : units) {
log.info("当前单位:{},下标数,{}",dingOrganization.getOrganizationName(),index);
log.info("当前单位:{},下标数,{}", dingOrganization.getOrganizationName(), index);
index++;
List<OrganizationEmployeePosition> allOrganizationEmployeePositionList = new ArrayList<>();
String organizationCode = dingOrganization.getOrganizationCode();
@@ -302,8 +302,8 @@ public class EmployeeBatchGetTask {
// 查询组织下 用户信息
GenericResult<Page<OrganizationEmployeePosition>> firstPageGenericResult = zwddClient.pageOrganizationEmployeePositions(query);
Page<OrganizationEmployeePosition> data = firstPageGenericResult.getData();
if (Objects.isNull(data)){
log.info("响应为空:{}",organizationCode);
if (Objects.isNull(data)) {
log.info("响应为空:{}", organizationCode);
continue;
}
if (CollUtil.isNotEmpty(data.getData())) {
@@ -313,7 +313,7 @@ public class EmployeeBatchGetTask {

log.info("dingOrganization :{}", JSON.toJSONString(dingOrganization));

log.info("totalSize :{},{}", totalSize,dingOrganization.getOrganizationName());
log.info("totalSize :{},{}", totalSize, dingOrganization.getOrganizationName());
if (totalSize > PAGE_SIZE) {
if (totalSize > MAX_SIZE) {
//超过1万 按1万的处理
@@ -326,9 +326,9 @@ public class EmployeeBatchGetTask {
query.setPageNo(pageNo);
GenericResult<Page<OrganizationEmployeePosition>> pageGenericResult = zwddClient.pageOrganizationEmployeePositions(query);
// log.info("pageGenericResult :{}", JSON.toJSONString(pageGenericResult));
if(pageGenericResult.isSuccess()){
if (pageGenericResult.isSuccess()) {
allOrganizationEmployeePositionList.addAll(pageGenericResult.getData().getData());
}else{
} else {
log.error(pageGenericResult.getMsg());
}
}
@@ -358,7 +358,7 @@ public class EmployeeBatchGetTask {
.eq(DingOrganization::getOrganizationCode, orgCode)
.last(BizConst.LIMIT_1));
VUtils.isTrue(Objects.isNull(org)).throwMessage("单位不存在");
log.info("所属单位 {} 要更新员工信息了",org.getOrganizationName());
log.info("所属单位 {} 要更新员工信息了", org.getOrganizationName());

List<OrganizationEmployeePosition> allOrganizationEmployeePositionList = new ArrayList<>();
String organizationCode = orgCode;
@@ -374,8 +374,8 @@ public class EmployeeBatchGetTask {
// 查询组织下 用户信息
GenericResult<Page<OrganizationEmployeePosition>> firstPageGenericResult = zwddClient.pageOrganizationEmployeePositions(query);
Page<OrganizationEmployeePosition> data = firstPageGenericResult.getData();
if (Objects.isNull(data)){
log.info("响应为空:{}",organizationCode);
if (Objects.isNull(data)) {
log.info("响应为空:{}", organizationCode);
return;
}
if (CollUtil.isNotEmpty(data.getData())) {
@@ -385,7 +385,7 @@ public class EmployeeBatchGetTask {

log.info("dingOrganization :{}", JSON.toJSONString(org));

log.info("totalSize :{},{}", totalSize,org.getOrganizationName());
log.info("totalSize :{},{}", totalSize, org.getOrganizationName());
if (totalSize > PAGE_SIZE) {
if (totalSize > MAX_SIZE) {
//超过1万 按1万的处理
@@ -398,9 +398,9 @@ public class EmployeeBatchGetTask {
query.setPageNo(pageNo);
GenericResult<Page<OrganizationEmployeePosition>> pageGenericResult = zwddClient.pageOrganizationEmployeePositions(query);
// log.info("pageGenericResult :{}", JSON.toJSONString(pageGenericResult));
if(pageGenericResult.isSuccess()){
if (pageGenericResult.isSuccess()) {
allOrganizationEmployeePositionList.addAll(pageGenericResult.getData().getData());
}else{
} else {
log.error(pageGenericResult.getMsg());
}
}
@@ -427,18 +427,19 @@ public class EmployeeBatchGetTask {

/**
* 更新员工信息 主要是头像
*
* @param empCode
*/
public void getEmployeeByCode(String empCode) {
GenericResult<EmployeeInfoDTO> result = zwddClient.getEmployeeByCode(empCode);
log.error("请求员工信息 result:{}",JSON.toJSONString(result));
if(!result.isSuccess()){
log.error("请求员工信息失败 :{},mesg:{}",empCode,result.getMsg());
log.error("请求员工信息 result:{}", JSON.toJSONString(result));
if (!result.isSuccess()) {
log.error("请求员工信息失败 :{},mesg:{}", empCode, result.getMsg());
return;
}
EmployeeInfoDTO data = result.getData();

if(Objects.isNull(data)){
if (Objects.isNull(data)) {
log.error("请求员工信息失败 返回为空");
return;
}
@@ -447,7 +448,7 @@ public class EmployeeBatchGetTask {
.eq(DingEmployeeInfo::getEmployeeCode, empCode)
.last(BizConst.LIMIT_1));

if(Objects.nonNull(emp)){
if (Objects.nonNull(emp)) {
emp.setAvatar(data.getGovEmpAvatar());
iDingEmployeeInfoService.updateById(emp);
}
@@ -456,7 +457,7 @@ public class EmployeeBatchGetTask {
.eq(UserInfo::getEmployeeCode, empCode)
.last(BizConst.LIMIT_1));

if(Objects.nonNull(user)){
if (Objects.nonNull(user)) {
user.setAvatar(data.getGovEmpAvatar());
iUserInfoService.updateById(user);
}
@@ -464,6 +465,7 @@ public class EmployeeBatchGetTask {

/**
* 更新一整个单位的
*
* @param orgCode
*/
public void getBatchEmployeeByCode(String orgCode) {
@@ -471,7 +473,7 @@ public class EmployeeBatchGetTask {
List<DingEmployeeInfo> employees = iDingEmployeeInfoService.list(Wrappers.lambdaQuery(DingEmployeeInfo.class)
.eq(DingEmployeeInfo::getEmpPosUnitCode, orgCode));

for(DingEmployeeInfo employee : employees){
for (DingEmployeeInfo employee : employees) {
getEmployeeByCode(employee.getEmployeeCode());
}
}


+ 1
- 1
hz-pm-api/src/main/java/com/hz/pm/api/expert/assembler/ExpertUserInfoAssembler.java View File

@@ -42,7 +42,7 @@ public class ExpertUserInfoAssembler {
private final DictionaryCache dictionaryCache;
private final RegionCacheHelper regionCacheHelper;

public ExpertFullInfoVO buildExpertFullInfo(List<AttachFileVo> attachFiles, ExpertFullInfoAllDTO expertFullInfoAll) {
public ExpertFullInfoVO buildExpertDetail(List<AttachFileVo> attachFiles, ExpertFullInfoAllDTO expertFullInfoAll) {
ExpertUserFullInfoDTO expertUserInfo = expertFullInfoAll.getExpertUserInfoDTO();
// 字典字典段map
Map<String, List<DictionaryFieldInfo>> dictMap = buildDictInfoMap(expertFullInfoAll.getExpertDictionaryList());


+ 5
- 21
hz-pm-api/src/main/java/com/hz/pm/api/expert/controller/ExpertController.java View File

@@ -9,6 +9,7 @@ import com.hz.pm.api.expert.model.req.ExpertRegistrationRequest;
import com.hz.pm.api.expert.model.req.ExpertUserBasicInfoSubmitRequest;
import com.hz.pm.api.expert.model.req.GetZzdInfoRequest;
import com.hz.pm.api.expert.model.vo.*;
import com.hz.pm.api.user.util.LoginUserUtil;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.log.annotation.WebLog;
import io.swagger.annotations.Api;
@@ -39,23 +40,6 @@ public class ExpertController {
private final ExpertManage expertManage;
private final ExpertAdminManage expertAdminManage;

/**
* 生成专家报名临时地址
*
* @return 生成专家报名临时地址
*/
@GetMapping("/getRegistrationUrl")
public String getRegistrationUrl() {
return expertManage.getRegistrationUrl();
}

@ApiIgnore
@GetMapping("/ephemeral/{uniqueId}/registration")
public void getRegistrationUrl(@PathVariable String uniqueId, HttpServletResponse response) throws IOException {
expertManage.redirectToRegistrationUrl(uniqueId, response);
}


@PostMapping("/registration")
@ApiOperation("社会专家报名")
@WebLog("社会专家报名")
@@ -84,14 +68,14 @@ public class ExpertController {

@GetMapping("/detail")
@ApiOperation("专家获取专家详细信息")
public ExpertFullInfoVO getExpertFullInfoDetail() {
return expertManage.getExpertFullInfoDetail(null);
public ExpertDetailVO getExpertDetail() {
return expertManage.getExpertDetail(LoginUserUtil.getUserId());
}

@GetMapping("/admin/detail")
@ApiOperation("专家管理员获取专家详细信息")
public ExpertFullInfoVO getExpertFullInfoDetail(@RequestParam(value = "expertUserId") @NotNull Long expertUserId) {
return expertManage.getExpertFullInfoDetail(expertUserId);
public ExpertDetailVO getExpertDetail(@RequestParam(value = "expertUserId") @NotNull Long userId) {
return expertManage.getExpertDetail(userId);
}

@PostMapping("/expert-library/list")


+ 22
- 8
hz-pm-api/src/main/java/com/hz/pm/api/expert/entity/ExpertUserFullInfo.java View File

@@ -73,8 +73,13 @@ public class ExpertUserFullInfo implements Serializable {
*/
private String avatarFile;

/**
* 身份证号
*/
private String idCard;

/**
* 身份证号
*/
private String idCardFile;

private String officePhone;
@@ -117,6 +122,11 @@ public class ExpertUserFullInfo implements Serializable {
private Integer star;

/**
* 学历
*/
private String education;

/**
* 学校及专业
*/
private String schoolMajor;
@@ -199,11 +209,6 @@ public class ExpertUserFullInfo implements Serializable {
private String itaicCredentials;

/**
* 专家来源
*/
private String expertSource;

/**
* 其他附件
*/
private String otherFile;
@@ -218,11 +223,20 @@ public class ExpertUserFullInfo implements Serializable {
*/
private String socialInsureFile;

// TODO 重新处理单位
/**
* 职务
*/
private String duties;

/**
* TODO:重新处理单位
*/
@TableField(exist = false)
private String companyUniqCode;

// TODO 重新处理单位
/**
* TODO:重新处理单位
*/
@TableField(exist = false)
private String company;



+ 2
- 19
hz-pm-api/src/main/java/com/hz/pm/api/expert/helper/ExpertManageHelper.java View File

@@ -28,28 +28,11 @@ public class ExpertManageHelper {
private final TagCache tagCache;
private final DictionaryCache dictionaryCache;


/**
* 校验区域code
*
* @param expertRegionInfo
*/
public void expertRegionInfoCheck(ExpertRegionInfo expertRegionInfo) {
// // todo 必须为叶子节点编码
// String regionCode = expertRegionInfo.getRegionCode();
// Integer regionLevel = expertRegionInfo.getRegionLevel();
// RegionDTO regionDTO = regionCache.getByCodeAndLevel(regionCode, regionLevel);
// if (Objects.isNull(regionDTO)) {
// throw new BadRequestException("illegal regionInfo");
// }
}


/**
* 校验标签code是否合法
*
* @param expertProfessionalInfo
* @param expertBasicInfo
* @param expertProfessionalInfo \
* @param expertBasicInfo \
*/
public void tagFieldCheck(ExpertProfessionalInfo expertProfessionalInfo, ExpertBasicInfo expertBasicInfo) {
List<TagFieldInfo> goodAt = expertProfessionalInfo.getGoodAt();


+ 32
- 105
hz-pm-api/src/main/java/com/hz/pm/api/expert/manage/ExpertManage.java View File

@@ -1,29 +1,22 @@
package com.hz.pm.api.expert.manage;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hz.pm.api.common.constant.BizConst;
import com.hz.pm.api.common.model.FileBasicInfo;
import com.hz.pm.api.common.model.entity.KeyValDTO;
import com.hz.pm.api.common.util.BizUtils;
import com.hz.pm.api.expert.assembler.ExpertInfoCmdAssembler;
import com.hz.pm.api.expert.assembler.ExpertUserInfoAssembler;
import com.hz.pm.api.expert.entity.ExpertUserFullInfo;
import com.hz.pm.api.expert.helper.ExpertInfoCommonHelper;
import com.hz.pm.api.expert.helper.ExpertManageHelper;
import com.hz.pm.api.expert.model.*;
import com.hz.pm.api.expert.model.cmd.ExpertFullInfoSaveCmd;
import com.hz.pm.api.expert.model.cmd.ExpertRecommendProofSaveCmd;
import com.hz.pm.api.expert.model.dto.ExpertDictionaryDTO;
import com.hz.pm.api.expert.model.dto.ExpertFullInfoAllDTO;
import com.hz.pm.api.expert.model.dto.DictionaryVO;
import com.hz.pm.api.expert.model.req.ExpertRegistrationRequest;
import com.hz.pm.api.expert.model.req.ExpertUserBasicInfoSubmitRequest;
import com.hz.pm.api.expert.model.vo.ExpertFullInfoVO;
import com.hz.pm.api.expert.model.vo.ExpertDetailVO;
import com.hz.pm.api.expert.model.vo.ExpertPortraitVO;
import com.hz.pm.api.expert.service.ExpertInfoService;
import com.hz.pm.api.expert.service.IExpertUserFullInfoService;
import com.hz.pm.api.meeting.entity.config.WebProperties;
import com.hz.pm.api.meeting.entity.domain.MeetingExpertJudge;
import com.hz.pm.api.meeting.entity.dto.ExpertInvitedRecordDTO;
import com.hz.pm.api.meeting.entity.enumeration.ExpertAttendStatusEnum;
@@ -32,7 +25,10 @@ import com.hz.pm.api.meeting.entity.enumeration.ExpertJudgeEnum.Performance;
import com.hz.pm.api.meeting.service.IMeetingExpertJudgeService;
import com.hz.pm.api.meeting.service.IMeetingExpertService;
import com.hz.pm.api.meta.constant.ExpertDictTypeEnum;
import com.hz.pm.api.meta.model.ExpertRegionInfo;
import com.hz.pm.api.meta.helper.DictionaryCache;
import com.hz.pm.api.meta.model.dto.DictDTO;
import com.hz.pm.api.meta.model.entity.ExpertDictionary;
import com.hz.pm.api.meta.service.IExpertDictionaryService;
import com.hz.pm.api.sms.constant.VerificationCodeType;
import com.hz.pm.api.sms.helper.VerifyCodeCheckHelper;
import com.hz.pm.api.sys.model.entity.Role;
@@ -47,29 +43,17 @@ import com.hz.pm.api.user.util.LoginUserUtil;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.model.GenericResult;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.cache.model.cache.CacheKey;
import com.ningdatech.cache.repository.CachePlusOps;
import com.ningdatech.file.entity.vo.result.AttachFileVo;
import com.ningdatech.file.service.FileService;
import com.ningdatech.zwdd.client.ZwddClient;
import com.ningdatech.zwdd.model.dto.DingInfoByMobileDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@@ -85,60 +69,34 @@ public class ExpertManage {
private final ExpertManageHelper expertManageHelper;
private final IExpertUserFullInfoService expertUserFullInfoService;
private final ExpertInfoService expertInfoService;
private final ExpertInfoCommonHelper expertInfoCommonHelper;
private final FileService fileService;
private final ExpertUserInfoAssembler expertUserInfoAssembler;
private final IUserInfoService userInfoService;
private final ExpertMetaApplyManage expertMetaApplyManage;
private final IUserRoleService userRoleService;
private final IRoleService roleService;
private final VerifyCodeCheckHelper verifyCodeCheckHelper;
private final CachePlusOps cachePlusOps;
private final ZwddClient zwddClient;
private final IMeetingExpertService meetingExpertService;
private final IMeetingExpertJudgeService expertJudgeService;
private final IExpertDictionaryService expertDictionaryService;
private final DictionaryCache dictionaryCache;


@Value("${expert-registration.verify-code.check:true}")
private Boolean expertRegistrationVerifyCodeCheck;

private static final Duration REGISTER_EXPIRED_DURATION = Duration.ofDays(3);
private static final Duration REGISTER_GEN_DURATION = Duration.ofMinutes(30);

private static final String RK_REGISTER_UNIQUE_ID = "expert_registration_id:";
private static final String RK_REGISTER_UNIQUE_ID_LAST = RK_REGISTER_UNIQUE_ID + "last";

public synchronized String getRegistrationUrl() {
CacheKey lastKey = new CacheKey(RK_REGISTER_UNIQUE_ID_LAST, REGISTER_GEN_DURATION);
String lastUniqueId = cachePlusOps.get(lastKey);
if (StrUtil.isBlank(lastUniqueId)) {
lastUniqueId = BizUtils.uuid32();
CacheKey key = new CacheKey();
key.setKey(RK_REGISTER_UNIQUE_ID + lastUniqueId);
key.setExpire(REGISTER_EXPIRED_DURATION);
cachePlusOps.set(lastKey, lastUniqueId);
String gmtUserTime = LoginUserUtil.getUserId() + "#" + System.currentTimeMillis();
cachePlusOps.set(key, gmtUserTime);
}
return WebProperties.webUrl + "/pm/expert/ephemeral/" + lastUniqueId + "/registration";
}

public void redirectToRegistrationUrl(String uniqueId, HttpServletResponse response) throws IOException {
CacheKey cacheKey = new CacheKey(RK_REGISTER_UNIQUE_ID + uniqueId);
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
try {
if (Boolean.TRUE.equals(cachePlusOps.exists(cacheKey))) {
response.sendRedirect(WebProperties.webUrl + WebProperties.expertRegistrationUrl);
private Map<String, List<DictionaryVO>> listExpertDictionary(Long userId) {
List<ExpertDictionary> dicts = expertDictionaryService.listByUserId(Collections.singleton(userId));
return dicts.stream().map(w -> {
Optional<DictDTO> dict = dictionaryCache.getByCode(w.getDictionaryCode());
if (dict.isPresent()) {
DictDTO dto = dict.get();
return new DictionaryVO(dto.getDictionaryCode(), dto.getName(), dto.getDictionaryType());
} else {
response.getWriter().write("专家报名链接已失效");
return null;
}
} catch (Exception e) {
log.error("专家报名链接重定向异常:", e);
response.getWriter().write("专家报名链接访问异常");
}
}).filter(Objects::nonNull).collect(Collectors.groupingBy(DictionaryVO::getDictionaryType));
}


/**
* 专家管理员新增专家
*
@@ -163,38 +121,20 @@ public class ExpertManage {
}
}

private void expertRecommendProofSubmit(List<DictionaryFieldInfo> recommendedWay, List<FileBasicInfo> recommendProofFile, Long expertUserId) {
// 证明材料提交
ExpertRecommendProofSaveCmd expertRecommendProofSaveCmd = new ExpertRecommendProofSaveCmd();
if (CollectionUtils.isNotEmpty(recommendProofFile)) {
expertRecommendProofSaveCmd.setRecommendationProofFileIdList(recommendProofFile.stream().map(FileBasicInfo::getFileId).collect(Collectors.toList()));
public ExpertDetailVO getExpertDetail(Long userId) {
ExpertUserFullInfo eui = expertUserFullInfoService.getByUserId(userId);
if (eui == null) {
throw BizException.wrap("专家信息不存在");
}
List<ExpertDictionaryDTO> recommendedWayDictionaryDTOList = new ArrayList<>();
if (CollUtil.isNotEmpty(recommendedWay)) {
recommendedWay.forEach(r -> {
ExpertDictionaryDTO expertDictionaryDTO = new ExpertDictionaryDTO();
expertDictionaryDTO.setDictionaryCode(r.getDictionaryCode());
expertDictionaryDTO.setExpertInfoField(ExpertDictTypeEnum.RECOMMENDED_WAY.getKey());
recommendedWayDictionaryDTOList.add(expertDictionaryDTO);
});
ExpertDetailVO expertDetail = BeanUtil.copyProperties(eui, ExpertDetailVO.class);
expertDetail.setDictionaries(listExpertDictionary(userId));
boolean isTechExpert = false;
List<DictionaryVO> expertType = expertDetail.getDictionaries().get(ExpertDictTypeEnum.EXPERT_TYPE.getKey());
if (expertType != null) {
isTechExpert = expertType.get(0).getDictionaryName().contains("技术");
}
expertRecommendProofSaveCmd.setRecommendedWay(recommendedWayDictionaryDTOList);
expertRecommendProofSaveCmd.setUserId(expertUserId);
expertInfoService.expertRecommendProofSave(expertRecommendProofSaveCmd);
}

public ExpertFullInfoVO getExpertFullInfoDetail(Long expertUserId) {
Long currentUserId = LoginUserUtil.getUserId();
if (Objects.isNull(expertUserId)) {
expertUserId = currentUserId;
}
ExpertFullInfoAllDTO expertUserFullInfoAll = expertInfoService.getExpertUserFullInfoAll(expertUserId);
if (Objects.isNull(expertUserFullInfoAll)) {
return null;
}
List<Long> fileIdList = expertInfoCommonHelper.getExpertFileIdList(expertUserFullInfoAll);
List<AttachFileVo> attachFiles = fileService.getByIds(fileIdList);
return expertUserInfoAssembler.buildExpertFullInfo(attachFiles, expertUserFullInfoAll);
expertDetail.setIsTechExpert(isTechExpert);
return expertDetail;
}

public Long generateOrGetUserId(ExpertBasicInfo basicInfo, Long operatorId) {
@@ -260,12 +200,6 @@ public class ExpertManage {
Long userId = generateOrGetUserId(basicInfo, operatorId);

// 校验区域编码合法性 校验履职意向编码合法性
ExpertRegionInfo expertRegionInfo = basicInfo.getExpertRegionInfo();
expertManageHelper.expertRegionInfoCheck(expertRegionInfo);
List<ExpertRegionInfo> expertIntentionWorkRegions = basicInfo.getExpertIntentionWorkRegions();
for (ExpertRegionInfo expertIntentionWorkRegion : expertIntentionWorkRegions) {
expertManageHelper.expertRegionInfoCheck(expertIntentionWorkRegion);
}
ExpertEduInfo eduInfo = req.getEduInfo();
ExpertJobInfo jobInfo = req.getJobInfo();
ExpertProfessionalInfo professionalInfo = req.getProfessionalInfo();
@@ -283,13 +217,6 @@ public class ExpertManage {
.buildExpertFullInfoSaveCmd(userId, basicInfo, eduInfo, jobInfo, professionalInfo);
expertInfoService.saveExpertInfo(expertFullInfoSaveCmd);
}

ExpertRecommendInfo recommendInfo = req.getRecommendInfo();
// 推荐证明材料
List<DictionaryFieldInfo> recommendedWay = recommendInfo.getRecommendedWay();
// 推荐方式
// List<FileBasicInfo> recommendProofFile = recommendInfo.getRecommendationProofFile();
// expertRecommendProofSubmit(recommendedWay, recommendProofFile, userId);
return userId;
}



+ 24
- 0
hz-pm-api/src/main/java/com/hz/pm/api/expert/model/dto/DictionaryVO.java View File

@@ -0,0 +1,24 @@
package com.hz.pm.api.expert.model.dto;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
* <p>
* DictionaryVO
* </p>
*
* @author WendyYang
* @since 14:29 2023/12/26
*/
@Data
@AllArgsConstructor
public class DictionaryVO {

private String dictionaryCode;

private String dictionaryName;

private String dictionaryType;

}

+ 180
- 0
hz-pm-api/src/main/java/com/hz/pm/api/expert/model/vo/ExpertDetailVO.java View File

@@ -0,0 +1,180 @@
package com.hz.pm.api.expert.model.vo;


import com.hz.pm.api.expert.model.dto.DictionaryVO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
* <p>
* ExpertDetailVO
* </p>
*
* @author WendyYang
* @since 10:19 2023/12/26
*/
@Data
public class ExpertDetailVO {

@ApiModelProperty("是否是技术专家")
private Boolean isTechExpert;

@ApiModelProperty(value = "用户ID")
private Long userId;

@ApiModelProperty(value = "信创用户ID")
private String mhUserId;

@ApiModelProperty(value = "专家编号")
private String mhExpertNo;

@ApiModelProperty(value = "是否是浙政钉用户")
private String isDingUser;

@ApiModelProperty(value = "手机号")
private String phoneNo;

@ApiModelProperty(value = "性别")
private String gender;

@ApiModelProperty(value = "专家姓名")
private String expertName;

@ApiModelProperty(value = "头像文件路径")
private String avatarFile;

@ApiModelProperty(value = "身份证号")
private String idCard;

@ApiModelProperty(value = "身份证文件路径")
private String idCardFile;

@ApiModelProperty(value = "办公电话")
private String officePhone;

@ApiModelProperty(value = "微信OpenID")
private String wechatOpenId;

@ApiModelProperty(value = "银行账号")
private String bankNo;

@ApiModelProperty(value = "银行")
private String bank;

@ApiModelProperty(value = "电子邮箱")
private String email;

@ApiModelProperty(value = "区域代码")
private String regionCode;

@ApiModelProperty(value = "区域级别")
private Integer regionLevel;

@ApiModelProperty(value = "企业ID")
private String mhCompanyId;


@ApiModelProperty(value = "所在单位")
private String unit;


@ApiModelProperty(value = "单位性质")
private String unitType;


@ApiModelProperty(value = "通讯地址")
private String address;


@ApiModelProperty(value = "码值(1:绿码 2:黄码 3:红码)")
private Integer star;


@ApiModelProperty(value = "学历")
private String education;


@ApiModelProperty(value = "学校及专业")
private String schoolMajor;


@ApiModelProperty(value = "毕业时间")
private LocalDate graduatedAt;


@ApiModelProperty(value = "技术职称及评定时间")
private String academicTitle;


@ApiModelProperty(value = "毕业证书文件路径")
private String graduationCertFile;

@ApiModelProperty(value = "学位证书文件路径")
private String degreeCertFile;


@ApiModelProperty(value = "开始工作时间")
private LocalDate startWorkAt;

@ApiModelProperty(value = "经历")
private String experience;

@ApiModelProperty(value = "政治面貌")
private String political;


@ApiModelProperty(value = "籍贯")
private String hometown;


@ApiModelProperty(value = "民族")
private String nationality;


@ApiModelProperty(value = "出生日期")
private LocalDate birthday;

@ApiModelProperty(value = "入库时间")

private LocalDateTime inPutTime;


@ApiModelProperty(value = "是否入库")
private String isPut;

@ApiModelProperty(value = "发证日期")
private LocalDateTime awardCertDate;

@ApiModelProperty(value = "信创创建人")
private String mhCreateBy;

@ApiModelProperty(value = "信创创建时间")
private LocalDateTime mhCreateOn;

@ApiModelProperty(value = "专业技术资格")
private String majorCredentials;

@ApiModelProperty(value = "信创技术资格")
private String itaicCredentials;

@ApiModelProperty(value = "其他附件")
private String otherFile;

@ApiModelProperty(value = "专家推荐表文件路径")
private String recommendFile;

@ApiModelProperty(value = "社保记录文件路径")
private String socialInsureFile;

@ApiModelProperty(value = "职务")
private String duties;

@ApiModelProperty("专家字典信息")
private Map<String, List<DictionaryVO>> dictionaries;

}

+ 6
- 16
hz-pm-api/src/main/java/com/hz/pm/api/external/MhUserOrgClient.java View File

@@ -1,11 +1,7 @@
package com.hz.pm.api.external;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.hz.pm.api.external.model.dto.MhExpertDTO;
@@ -13,16 +9,10 @@ import com.hz.pm.api.external.model.dto.MhOrgDTO;
import com.hz.pm.api.external.model.dto.MhRetDTO;
import com.hz.pm.api.external.model.dto.MhUserDTO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;

@@ -37,22 +27,22 @@ import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
@Component
public class MhUserOrgClient {

@Value("${xc.api-host:}")
private String xcApiHost;
@Value("${mh.api-host:}")
private String mhApiHost;

public static final String UNIT_URL = "/sync/unit";
public static final String USER_URL = "/sync/user";
public static final String EXPERT_URL = "/sync/expert";

public MhRetDTO<List<MhOrgDTO>> queryOrges() {
String requestUrl = xcApiHost + UNIT_URL;
public MhRetDTO<List<MhOrgDTO>> queryUnits() {
String requestUrl = mhApiHost + UNIT_URL;
String retBody = HttpUtil.get(requestUrl);
return JSONUtil.toBean(retBody, new TypeReference<MhRetDTO<List<MhOrgDTO>>>() {
}, false);
}

public MhRetDTO<List<MhUserDTO>> queryUsers(LocalDateTime syncDateTime) {
String requestUrl = xcApiHost + USER_URL;
String requestUrl = mhApiHost + USER_URL;
if (syncDateTime != null) {
String timeString = LocalDateTimeUtil.format(syncDateTime, NORM_DATETIME_FORMATTER);
requestUrl = "?syncDateTime=" + timeString;
@@ -63,7 +53,7 @@ public class MhUserOrgClient {
}

public MhRetDTO<MhExpertDTO> queryExperts(LocalDateTime syncDateTime) {
String requestUrl = xcApiHost + EXPERT_URL;
String requestUrl = mhApiHost + EXPERT_URL;
if (syncDateTime != null) {
String timeString = LocalDateTimeUtil.format(syncDateTime, NORM_DATETIME_FORMATTER);
requestUrl = "?syncDateTime=" + timeString;


+ 8
- 6
hz-pm-api/src/main/java/com/hz/pm/api/external/controller/MhSyncController.java View File

@@ -1,6 +1,7 @@
package com.hz.pm.api.external.controller;

import com.hz.pm.api.external.MhUserOrgClient;
import com.hz.pm.api.user.manage.SyncMhUserOrgManage;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
@@ -23,17 +24,18 @@ import java.time.LocalDateTime;
@RequestMapping("/api/v1/mh/sync")
public class MhSyncController {

private final SyncMhUserOrgManage syncMhUserOrgManage;
private final MhUserOrgClient mhUserOrgClient;

@GetMapping("/users")
public Object getUsers(@RequestParam(value = "syncTime", required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime syncTime) {
return mhUserOrgClient.queryUsers(syncTime);
public void getUsers(@RequestParam(value = "syncTime", required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime syncTime) {
syncMhUserOrgManage.syncUsers(syncTime);
}

@GetMapping("/orges")
public Object getOrges() {
return mhUserOrgClient.queryOrges();
@GetMapping("/units")
public void getUnits() {
syncMhUserOrgManage.syncUnits();
}

@GetMapping("/experts")


+ 1
- 1
hz-pm-api/src/main/java/com/hz/pm/api/external/model/dto/MhUserDTO.java View File

@@ -30,7 +30,7 @@ public class MhUserDTO {
*/
private Long mhUnitId;
/**
* 用户状态
* 用户状态:1 有效、0 无效
*/
private Integer status;
/**


+ 4
- 0
hz-pm-api/src/main/java/com/hz/pm/api/meta/constant/ExpertDictTypeEnum.java View File

@@ -45,6 +45,10 @@ public enum ExpertDictTypeEnum {
*/
EXPERT_TYPE("expert_type"),
/**
* 专家来源
*/
EXPERT_SOURCE("expert_source"),
/**
* 专家领域
*/
EXPERT_AREA("expert_area"),


+ 1
- 1
hz-pm-api/src/main/java/com/hz/pm/api/meta/model/entity/ExpertDictionary.java View File

@@ -18,7 +18,7 @@ import lombok.Data;
*/
@Data
@TableName("expert_dictionary")
@ApiModel(value = "ExpertDictionary对象", description = "")
@ApiModel(value = "ExpertDictionary对象")
public class ExpertDictionary implements Serializable {

private static final long serialVersionUID = 1L;


+ 2
- 0
hz-pm-api/src/main/java/com/hz/pm/api/meta/service/IExpertDictionaryService.java View File

@@ -29,6 +29,8 @@ public interface IExpertDictionaryService extends IService<ExpertDictionary> {
**/
List<ExpertDictionary> listByUserId(Collection<Long> userIds, ExpertDictTypeEnum dictType);

List<ExpertDictionary> listByUserId(Collection<Long> userIds);

default void removeByUserId(Long userId) {
this.remove(Wrappers.lambdaQuery(ExpertDictionary.class).eq(ExpertDictionary::getUserId, userId));
}


+ 7
- 1
hz-pm-api/src/main/java/com/hz/pm/api/meta/service/impl/ExpertDictionaryServiceImpl.java View File

@@ -14,7 +14,7 @@ import java.util.List;

/**
* <p>
* 服务实现类
* 服务实现类
* </p>
*
* @author Liuxinxin
@@ -32,4 +32,10 @@ public class ExpertDictionaryServiceImpl extends ServiceImpl<ExpertDictionaryMap
return list(query);
}

@Override
public List<ExpertDictionary> listByUserId(Collection<Long> userIds) {
LambdaQueryWrapper<ExpertDictionary> query = Wrappers.lambdaQuery(ExpertDictionary.class)
.in(ExpertDictionary::getUserId, userIds);
return list(query);
}
}

+ 1
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/constant/UserAvailableEnum.java View File

@@ -15,4 +15,5 @@ public enum UserAvailableEnum {
* 禁用
*/
DISABLE

}

+ 18
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/controller/MhUnitController.java View File

@@ -0,0 +1,18 @@
package com.hz.pm.api.user.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;

/**
* <p>
* 组织表 前端控制器
* </p>
*
* @author CMM
* @since 2023-12-25
*/
@Controller
@RequestMapping("/api.user/mhUnit")
public class MhUnitController {

}

+ 10
- 3
hz-pm-api/src/main/java/com/hz/pm/api/user/controller/UserAuthController.java View File

@@ -85,7 +85,14 @@ public class UserAuthController {
@ApiOperation(value = "代登陆")
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "账号", required = true, paramType = "form", dataType = "String")})
public void agentLogin(@RequestParam(value = "userId", required = true) String userId) {
public void agentLogin(@RequestParam(value = "userId") String userId) {
// 不实现任何内容,只是为了出api文档
}

@PostMapping(value = "/mh-login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ApiOperation(value = "代登陆")
@ApiImplicitParam(name = "code", value = "账号", paramType = "form")
public void mhLogin(@RequestParam(value = "code") String code) {
// 不实现任何内容,只是为了出api文档
}

@@ -95,8 +102,8 @@ public class UserAuthController {
@ApiImplicitParam(name = "credential", value = "凭证", required = true, paramType = "form", dataType = "String"),
@ApiImplicitParam(name = "platform", value = "平台 PROVINCIAL_BUREAU,省局", required = true, paramType = "form", dataType = "String")
})
public void commonLogin(@RequestParam(value = "credential", required = true) String credential
, @RequestParam(value = "platform", required = true) String platform) {
public void commonLogin(@RequestParam(value = "credential") String credential
, @RequestParam(value = "platform") String platform) {
// 不实现任何内容,只是为了出api文档
}
}

+ 42
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/entity/MhUnit.java View File

@@ -0,0 +1,42 @@
package com.hz.pm.api.user.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.time.LocalDateTime;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* <p>
* 组织表
* </p>
*
* @author CMM
* @since 2023-12-25
*/
@Data
@TableName("MH_UNIT")
@ApiModel(value = "MhUnit对象", description = "组织表")
public class MhUnit implements Serializable {

private static final long serialVersionUID = 1L;

@TableId(type = IdType.INPUT)
private Long id;

private String name;

private Long parentId;

private Short sort;

private LocalDateTime createOn;

private LocalDateTime updateOn;

}

+ 19
- 4
hz-pm-api/src/main/java/com/hz/pm/api/user/entity/UserInfo.java View File

@@ -11,6 +11,9 @@ import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;




/**
* <p>
*
@@ -19,12 +22,12 @@ import java.time.LocalDateTime;
* @author Lierbao
* @since 2023-02-01
*/
@TableName("nd_user_info")
@Builder
@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
@ApiModel(value = "NdUserInfo对象")
@AllArgsConstructor
@TableName("nd_user_info")
@ApiModel(value = "UserInfo对象")
public class UserInfo implements Serializable {

private static final long serialVersionUID = 1L;
@@ -32,6 +35,11 @@ public class UserInfo implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;

/**
* 信创系统用户ID
*/
private String mhUserId;

private String username;

private String mobile;
@@ -40,12 +48,19 @@ public class UserInfo implements Serializable {

private Long accountId;

private String wechatOpenId;

/**
* 账号状态
*/
private String available;

private String employeeCode;

private String regionCode;

private Long mhUnitId;

private String empPosUnitCode;
private String empPosUnitName;



+ 329
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/manage/SyncMhUserOrgManage.java View File

@@ -0,0 +1,329 @@
package com.hz.pm.api.user.manage;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hz.pm.api.common.util.BizUtils;
import com.hz.pm.api.expert.entity.ExpertUserFullInfo;
import com.hz.pm.api.expert.service.IExpertUserFullInfoService;
import com.hz.pm.api.external.MhUserOrgClient;
import com.hz.pm.api.external.model.dto.*;
import com.hz.pm.api.meta.constant.ExpertDictTypeEnum;
import com.hz.pm.api.meta.helper.DictionaryCache;
import com.hz.pm.api.meta.model.dto.DictDTO;
import com.hz.pm.api.meta.model.entity.ExpertDictionary;
import com.hz.pm.api.meta.service.IExpertDictionaryService;
import com.hz.pm.api.user.constant.UserAvailableEnum;
import com.hz.pm.api.user.entity.MhUnit;
import com.hz.pm.api.user.entity.UserInfo;
import com.hz.pm.api.user.service.IMhUnitService;
import com.hz.pm.api.user.service.IUserInfoService;
import com.hz.pm.api.user.task.SyncMhUserProperties;
import com.ningdatech.basic.util.CollUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.SetUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.hz.pm.api.meta.constant.ExpertDictTypeEnum.*;

/**
* <p>
* SyncMhUserManage
* </p>
*
* @author WendyYang
* @since 11:54 2023/12/25
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class SyncMhUserOrgManage {

private final IExpertUserFullInfoService expertUserFullInfoService;
private final IUserInfoService userInfoService;
private final MhUserOrgClient mhUserOrgClient;
private final SyncMhUserProperties syncMhUserProperties;
private final IMhUnitService mhUnitService;
private final DictionaryCache dictionaryCache;
private final IExpertDictionaryService expertDictionaryService;

public void syncUsers(LocalDateTime syncDateTime) {
MhRetDTO<List<MhUserDTO>> mhRet = mhUserOrgClient.queryUsers(syncDateTime);
if (mhRet.isOk()) {
List<MhUserDTO> mhUsers = mhRet.getData();
if (CollUtil.isEmpty(mhUsers)) {
return;
}
Integer batchSize = syncMhUserProperties.getBatchSize();
List<List<MhUserDTO>> mhUserParts = ListUtil.partition(mhUsers, batchSize);
for (List<MhUserDTO> part : mhUserParts) {
List<String> mhUserIds = CollUtils.fieldList(part, MhUserDTO::getUserId);
Map<String, Long> userIdMap = userInfoService.listUserIdByMhUserIds(mhUserIds);
List<UserInfo> savedList = new ArrayList<>();
for (MhUserDTO mhUser : part) {
if (StrUtil.isBlank(mhUser.getUserId())) {
continue;
}
UserInfo userInfo = new UserInfo();
userInfo.setMhUserId(mhUser.getUserId());
if (Boolean.TRUE.equals(mhUser.getIsZzdAccount())) {
userInfo.setAccountId(Long.parseLong(mhUser.getAccountId()));
}
UserAvailableEnum userStatus = getUserAvailable(mhUser.getStatus());
userInfo.setAvailable(userStatus.name());
userInfo.setRealName(mhUser.getUserName());
userInfo.setUsername(mhUser.getAccount());
userInfo.setId(userIdMap.get(mhUser.getUserId()));
userInfo.setRegionCode("330100");
userInfo.setMhUnitId(mhUser.getMhUnitId());
savedList.add(userInfo);
}
if (!savedList.isEmpty()) {
log.info("同步用户数量:{}", savedList.size());
userInfoService.saveOrUpdateBatch(savedList);
}
}
} else {
log.error("同步用户信息失败:{}", JSONUtil.toJsonStr(mhRet));
}
}

private UserAvailableEnum getUserAvailable(Integer status) {
return status == null || status == 0 ? UserAvailableEnum.DISABLE : UserAvailableEnum.ENABLE;
}

@Transactional(rollbackFor = Exception.class)
public void syncUnits() {
MhRetDTO<List<MhOrgDTO>> mhRet = mhUserOrgClient.queryUnits();
if (mhRet.isOk()) {
List<MhOrgDTO> mhUnits = mhRet.getData();
if (mhUnits == null || mhUnits.isEmpty()) {
log.info("未获取到组织信息");
return;
}
List<Long> unitIds = CollUtils.fieldList(mhUnits, MhOrgDTO::getUnitId);
List<Long> existsUnitIds = mhUnitService.listUnitIds(unitIds);
List<MhUnit> saveList = new ArrayList<>();
List<MhUnit> updateList = new ArrayList<>();
for (MhOrgDTO org : mhUnits) {
MhUnit unit = new MhUnit();
unit.setSort(Short.parseShort(org.getSortNum()));
unit.setName(org.getUnitName());
unit.setParentId(org.getUnitPid());
unit.setId(org.getUnitId());
if (existsUnitIds.contains(unit.getId())) {
updateList.add(unit);
} else {
saveList.add(unit);
}
}
mhUnitService.saveBatch(saveList);
mhUnitService.updateBatchById(updateList);
} else {
log.error("同步组织信息失败:{}", JSONUtil.toJsonStr(mhRet));
}
}

public void syncExperts(LocalDateTime syncDateTime) {
MhRetDTO<MhExpertDTO> mhRet = mhUserOrgClient.queryExperts(syncDateTime);
if (mhRet.isOk()) {
MhExpertDTO data = mhRet.getData();
if (data == null) {
return;
}
List<MhReviewExpertDTO> reviewExperts = data.getReviewExpertVOList();
if (CollUtil.isNotEmpty(reviewExperts)) {
saveReviewExperts(reviewExperts);
}
List<MhTechExpertDTO> techExperts = data.getTechnicalExpertVOList();
if (CollUtil.isNotEmpty(techExperts)) {
saveTechExperts(techExperts);
}
} else {
log.error("同步专家信息失败:{}", JSONUtil.toJsonStr(mhRet));
}
}

private void saveReviewExperts(List<MhReviewExpertDTO> reviewExperts) {
List<String> expertNos = CollUtils.fieldList(reviewExperts, MhReviewExpertDTO::getExpertNo);
Map<String, ExpertUserFullInfo> expertMap = getExpertsMapMhExpertNo(expertNos);
for (MhReviewExpertDTO expert : reviewExperts) {
ExpertUserFullInfo eui = new ExpertUserFullInfo();
eui.setWechatOpenId(expert.getOpenId());
eui.setAvatarFile(expert.getFilePhoto());
BizUtils.notNull(expert.getBirthday(), w -> eui.setBirthday(DateUtil.date(w).toLocalDateTime().toLocalDate()));
eui.setExpertName(expert.getName());
eui.setMhExpertNo(expert.getExpertNo());
eui.setEmail(expert.getEmail());
eui.setExperience(expert.getExperience());
eui.setGender(expert.getGender());
eui.setStar(expert.getStar());
eui.setSchoolMajor(expert.getSchool());
LocalDateTime inputTime = DateUtil.parse(expert.getInPutTime()).toLocalDateTime();
eui.setInPutTime(inputTime);
eui.setEducation(expert.getEducation());
eui.setNationality(expert.getNation());
eui.setHometown(expert.getNativePlace());
eui.setIsPut(expert.getIsPut());
eui.setPhoneNo(expert.getPhone());
eui.setUnit(expert.getUnit());
eui.setUnitType(expert.getNature());
eui.setOfficePhone(expert.getTel());
eui.setAcademicTitle(expert.getTitle());
eui.setPolitical(expert.getPolitical());
eui.setDuties(expert.getDuties());
eui.setAddress(expert.getPlace());

ExpertUserFullInfo oldEui = expertMap.get(eui.getMhExpertNo());
if (oldEui == null) {
UserInfo expertUser = new UserInfo();
expertUser.setUsername(expert.getName());
expertUser.setMobile(expert.getPhone());
expertUser.setRealName(expert.getName());
userInfoService.save(expertUser);
eui.setUserId(expertUser.getId());
} else {
eui.setUserId(oldEui.getUserId());
eui.setId(oldEui.getId());
}
expertUserFullInfoService.saveOrUpdate(eui);
String expertLevel = expert.getExpertLevel();
List<ExpertDictionary> dicts = new ArrayList<>();
Optional<DictDTO> levelDict = dictionaryCache.getByDictTypeAndName(EXPERT_LEVEL.getKey(), expertLevel);
levelDict.ifPresent(dict -> dicts.add(getExpertDictionary(eui.getUserId(), dict)));

String grade = expert.getGrade();
Optional<DictDTO> gradeDict = dictionaryCache.getByDictTypeAndName(EXPERT_LIBRARY.getKey(), grade);
gradeDict.ifPresent(dict -> dicts.add(getExpertDictionary(eui.getUserId(), dict)));

String area = expert.getArea();
Optional<DictDTO> areaDict = dictionaryCache.getByDictTypeAndName(EXPERT_AREA.getKey(), area);
areaDict.ifPresent(dict -> dicts.add(getExpertDictionary(eui.getUserId(), dict)));

String skills = expert.getSkills();
if (StrUtil.isNotBlank(skills)) {
List<ExpertDictionary> skillsDicts = getSkillsDicts(skills, eui.getUserId());
if (!skillsDicts.isEmpty()) {
dicts.addAll(skillsDicts);
}
}
expertDictionaryService.removeByUserId(eui.getUserId());
expertDictionaryService.saveBatch(dicts);
}

}

private void saveTechExperts(List<MhTechExpertDTO> techExperts) {
List<String> expertNos = CollUtils.fieldList(techExperts, MhTechExpertDTO::getExpertNo);
Map<String, ExpertUserFullInfo> expertMap = getExpertsMapMhExpertNo(expertNos);
for (MhTechExpertDTO expert : techExperts) {
ExpertUserFullInfo eui = new ExpertUserFullInfo();
eui.setWechatOpenId(expert.getOpenId());
eui.setAvatarFile(expert.getFilePhoto());
BizUtils.notNull(expert.getBirthday(), w -> eui.setBirthday(DateUtil.date(w).toLocalDateTime().toLocalDate()));
eui.setExpertName(expert.getName());
eui.setMhExpertNo(expert.getExpertNo());
eui.setExperience(expert.getTextExperience());
eui.setGender(expert.getGender());
eui.setStar(expert.getStar());
eui.setIdCard(expert.getIdCard());
eui.setIdCardFile(expert.getFileIdCard());
eui.setRecommendFile(expert.getFileRecommend());
eui.setSocialInsureFile(expert.getFileSocial());
eui.setGraduationCertFile(expert.getFileDiploma());
eui.setDegreeCertFile(expert.getFileDegree());
eui.setMhCreateOn(LocalDateTimeUtil.of(expert.getCreateTime()));
eui.setMhCreateBy(expert.getCreateUser());
LocalDateTime inputTime = DateUtil.parse(expert.getInPutTime()).toLocalDateTime();
eui.setInPutTime(inputTime);
eui.setEducation(expert.getEducation());
eui.setIsPut(expert.getIsPut());
eui.setPhoneNo(expert.getPhone());
eui.setMhCompanyId(expert.getCompanyId());
eui.setPolitical(expert.getPolitical());
eui.setItaicCredentials(expert.getCredentialsSpeciality());
eui.setMajorCredentials(expert.getCredentialsTechnology());
eui.setOtherFile(expert.getFileOther());
BizUtils.notBlank(expert.getCartDate(),w -> {
LocalDateTime certDate = DateUtil.parseDate(w).toLocalDateTime();
eui.setAwardCertDate(certDate);
});
ExpertUserFullInfo oldEui = expertMap.get(eui.getMhExpertNo());
if (oldEui == null) {
UserInfo expertUser = new UserInfo();
expertUser.setUsername(expert.getName());
expertUser.setMobile(expert.getPhone());
expertUser.setRealName(expert.getName());
userInfoService.save(expertUser);
eui.setUserId(expertUser.getId());
} else {
eui.setUserId(oldEui.getUserId());
eui.setId(oldEui.getId());
}
expertUserFullInfoService.saveOrUpdate(eui);
List<ExpertDictionary> dicts = new ArrayList<>();
// 专家级别
String expertLevel = expert.getExpertLevel();
Optional<DictDTO> levelDict = dictionaryCache.getByDictTypeAndName(EXPERT_LEVEL.getKey(), expertLevel);
levelDict.ifPresent(dict -> dicts.add(getExpertDictionary(eui.getUserId(), dict)));
// 专家来源
String expertCate = expert.getExpertCate();
Optional<DictDTO> sourceDict = dictionaryCache.getByDictTypeAndName(EXPERT_SOURCE.getKey(), expertCate);
sourceDict.ifPresent(dict -> dicts.add(getExpertDictionary(eui.getUserId(), dict)));

String skills = expert.getSkills();
if (StrUtil.isNotBlank(skills)) {
List<ExpertDictionary> skillsDicts = getSkillsDicts(skills, eui.getUserId());
if (!skillsDicts.isEmpty()) {
dicts.addAll(skillsDicts);
}
}
expertDictionaryService.removeByUserId(eui.getUserId());
expertDictionaryService.saveBatch(dicts);
}

}

private List<ExpertDictionary> getSkillsDicts(String skills, Long userId) {
List<ExpertDictionary> dicts = new ArrayList<>();
List<DictDTO> skillsDict = dictionaryCache.listDictByDictType(EXPERT_SPECIALTY.getKey());
if (StrUtil.isNotBlank(skills)) {
for (String skill : CollUtil.newHashSet(skills.split("[,、,]"))) {
Optional<DictDTO> first = skillsDict.stream()
.filter(dict -> dict.getName().equals(skill.trim()))
.findFirst();
first.ifPresent(dict -> dicts.add(getExpertDictionary(userId, dict)));
}
}
return dicts;
}

private ExpertDictionary getExpertDictionary(Long userId, DictDTO dict) {
ExpertDictionary dictionary = new ExpertDictionary();
dictionary.setUserId(userId);
dictionary.setDictionaryCode(dict.getDictionaryCode());
dictionary.setExpertInfoField(dict.getDictionaryType());
return dictionary;
}

private Map<String, ExpertUserFullInfo> getExpertsMapMhExpertNo(List<String> expertNos) {
LambdaQueryWrapper<ExpertUserFullInfo> euiQuery = Wrappers.lambdaQuery(ExpertUserFullInfo.class)
.select(ExpertUserFullInfo::getMhExpertNo, ExpertUserFullInfo::getUserId, ExpertUserFullInfo::getId)
.in(ExpertUserFullInfo::getMhExpertNo, expertNos);
List<ExpertUserFullInfo> experts = expertUserFullInfoService.list(euiQuery);
return CollUtils.listToMap(experts, ExpertUserFullInfo::getMhExpertNo);
}

}

+ 16
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/mapper/MhUnitMapper.java View File

@@ -0,0 +1,16 @@
package com.hz.pm.api.user.mapper;

import com.hz.pm.api.user.entity.MhUnit;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
* <p>
* 组织表 Mapper 接口
* </p>
*
* @author CMM
* @since 2023-12-25
*/
public interface MhUnitMapper extends BaseMapper<MhUnit> {

}

+ 5
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/mapper/MhUnitMapper.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hz.pm.api.user.mapper.MhUnitMapper">

</mapper>

+ 2
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/AuthProperties.java View File

@@ -34,6 +34,8 @@ public class AuthProperties {
*/
private String agentLoginUrl;

private String mhLoginUrl;

/**
* 跳转登陆接口(目前只有省局跳转)
*/


+ 3
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/WebSecurityConfig.java View File

@@ -1,5 +1,6 @@
package com.hz.pm.api.user.security.auth;

import com.hz.pm.api.user.security.auth.mh.MhAuthSecurityConfig;
import com.ningdatech.basic.util.NdJsonUtil;
import com.ningdatech.basic.util.StrPool;
import com.hz.pm.api.common.constant.BizConst;
@@ -37,6 +38,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final DefaultLogoutSuccessHandler logoutSuccessHandler;
private final DefaultExpiredSessionStrategy defaultExpiredSessionStrategy;
private final AgentAuthSecurityConfig agentAuthSecurityConfig;
private final MhAuthSecurityConfig mhAuthSecurityConfig;
private final CommonAuthSecurityConfig commonAuthSecurityConfig;

@Override
@@ -47,6 +49,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.and().apply(credentialAuthSecurityConfig)
.and().apply(agentAuthSecurityConfig)
.and().apply(commonAuthSecurityConfig)
.and().apply(mhAuthSecurityConfig)
.and()
.authorizeRequests()
.antMatchers(authProperties.getIgnoreAuthUrlsArray())


+ 66
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhAuthFilter.java View File

@@ -0,0 +1,66 @@
package com.hz.pm.api.user.security.auth.mh;

import com.hz.pm.api.user.security.auth.model.WebRequestDetails;
import com.ningdatech.basic.exception.BizException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* <p>
* AgentAuthFilter
* </p>
*
* @author WendyYang
* @since 11:20 2023/12/26
*/
public class MhAuthFilter extends AbstractAuthenticationProcessingFilter {

private boolean postOnly = true;

private static final String AUTH_CODE = "code";

// ~ Constructors
// ===================================================================================================

public MhAuthFilter(String processingUrl) {
super(new AntPathRequestMatcher(processingUrl, HttpMethod.POST.name()));
}

// ========================================================================================================

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {
throw new AuthenticationServiceException("请求方法错误");
}
String authCode = request.getParameter(AUTH_CODE);
if (StringUtils.isBlank(authCode)) {
throw new BadCredentialsException("授权码不能为空");
}
// 获取临时授权码对应的mhUserId或者openId
String mhUserIdOrOpenId = "952795279527";
try {
MhAuthToken authRequest = new MhAuthToken(mhUserIdOrOpenId, mhUserIdOrOpenId);
authRequest.setDetails(new WebRequestDetails(request));
return this.getAuthenticationManager().authenticate(authRequest);
} catch (AuthenticationException e) {
throw new BadCredentialsException("用户id 不能为空");
} catch (BizException e) {
throw new BadCredentialsException(e.getMessage());
} catch (Exception e) {
throw new InternalAuthenticationServiceException("授权失败:", e);
}
}

}

+ 38
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhAuthProvider.java View File

@@ -0,0 +1,38 @@
package com.hz.pm.api.user.security.auth.mh;

import lombok.Setter;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

/**
* <p>
* AgentAuthProvider
* </p>
*
* @author WendyYang
* @since 20:41 2023/12/15
*/
@Setter
public class MhAuthProvider implements AuthenticationProvider {

private UserDetailsService userDetailsService;

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
MhAuthToken authenticationToken = (MhAuthToken) authentication;
String principal = (String) authenticationToken.getPrincipal();

UserDetails user = userDetailsService.loadUserByUsername(principal);
// 将用户定义的user放入token中,这样可以在session中查询到所有自定义的用户信息
return new MhAuthToken(user, user.getPassword(), user.getAuthorities());
}

@Override
public boolean supports(Class<?> authentication) {
return MhAuthToken.class.isAssignableFrom(authentication);
}

}

+ 58
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhAuthSecurityConfig.java View File

@@ -0,0 +1,58 @@
package com.hz.pm.api.user.security.auth.mh;

import com.hz.pm.api.user.security.auth.AuthProperties;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;

/**
* <p>
* MhAuthSecurityConfig
* </p>
*
* @author WendyYang
* @since 14:24 2023/12/16
*/
@Component
public class MhAuthSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {


protected final AuthenticationSuccessHandler defaultLoginSuccessHandler;
protected final AuthenticationFailureHandler defaultLoginFailureHandler;
private final UserDetailsService mhLoginUserDetailService;
private final AuthProperties authProperties;

public MhAuthSecurityConfig(@Qualifier(value = "defaultLoginSuccessHandler") AuthenticationSuccessHandler loginSuccessHandler,
@Qualifier(value = "defaultLoginFailureHandler") AuthenticationFailureHandler loginFailureHandler,
@Qualifier(value = "mhLoginUserDetailService") UserDetailsService userDetailsService,
AuthProperties authProperties) {
this.defaultLoginSuccessHandler = loginSuccessHandler;
this.defaultLoginFailureHandler = loginFailureHandler;
this.mhLoginUserDetailService = userDetailsService;
this.authProperties = authProperties;
}

@Override
public void configure(HttpSecurity http) {
MhAuthFilter agentAuthFilter =
new MhAuthFilter(authProperties.getMhLoginUrl());
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
agentAuthFilter.setAuthenticationManager(authenticationManager);
agentAuthFilter.setAuthenticationSuccessHandler(defaultLoginSuccessHandler);
agentAuthFilter.setAuthenticationFailureHandler(defaultLoginFailureHandler);

MhAuthProvider authenticationProvider = new MhAuthProvider();
authenticationProvider.setUserDetailsService(mhLoginUserDetailService);

http.authenticationProvider(authenticationProvider)
.addFilterAfter(agentAuthFilter, UsernamePasswordAuthenticationFilter.class);
}

}

+ 78
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhAuthToken.java View File

@@ -0,0 +1,78 @@
package com.hz.pm.api.user.security.auth.mh;

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;

import java.util.Collection;

/**
* <p>
* MhAuthToken
* </p>
*
* @author WendyYang
* @since 11:21 2023/12/26
*/
public class MhAuthToken extends AbstractAuthenticationToken {

private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

private final Object principal;

private final Object credentials;

/**
* This constructor can be safely used by any code that wishes to create a
* <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()} will return
* <code>false</code>.
*/
public MhAuthToken(String principal, String credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
setAuthenticated(false);
}

/**
* This constructor should only be used by <code>AuthenticationManager</code> or <code>AuthenticationProvider</code>
* implementations that are satisfied with producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>)
* authentication token.
*
* @param principal \
* @param authorities \
*/
public MhAuthToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
// must use super, as we override
super.setAuthenticated(true);
}

@Override
public Object getCredentials() {
return this.credentials;
}

@Override
public Object getPrincipal() {
return this.principal;
}

@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException(
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}
super.setAuthenticated(false);
}

@Override
public void eraseCredentials() {
super.eraseCredentials();
}

}

+ 55
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/mh/MhLoginUserDetailService.java View File

@@ -0,0 +1,55 @@
package com.hz.pm.api.user.security.auth.mh;


import com.hz.pm.api.common.helper.UserInfoHelper;
import com.hz.pm.api.user.constant.UserAvailableEnum;
import com.hz.pm.api.user.security.auth.model.UserFullInfoDTO;
import com.hz.pm.api.user.security.auth.model.UserInfoDetails;
import com.hz.pm.api.user.security.auth.validate.CommonLoginException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Objects;

import static com.hz.pm.api.user.constant.UserAvailableEnum.DISABLE;

/**
* <p>
* AgentLoginUserDetailService
* </p>
*
* @author WendyYang
* @since 11:22 2023/12/26
*/
@Service("mhLoginUserDetailService")
@RequiredArgsConstructor
public class MhLoginUserDetailService implements UserDetailsService {

private final UserInfoHelper userInfoHelper;

@Override
public UserInfoDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserFullInfoDTO userInfo = userInfoHelper.getUserFullInfoByMhUserIdOrOpenId(username);
if (userInfo == null || DISABLE.equals(userInfo.getAvailable())) {
throw new UsernameNotFoundException("用户不存在或已被禁用");
}
UserInfoDetails userDetails = new UserInfoDetails();
userDetails.setUserId(userInfo.getUserId());
userDetails.setUsername(userInfo.getUsername());
userDetails.setRealName(userInfo.getRealName());
userDetails.setUserRoleList(userInfo.getUserRoleList());
userDetails.setRegionCode(userInfo.getRegionCode());
userDetails.setRegionLevel(userInfo.getRegionLevel());
userDetails.setIdentifier(userInfo.getIdentifier());
userDetails.setPassword(userInfo.getCredential());
userDetails.setEmployeeCode(userInfo.getEmployeeCode());
userDetails.setOrganizationCode(userInfo.getOrganizationCode());
userDetails.setOrganizationName(userInfo.getOrganizationName());
userDetails.setEmpPosUnitCode(userInfo.getEmpPosUnitCode());
userDetails.setEmpPosUnitName(userInfo.getOrganizationName());
return userDetails;
}

}

+ 29
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/service/IMhUnitService.java View File

@@ -0,0 +1,29 @@
package com.hz.pm.api.user.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hz.pm.api.user.entity.MhUnit;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ningdatech.basic.util.CollUtils;

import java.util.Collection;
import java.util.List;

/**
* <p>
* 组织表 服务类
* </p>
*
* @author CMM
* @since 2023-12-25
*/
public interface IMhUnitService extends IService<MhUnit> {

default List<Long> listUnitIds(Collection<Long> unitIds){
LambdaQueryWrapper<MhUnit> query = Wrappers.lambdaQuery(MhUnit.class)
.select(MhUnit::getId)
.in(MhUnit::getId,unitIds);
return CollUtils.fieldList(list(query), MhUnit::getId);
}

}

+ 12
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/service/IUserInfoService.java View File

@@ -1,10 +1,14 @@
package com.hz.pm.api.user.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hz.pm.api.user.entity.UserInfo;
import com.ningdatech.basic.util.CollUtils;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* <p>
@@ -23,4 +27,12 @@ public interface IUserInfoService extends IService<UserInfo> {
UserInfo getUserInfoByAccountId(Long accountId);

List<UserInfo> getUserInfoByEmployeeCodes(Collection<String> employeeCodes);

default Map<String, Long> listUserIdByMhUserIds(Collection<String> mhUserIds) {
LambdaQueryWrapper<UserInfo> query = Wrappers.lambdaQuery(UserInfo.class)
.select(UserInfo::getMhUserId, UserInfo::getId)
.in(UserInfo::getMhUserId, mhUserIds);
return CollUtils.listToMap(list(query), UserInfo::getMhUserId, UserInfo::getId);
}

}

+ 20
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/service/impl/MhUnitServiceImpl.java View File

@@ -0,0 +1,20 @@
package com.hz.pm.api.user.service.impl;

import com.hz.pm.api.user.entity.MhUnit;
import com.hz.pm.api.user.mapper.MhUnitMapper;
import com.hz.pm.api.user.service.IMhUnitService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
* <p>
* 组织表 服务实现类
* </p>
*
* @author CMM
* @since 2023-12-25
*/
@Service
public class MhUnitServiceImpl extends ServiceImpl<MhUnitMapper, MhUnit> implements IMhUnitService {

}

+ 31
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhExpertProperties.java View File

@@ -0,0 +1,31 @@
package com.hz.pm.api.user.task;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* <p>
* SyncMhUnitProperties
* </p>
*
* @author WendyYang
* @since 11:49 2023/12/25
*/
@Data
@Component
@ConfigurationProperties(prefix = SyncMhExpertProperties.PREFIX)
public class SyncMhExpertProperties {

public static final String PREFIX = "sync-mh-expert";

/**
* 单位:分钟
*/
private Integer fixedRate = 5;

private Boolean open = true;

private Integer batchSize = 2000;

}

+ 38
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhExpertTask.java View File

@@ -0,0 +1,38 @@
package com.hz.pm.api.user.task;

import com.hz.pm.api.user.manage.SyncMhUserOrgManage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;


/**
* <p>
* SyncMhUserTask
* </p>
*
* @author WendyYang
* @since 11:02 2023/12/25
*/
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = SyncMhExpertProperties.PREFIX, value = "open", matchIfMissing = true)
public class SyncMhExpertTask {

private final SyncMhUserOrgManage syncMhUserOrgManage;
private final SyncMhExpertProperties syncMhExpertProperties;

@Scheduled(fixedRateString = "#{syncMhExpertProperties.getFixedRate()}", timeUnit = TimeUnit.MINUTES)
public void execute() {
Integer fixedRate = syncMhExpertProperties.getFixedRate();
LocalDateTime syncDateTime = LocalDateTime.now().minusMinutes(fixedRate + 1L);
syncMhUserOrgManage.syncExperts(syncDateTime);
}

}

+ 28
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhUnitProperties.java View File

@@ -0,0 +1,28 @@
package com.hz.pm.api.user.task;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* <p>
* SyncMhUnitProperties
* </p>
*
* @author WendyYang
* @since 11:49 2023/12/25
*/
@Data
@Component
@ConfigurationProperties(prefix = SyncMhUnitProperties.PREFIX)
public class SyncMhUnitProperties {

public static final String PREFIX = "sync-mh-unit";

private Integer fixedRate = 2;

private Boolean open = true;

private Integer batchSize = 2000;

}

+ 34
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhUnitTask.java View File

@@ -0,0 +1,34 @@
package com.hz.pm.api.user.task;

import com.hz.pm.api.user.manage.SyncMhUserOrgManage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;


/**
* <p>
* SyncMhUserTask
* </p>
*
* @author WendyYang
* @since 11:02 2023/12/25
*/
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = SyncMhUnitProperties.PREFIX, value = "open", matchIfMissing = true)
public class SyncMhUnitTask {

private final SyncMhUserOrgManage syncMhUserOrgManage;

@Scheduled(fixedRateString = "#{syncMhUnitProperties.getFixedRate()}", timeUnit = TimeUnit.HOURS)
public void execute() {
syncMhUserOrgManage.syncUnits();
}

}

+ 28
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhUserProperties.java View File

@@ -0,0 +1,28 @@
package com.hz.pm.api.user.task;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* <p>
* SyncMhUserProperties
* </p>
*
* @author WendyYang
* @since 11:49 2023/12/25
*/
@Data
@Component
@ConfigurationProperties(prefix = SyncMhUserProperties.PREFIX)
public class SyncMhUserProperties {

public static final String PREFIX = "sync-mh-user";

private Integer fixedRate = 30;

private Boolean open = true;

private Integer batchSize = 2000;

}

+ 38
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/task/SyncMhUserTask.java View File

@@ -0,0 +1,38 @@
package com.hz.pm.api.user.task;

import com.hz.pm.api.user.manage.SyncMhUserOrgManage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;


/**
* <p>
* SyncMhUserTask
* </p>
*
* @author WendyYang
* @since 11:02 2023/12/25
*/
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = SyncMhUserProperties.PREFIX, value = "open", matchIfMissing = true)
public class SyncMhUserTask {

private final SyncMhUserProperties syncMhUserProperties;
private final SyncMhUserOrgManage syncMhUserOrgManage;

@Scheduled(fixedRateString = "#{syncMhUserProperties.getFixedRate()}", timeUnit = TimeUnit.MINUTES)
public void execute() {
Integer fixedRate = syncMhUserProperties.getFixedRate();
LocalDateTime syncDateTime = LocalDateTime.now().minusMinutes(fixedRate + 1L);
syncMhUserOrgManage.syncUsers(syncDateTime);
}

}

+ 6
- 2
hz-pm-api/src/main/resources/application-dev.yml View File

@@ -245,5 +245,9 @@ web:
expert-registration:
verify-code:
check: false


sync-mh-expert:
open: false
sync-mh-unit:
open: false
sync-mh-user:
open: false

+ 0
- 248
hz-pm-api/src/main/resources/application-pre.yml View File

@@ -1,248 +0,0 @@
server:
port: 38888
servlet:
context-path: /hzpm
#最大并发数,默认200
tomcat:
threads:
max: 600
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
session:
store-type: redis
redis:
namespace: "spring:session"
redis:
timeout: 5000
host: localhost
port: 6379
database: 0
password: Ndkj1234
jedis:
pool:
max-active: 200
max-idle: 500
min-idle: 8
max-wait: 10000
application:
name: pm
jackson:
default-property-inclusion: non_null
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
jpa:
properties:
hibernate:
default_schema: PUBLIC
hbm2ddl:
auto: update
show_sql: true
show-sql: true
hibernate:
ddl-auto: update
datasource:
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.kingbase8.Driver
url: jdbc:kingbase8://10.53.168.41:54321/nd_project_management?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&nullCatalogMeansCurrent=true
username: SYSTEM
password: Ndkj1234
# 数据源
hikari:
# 是客户端等待连接池连接的最大毫秒数
connection-timeout: 30000
# 是允许连接在连接池中空闲的最长时间
minimum-idle: 10
# 配置最大池大小
maximum-pool-size: 300
# 是允许连接在连接池中空闲的最长时间(以毫秒为单位)
idle-timeout: 60000
# 池中连接关闭后的最长生命周期(以毫秒为单位)
max-lifetime: 600000
# 配置从池返回的连接的默认自动提交行为。默认值为true。
auto-commit: true
# 开启连接监测泄露
leak-detection-threshold: 5000
# 测试连接数据库
connection-test-query: SELECT 1
#设置上传 单个文件的大小
servlet:
multipart:
max-file-size: 100MB
max-request-size: 150MB
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-value: true
logic-not-delete-value: false
logging:
config: classpath:logback-spring.xml
#日志配置
level:
root: info
file:
path: logs
nd:
cache:
type: REDIS
serializerType: ProtoStuff
cacheNullVal: true
def:
keyPrefix: pm
log:
enabled: true
type: DB
# 文件存储
file:
storage-type: ALI_OSS
ali:
protocol: http://
bucket: projectmangmentoss
urlPrefix: oss-cn-lishui-gov-d01-a.ops.lsdx-zw.gov.cn
endpoint: oss-cn-lishui-gov-d01-a.ops.lsdx-zw.gov.cn
accessKeyId: XS3kNLtfW5i41SaC
accessKeySecret: 2cywvSZWANml7pZXxRAeAiHfisIhqm
# 日志文件配置
log:
path: ./logs
info:
file-size: 50MB
max-size: 5
total-size: 200MB
error:
file-size: 10MB
max-size: 5
total-size: 50MB

swagger:
enabled: true

flowable:
async-executor-activate: true
#关闭一些不需要的功能服务
rest-api-enabled: false
# database-schema-update: false
idm:
enabled: false
common:
enabled: false
dmn:
enabled: false
form:
enabled: false
app:
enabled: false

wflow:
file:
max-size: 20 #最大文件上传大小,MB

sa-token:
# token 名称 (同时也是cookie名称)
token-name: wflowToken
# token 有效期,单位s 默认30天, -1代表永不过期
timeout: 172800
# token 临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
#浙政钉公司顶级organizationCode
organization:
dept-visible-scopes:
- GO_c1a6f8d5338e4a468337b08da76e2e31

yxt:
wsdl-url: classpath:wsdl-prod.xml
#账号
user-code: Lssdsjj
#密码
password: Lssdsjj@2021
#音信通开关
sms-enable: true
tel-enable: true

#省局联审 请求信息
provincial:
host: https://pms.zj.gov.cn/prometheus-zhejiang_foreign
pushUrl: /api/v1/foreign/importantPro
detailUrl: /api/v1/foreign/importantProView
domainUrl: /api/v1/foreign/dominantUnit
key: b5b2096953534a53991be4ea95f8cffa
secret: 1bec9b77134d4962ac466fbe9696b897
# host: http://223.4.72.75/prometheus-zhejiang_foreign
# pushUrl: /api/v1/foreign/importantPro
# detailUrl: /api/v1/foreign/importantProView
# key: b5b2096953534a53991be4ea95f8cffa
# secret: 1bec9b77134d4962ac466fbe9696b897


#天印服务器接口信息
irs:
is-search-app: true
digital-resource-indicators:
url: https://interface.zjzwfw.gov.cn/gateway/api/proxy/001003001029/dataSharing/99E2bic31KdXzaa7.htm
interfaceName: 99E2bic31KdXzaa7
app-key: A331101453557202109017383
app-secret: 496f0f2a19994f76b4fd9dae087366c7
seal-platform:
project-id: 330001110
project-secret: 70e512d40c8f440484db4acab181570a
access-key: 42bcb49bea174986a3bfdfba7d005566
secret-key: bebff29877d4443abd67fc4f8fb335d8
api-url: https://bcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220309000004/seal-platform/seal/v1/rest/sign/signPdf
app-report:
url: https://bcdsg.zj.gov.cn:8443/restapi/prod/IC33000020230427000001/irs-res-bill/report/pdfUrl
appScret: BCDSGS_4ab4235d26a9a357170a39f3a13fd68c
appKey: BCDSGA_d874c8e46b541eb4e8aac6510fd3351b
push-app:
url: https://interface.zjzwfw.gov.cn/gateway/api/proxy/001003001029/dataSharing/94wbaL1I1Pbz0648.htm
appScret: 496f0f2a19994f76b4fd9dae087366c7
appKey: A331101453557202109017383
search-app:
url: https://interface.zjzwfw.gov.cn/gateway/api/001003001029/dataSharing/XS8daav3bcemZ3Ra.htm
appScret: 496f0f2a19994f76b4fd9dae087366c7
appKey: A331101453557202109017383
province-gov:
can-search: true
url: https://interface.zjzwfw.gov.cn/gateway/api/proxy/001003001029/dataSharing/62vd5jAdM0b7Gr00.htm
interfaceName: 62vd5jAdM0b7Gr00
appSecret: 496f0f2a19994f76b4fd9dae087366c7
appKey: A331101453557202109017383
push-project-detail:
url: https://interface.zjzwfw.gov.cn/gateway/api/proxy/001003001029/dataSharing/3XN9R93Pva6db7sf.htm
interfaceName: 3XN9R93Pva6db7sf
appSecret: 496f0f2a19994f76b4fd9dae087366c7
appKey: A331101453557202109017383
core-biz:
url: https://interface.zjzwfw.gov.cn/gateway/api/001008012012001/dataSharing/Fc3re2cq7r64Qfa7.htm
interfaceName: Fc3re2cq7r64Qfa7
appSecret: 496f0f2a19994f76b4fd9dae087366c7
appKey: A331101453557202109017383
interface-refresh:
method: POST
request-token-url: http://interface.zjzwfw.gov.cn/gateway/app/refreshTokenByKey.htm
refresh-token-url: http://interface.zjzwfw.gov.cn/gateway/app/refreshTokenBySec.htm
interface-local-refresh:
method: GET
request-token-url: https://interface.ls.local/a/api/requestTokenKey?appKey={appKey}&requestTime={requestTime}&sign={sign}
refresh-token-url: https://interface.ls.local/a/api/refreshTokenKey?appKey={appKey}&requestTime={requestTime}&sign={sign}
hostname: iZ6mx01asxnsmennpzoxooZ
project:
push-url: http://10.53.168.41:38088/open/api/v1/project-receive/save
no-effective-url: http://10.53.168.41:38088/open/api/v1/project-receive/not-effective
delete-all-url: http://10.53.168.41:38088/open/api/v1/project-receive/delete-all
login:
phone-verify-code:
skip: true
url: http://60.188.225.145:8080/login
web:
url: http://60.188.225.145:8080

+ 0
- 12
hz-pm-api/src/main/resources/integration/zwdd-pre.yml View File

@@ -1,12 +0,0 @@
#浙政钉
integration:
zwdd:
#扫码
app-auth-key: ls_project_managment_din-b1Y3I1g7Rr94yX76KfFkpp18Uy4WHtU0b6rINJ3
app-auth-secret: 75e8PMHv984KYF0Mcy6v4pxt480y73dbD7kB65dD
#免登/获取信息
app-key: ls_project-c32LNu87v60UiANZVja
app-secret: R14QgbBr21751LTGml3Vt8oX9doPl4Lk1ROzZNfG
#专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729
tenantId: 196729
domain: openplatform-pro.ding.zj.gov.cn

+ 1
- 0
hz-pm-api/src/main/resources/security/auth-dev.yml View File

@@ -4,6 +4,7 @@ security:
invalid-session-url: /api/v1/user/auth/invalid-session
password-login-url: /api/v1/user/auth/login
agent-login-url: /api/v1/user/auth/agent-login
mh-login-url: /api/v1/user/auth/mh-login
logout-url: /api/v1/user/auth/logout
common-login-url: /api/v1/user/auth/common-login
ignore-auth-urls:


+ 0
- 84
hz-pm-api/src/main/resources/security/auth-pre.yml View File

@@ -1,84 +0,0 @@
security:
auth:
auth-require-url: /api/v1/user/auth/auth-require
invalid-session-url: /api/v1/user/auth/invalid-session
password-login-url: /api/v1/user/auth/login
agent-login-url: /api/v1/user/auth/agent-login
logout-url: /api/v1/user/auth/logout
common-login-url: /api/v1/user/auth/common-login
ignore-auth-urls:
- /v2/api-docs
- /swagger-ui.html
- /webjars/**
- /swagger-resources/**
- /webjars/
- /api/v1/user/auth/register
- /api/v1/user/auth/auth-require
- /api/v1/user/auth/invalid-session
- /api/v1/user/auth/login/password
- /api/v1/user/auth/forget-password
- /api/v1/user/auth/common-login
- /doc.html
- /ok.html
- /open/api/**
- /oa/**
- /wflow/**
- /sys/**
- /api/v1/verification/**
- /api/v1/expert/registration
- /api/v1/meta/dictionary/list
- /api/v1/meta/tag
- /api/v1/organization/tree-list
- /api/v1/organization/get-child-list
- /api/v1/region/tree
- /api/v1/expert/get-zzd-info
- /file/upload
- /file/download
- /api/v1/zwdd/pull/**
- /api/v1/irs/**
- /api/v1/wps-convert/**
- /api/v1/belong-org/business-strip/list
- /expert/ephemeral/*/registration
ignore-csrf-urls:
- /api/v1/user/auth/**
- /v2/api-docs
- /swagger-ui.html
- /webjars/**
- /swagger-resources/**
- /webjars/
- /doc.html
- /ok.html
- /api/v1/**
- /file/**
- /optLog/**
- /dict/**
- /oa/**
- /wflow/**
- /sys/**
- /api/v1/verification/**
- /api/v1/expert/registration
- /api/v1/meta/dictionary/list
- /api/v1/meta/tag
- /api/v1/organization/tree-list
- /api/v1/organization/get-child-list
- /api/v1/region/tree
- /api/v1/expert/get-zzd-info
- /file/upload
- /file/download
- /api/v1/zwdd/pull/**
- /api/v1/irs/**
- /api/v1/wps-convert/**
- /api/v1/belong-org/business-strip/list
- /expert/ephemeral/*/registration
role-map:
"engineer":
"project_manager":
- /api/v1/user-info/kick-off/**
"enterprise_admin":
"regional_general_manager":
"driver":
"super_admin":
- /api/v1/user-info/save
- /api/v1/user-info/del
- /api/v1/user-info/kick-off/**
- /api/v1/user-info/password/mod

+ 1
- 0
hz-pm-api/src/main/resources/security/auth-prod.yml View File

@@ -4,6 +4,7 @@ security:
invalid-session-url: /api/v1/user/auth/invalid-session
password-login-url: /api/v1/user/auth/login
agent-login-url: /api/v1/user/auth/agent-login
mh-login-url: /api/v1/user/auth/mh-login
logout-url: /api/v1/user/auth/logout
common-login-url: /api/v1/user/auth/common-login
ignore-auth-urls:


+ 0
- 0
hz-pm-gen/lib/kingbase8-8.2.0.jar View File


+ 2
- 1
hz-pm-gen/pom.xml View File

@@ -15,11 +15,12 @@
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3.2</version>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>


hz-pm-gen/src/main/java/com/hz/pm/gen/config/GeneratorCodeKingbaseConfig.java → hz-pm-gen/src/main/java/com/hz/pm/gen/config/CodeGen.java View File

@@ -7,21 +7,20 @@ import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;

/**
* @description: 自动生成code代码
* @author: zpf
* @date: 2023/01/03 09:20
* <p>
* CodeGen
* </p>
*
* @author WendyYang
* @since 13:27 2023/12/25
*/
public class GeneratorCodeKingbaseConfig {
public class CodeGen {

private static final String PATH_LXX = "/Users/liuxinxin/IdeaProjects/project-management/pmapi/src/main/java";
private static final String PATH_YYD = "/Users/wendy/code project/java/project-management/pmapi/src/main/java";
private static final String PATH_LS = "";
private static final String PATH_ZPF = "D:\\ningda\\project-management\\pmapi\\src\\main\\java";
private static final String PATH_CMM = "D:\\work\\project-management\\project-management\\pmapi\\src\\main\\java";
private static final String PATH_YYD = "/Users/wendy/coding/java/hz-project-management/hz-pm-api/src/main/java";

private static final String URL = "jdbc:kingbase8://120.26.44.207:54321/nd_project_management?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8";
private static final String USER_NAME = "SYSTEM";
private static final String PASSWORD = "Ndkj1234";
private static final String URL = "jdbc:dm://47.98.125.47:5236/HZ_PROJECT_MANAGEMENT?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8";
private static final String USER_NAME = "SYSDBA";
private static final String PASSWORD = "SYSDBA";

private static void generate(String author, String packageName, String path, String... tableNames) {
FastAutoGenerator.create(URL, USER_NAME, PASSWORD)
@@ -37,13 +36,13 @@ public class GeneratorCodeKingbaseConfig {
})
.packageConfig(builder -> {
// 设置父包名
builder.parent("com.ningdatech")
builder.parent("com.hz.pm")
// 设置父包模块名
.moduleName("pmapi." + packageName)
.moduleName("api." + packageName)
// 设置mapperXml生成路径
.pathInfo(Collections.singletonMap(OutputFile.xml,
//设置自己的生成路径
path + "/com/ningdatech/pmapi/" + packageName + "/mapper"));
path + "/com/hz/pm/api/" + packageName + "/mapper"));
})
.strategyConfig(builder -> {
builder.addTablePrefix("");
@@ -56,8 +55,7 @@ public class GeneratorCodeKingbaseConfig {
}

public static void main(String[] args) {
//generate("Liuxinxin", "expert", PATH_LXX, "expert_gov_business_strip");
generate("CMM", "test", PATH_CMM, "nd_performance_appraisal_app_score_info");
generate("CMM", "user", PATH_YYD, "mh_unit");
}

}

Loading…
Cancel
Save