Compare commits

..

12 Commits

Author SHA1 Message Date
YY
40eb2d80a4 添加品类库供应商入库审批Enum 2025-08-08 09:24:41 +08:00
ed94274923 流程审批业务类型枚举 2025-08-08 09:21:01 +08:00
05dbdb6407 流程审批业务类型枚举 2025-08-08 09:19:50 +08:00
536c6a5438 外部系统详情页鉴权功能修改:
1. 外部页面在params参数中传输userId
2. 页面调用接口前,获取userId,拼接_当前系统时间放入请求头 xxxxx_2025-01-01 00:00:00
3. 每个接口请求头加密传递userId: 密文
2025-08-08 09:17:48 +08:00
fb2efa6aa0 流程审批业务类型枚举 2025-08-07 16:21:19 +08:00
0cf9e59d17 流程中心:发起 2025-08-07 10:46:29 +08:00
278c6f0f0f BaseCacheUser补充组织id和名称全路径 2025-08-06 10:10:25 +08:00
a731a31a59 字典补充注解 2025-08-01 16:56:11 +08:00
2e58d1d1a4 品类补充字段 2025-07-31 15:31:36 +08:00
2527208ac7 系统管理feign 2025-07-30 16:21:41 +08:00
07df918174 系统管理feign 2025-07-30 15:52:05 +08:00
deb9d58130 系统管理feign 2025-07-28 11:24:54 +08:00
19 changed files with 468 additions and 15 deletions

View File

@ -6,6 +6,7 @@ import com.chinaunicom.mall.ebtp.common.base.fallback.DictClientFallback;
import com.chinaunicom.mall.ebtp.common.constant.ServiceNameConstants;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@ -25,10 +26,10 @@ public interface DictClient {
*/
@ApiOperation("查询数据集合")
@GetMapping("/v1/dictProject/selectDictList")
BaseResponse<List<DictProject>> selectDictList(DictProject dictProject);
BaseResponse<List<DictProject>> selectDictList(@SpringQueryMap DictProject dictProject);
@ApiOperation("查询数据集合(支持详情查询)")
@GetMapping("/v1/dictProject/getDictList")
BaseResponse<List<DictProject>> getDictList(DictProject dictProject);
BaseResponse<List<DictProject>> getDictList(@SpringQueryMap DictProject dictProject);
}

View File

@ -53,6 +53,10 @@ public interface SystemClient {
@PostMapping("/v1/supplieruser/register")
BaseResponse<SysSupplierUser> register(@ApiParam(value = "注册信息", required = true) @RequestBody @Valid SupplierRegistrationVO registrationVO);
@ApiOperation("修改供应商用户信息")
@PostMapping("/v1/supplieruser/update")
BaseResponse<Boolean> update(@ApiParam(value = "供应商用户信息", required = true) @RequestBody SysSupplierUser sysSupplierUser);
// -----------------------组织接口-----------------------
@ApiOperation("查询组织信息(当前组织及下级组织列表)")
@GetMapping("/v1/sysorg/queryOrgWithChildren")
@ -64,7 +68,7 @@ public interface SystemClient {
@ApiOperation("查询机构列表")
@GetMapping("/v1/sysorg/list")
BaseResponse<List<SysOrg>> getOrglist(@ApiParam(value = "查询对象数据", required = false) @SpringQueryMap SysOrg param);
BaseResponse<List<SysOrg>> getOrglist(@ApiParam(value = "查询对象数据", required = false) @SpringQueryMap SysOrgVO param);
@ApiOperation("查询所有数据(树形结构)")
@GetMapping("/v1/sysorg/queryAll")

View File

@ -114,6 +114,16 @@ public class BaseCacheUser {
* 组织名称
*/
private String organizationName;
/**
* 组织ID全路径
*/
private String organizationFullId;
/**
* 组织名称全路径
*/
private String organizationFullName;
//
/**
* 组织机构类别

View File

@ -46,6 +46,11 @@ public class CoscoCategoryMaintenance extends BaseEntity implements Serializable
@ApiModelProperty(value = "路径")
private String path;
/**
* 路径名称从根到当前节点的所有category_name以逗号分隔
*/
@ApiModelProperty(value = "路径名称")
private String pathName;
/**
* 品类名称
*/

View File

@ -78,7 +78,8 @@ public class SysOrg extends BaseEntity implements Serializable {
@ApiModelProperty(value = "所属分公司编码")
private String cuCompanyNumber;
@ApiModelProperty(value = "所属公司名称")
private String cuCompanyName;
@ApiModelProperty(value = "租户ID")
private String tenantId;

View File

@ -36,4 +36,7 @@ public class SysOrgVO extends SysOrg implements Serializable {
@ApiModelProperty(value = "树形结构所有部门ID")
private String allDepartmentId;
@ApiModelProperty(value = "所属公司名称")
private String cuCompanyName;
}

View File

@ -40,6 +40,11 @@ public class SystemClientFallback implements SystemClient {
return null;
}
@Override
public BaseResponse<Boolean> update(SysSupplierUser sysSupplierUser) {
return null;
}
@Override
public BaseResponse<List<SysOrg>> getOrgWithChildren(SysOrg sysOrg) {
return null;
@ -51,7 +56,7 @@ public class SystemClientFallback implements SystemClient {
}
@Override
public BaseResponse<List<SysOrg>> getOrglist(SysOrg param) {
public BaseResponse<List<SysOrg>> getOrglist(SysOrgVO param) {
return null;
}

View File

@ -1,16 +1,32 @@
package com.chinaunicom.mall.ebtp.common.base.service.impl;
import com.chinaunicom.mall.ebtp.cloud.security.starter.common.RSAcheck;
import com.chinaunicom.mall.ebtp.cloud.security.starter.filter.CurrentRoleHolder;
import com.chinaunicom.mall.ebtp.common.base.client.SystemClient;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseCacheUser;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
import com.chinaunicom.mall.ebtp.common.base.entity.SysUser;
import com.chinaunicom.mall.ebtp.common.base.service.IBaseCacheUserService;
import com.chinaunicom.mall.ebtp.common.exception.common.CommonExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import com.chinaunicom.mall.ebtp.cloud.security.starter.filter.BearerTokenHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import static com.chinaunicom.mall.ebtp.cloud.security.starter.common.Constants.REDIS_USER_KEY;
/**
@ -28,28 +44,96 @@ public class BaseCacheUserServiceImpl implements IBaseCacheUserService {
@Qualifier("userinfoRedisTemplate")
private RedisTemplate<String, Object> redisTemplate;
@Value("${login.captcha.privateKey}")
private String privateKey;
@Autowired
private SystemClient systemClient;
@Override
public BaseCacheUser getCacheUser() {
try {
String token = BearerTokenHolder.getToken();
if (token == null || token.isEmpty()) {
log.warn("未获取到token");
return null;
BaseCacheUser cacheUser = null;
if (StringUtils.hasText(token)) {
Object o = redisTemplate.opsForValue().get(REDIS_USER_KEY + token);
if (o instanceof BaseCacheUser) {
cacheUser = (BaseCacheUser) o;
}
}
Object o = redisTemplate.opsForValue().get(REDIS_USER_KEY + token);
if (o instanceof BaseCacheUser) {
BaseCacheUser cacheUser = (BaseCacheUser) o;
// 添加当前用户角色
// 如果Token没有传递或获取不到尝试从请求头获取userId字段来获取用户信息流程/IOA等需要挂载外部页面的鉴权外部页面的前端将userId拼接_时间加密放到请求头传递
if (cacheUser == null) {
// token为空或redis未找到尝试从请求参数code解密userId
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attrs != null) {
String userId = attrs.getRequest().getHeader("userId");
String cap = this.decrypt(userId);
String[] caps = cap.split("_");
if (caps.length != 2) {
log.warn("解密后的userId格式不正确userId:{}", userId);
return null;
}
userId = caps[0];
cacheUser = getCacheUserByUserId(userId);
} else {
log.warn("无法获取ServletRequestAttributes");
}
}
if (cacheUser != null) {
cacheUser.setCurrentRoleCode(CurrentRoleHolder.getRole());
return cacheUser;
} else {
log.warn("redis中未找到用户信息token:{}", token);
return null;
}
return null;
} catch (Exception e) {
log.error("获取缓存用户信息异常", e);
return null;
}
}
/**
* 通过userId远程获取用户并封装为BaseCacheUser
*/
private BaseCacheUser getCacheUserByUserId(String userId) {
BaseResponse<SysUser> resp = systemClient.getUser(userId);
if (resp != null && resp.isSuccess() && resp.getData() != null) {
SysUser user = resp.getData();
BaseCacheUser cacheUser = new BaseCacheUser();
cacheUser.setUserId(user.getUserId());
cacheUser.setFullName(user.getName());
cacheUser.setLoginName(user.getEmployeeNumber());
cacheUser.setMobilePhone(user.getMobile());
cacheUser.setOfficePhone(user.getOfficePhone());
cacheUser.setSex(user.getSex() != null ? user.getSex().toString() : null);
cacheUser.setEmployeeNumber(user.getEmployeeNumber());
cacheUser.setEmailAddress(user.getEmail());
cacheUser.setUserType("0");
// cacheUser.setDeptId(orgId);
// cacheUser.setDeptName(sysOrg.getOrgName());
// cacheUser.setOrganizationId(sysOrg.getCuCompanyNumber());
// cacheUser.setOrganizationName(sysOrg.getCuCompanyName());
// cacheUser.setOrganizationFullId(sysOrg.getOrgFullId());
// cacheUser.setOrganizationFullName(sysOrg.getOrgFullName());
// BeanUtils.copyProperties(sysUser, cacheUser);
return cacheUser;
} else {
log.warn("systemClient未获取到用户信息userId:{}", userId);
return null;
}
}
private String decrypt(String value){
String val = "";
System.out.println("\r解密前文字\r\n" + value);
try {
byte[] encodedData = RSAcheck.decryptBASE64(value);
byte[] decodedData = RSAcheck.decryptByPrivateKey(encodedData, privateKey);
val = new String(decodedData);
System.out.println("解密后文字:\r\n" + val);
}catch (Exception e){
log.error("解密失败 异常!",e);
CommonExceptionEnum.FRAME_EXCEPTION_COMMON_DATA_OTHER_ERROR.customValidName("解密失败",true);
}
return val;
}
}

View File

@ -0,0 +1,33 @@
package com.chinaunicom.mall.ebtp.common.workflow.client;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
import com.chinaunicom.mall.ebtp.common.constant.ServiceNameConstants;
import com.chinaunicom.mall.ebtp.common.workflow.entity.WorkflowCreateResponse;
import com.chinaunicom.mall.ebtp.common.workflow.fallback.WorkflowFeignClientFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = ServiceNameConstants.EXTEND_SERVICE, fallback = WorkflowFeignClientFallback.class)
public interface WorkflowFeignClient {
/**
* @param userEmail 发起人邮箱
* @param userName 发起人用户名
* @param userOrgId 发起人所在部门id
* @param modelId 流程模型ID
* @param businessKey 节点标识
* @param url 流程审批详情页面URL(urlencode)
* @return 流程创建结果 获取processInstanceId与业务数据ID进行关联为了后续回调处理后续业务
*/
@GetMapping("/workflow/create")
BaseResponse<WorkflowCreateResponse> create(
@RequestParam String userEmail,
@RequestParam String userName,
@RequestParam String userOrgId,
@RequestParam String modelId,
@RequestParam String businessKey,
@RequestParam String url
);
}

View File

@ -0,0 +1,25 @@
package com.chinaunicom.mall.ebtp.common.workflow.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 流程审批业务类型枚举
*/
@Getter
@AllArgsConstructor
public enum BusinessTypeEnum {
SUPPLIER_ACCESS_APPROVAL("supplierAccessApproval", "供应商准入审批"),
SUPPLIER_CATEGORY_ACCESS_APPROVAL("supplierCategoryAccessApproval", "供应商品类准入审批"),
SUPPLIER_INFO_CHANGE_APPROVAL("supplierInfoChangeApproval", "供应商信息变更审批"),
BLACKLIST_APPROVAL("blacklistApproval", "黑名单审批"),
EXIT_APPROVAL("exitApproval", "退出审批"),
CATEGORY_LIBRARY_APPROVAL("categoryLibraryApproval", "品类库审批"),
CATEGORY_LIBRARY_SUPPLIER_APPROVAL("categoryLibrarySupplierApproval","品类库供应商入库审批"),
EVALUATION_APPROVAL("evaluationApproval", "评价审批"),
ANNUAL_REVIEW_APPROVAL("annualReviewApproval", "年审审批");
private final String key;
private final String desc;
}

View File

@ -0,0 +1,40 @@
package com.chinaunicom.mall.ebtp.common.workflow.entity;
import lombok.Data;
/**
*
{
"resultCode": "0",
"resultMsg": "成功",
"resultObject": {
"token": "5f50b59a-faf8-4ea2-b7e9-2e4fa04c46fa",
"id": 7000458,
"userId": 7180012,
"loginName": "dingx23",
"loginPassword": null,
"userName": "丁侠",
"userMail": "dingx23@chinaunicom.cn",
"userPhone": "",
"userStatus": "1",
"userType": "1",
"createId": "0",
"createTime": "2023-07-18T16:23:28",
"updateId": "0",
"updateTime": "2025-05-07T19:07:19",
"attributes": {
"oaOrgInfo": null,
"oaEmpCode": "0958168",
"siteInfo": "4,999,1,联通软件研究院-公共平台与架构研发事业部,主岗,"
}
}
}
*/
@Data
public class WorkflowBaseResponse<T> {
private String resultCode;
private String resultMsg;
private T resultObject;
}

View File

@ -0,0 +1,31 @@
package com.chinaunicom.mall.ebtp.common.workflow.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
{
"modelId": "1953018896810274817",
"businessKey":"10002",
"variables": [{
"name":"internal_app_env_key",
"value":"env_test"
},{
"name":"url",
"value":"http://10.0.0.125:3000/index"
}
]
}
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class WorkflowCreateRequest {
private String modelId;
private String businessKey;
private WorkflowVariable[] variables;
}

View File

@ -0,0 +1,81 @@
package com.chinaunicom.mall.ebtp.common.workflow.entity;
import lombok.Data;
/**
* {
"id": "69f4b176-7335-11f0-ad9f-a2843e06dd7d",
"processDefId": "Process_2p4rq5b:1:2ba9b30c-72a4-11f0-ad9f-a2843e06dd7d",
"orgId": "ce7d12dd8bcd416aafe3bea5a4e96edd",
"appId": "580470127",
"envType": "env_test",
"startUserName": "丁侠",
"startDepartmentId": null,
"customInfoAttr": null,
"memo": null,
"processCode": "cslc",
"formKey": "10002",
"appInfo": "{\"appId\":580470127,\"appCode\":\"clc1752747475234\",\"appName\":\"ceshi07\",\"appUseType\":\"1001\",\"appType\":\"0\",\"appEnv\":\"env_dev,env_test\",\"orgId\":\"ce7d12dd8bcd416aafe3bea5a4e96edd\",\"orgName\":\"中国远洋海运集团有限公司\",\"statusCd\":\"00A\"}",
"startUserId": "7180012",
"processName": "测试流程",
"processAttr": "{}",
"startTime": "2025-08-07 10:22:49",
"businessKey": "10002",
"processType": "Main",
"businessStatus": null,
"processInstanceId": "69f4b176-7335-11f0-ad9f-a2843e06dd7d",
"processInstanceName": "测试流程",
"createTime": "2025-08-07 10:22:49",
"endTime": null,
"startUser": {
"userId": "7180012",
"loginName": "dingx23",
"userName": "丁侠",
"userMail": "dingx23@chinaunicom.cn",
"userPhone": "",
"oaOrgInfo": "联通软件研究院-公共平台与架构研发事业部"
},
"tenantId": "580470127",
"processVariables": {
"processInstanceId": "69f4b176-7335-11f0-ad9f-a2843e06dd7d",
"internal_app_env_key": "env_test",
"internal_app_id": 580470127,
"internal_process_attr": "{}",
"internal_app_org_key": "ce7d12dd8bcd416aafe3bea5a4e96edd",
"internal_start_user_name": "丁侠",
"internal_start_user_id": "7180012",
"internal_app_info_key": "{\"appId\":580470127,\"appCode\":\"clc1752747475234\",\"appName\":\"ceshi07\",\"appUseType\":\"1001\",\"appType\":\"0\",\"appEnv\":\"env_dev,env_test\",\"orgId\":\"ce7d12dd8bcd416aafe3bea5a4e96edd\",\"orgName\":\"中国远洋海运集团有限公司\",\"statusCd\":\"00A\"}",
"url": "http://10.0.0.125:3000/index",
"internal_process_code_": "cslc",
"internal_start_form_key": "10002"
}
*/
@Data
public class WorkflowCreateResponse {
private String id;
private String processDefId;
private String orgId;
private String appId;
private String envType;
private String startUserName;
private String startDepartmentId;
private String customInfoAttr;
private String memo;
private String processCode;
private String formKey;
private String appInfo;
private String startUserId;
private String processName;
private String processAttr;
private String startTime;
private String businessKey;
private String processType;
private String businessStatus;
private String processInstanceId;
private String processInstanceName;
private String createTime;
private String endTime;
private WorkflowUser startUser;
private String tenantId;
// private WorkflowProcessVariables processVariables;
}

View File

@ -0,0 +1,17 @@
package com.chinaunicom.mall.ebtp.common.workflow.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class WorkflowExchange {
private String dateTime;
private Boolean createUserWhenNotExist;
private String userOrgId;
private WorkflowUser userVo;
}

View File

@ -0,0 +1,14 @@
package com.chinaunicom.mall.ebtp.common.workflow.entity;
import lombok.Data;
/**
*
"clientId":"zhongyuan-haiyun",
"exchangeRequest":"zAW5fhAo3z078qTBd8jGkXqkmeivlYs1U4yslBoqYCgjDMIq33OJidLsP5WQhQDsZAq6h0kOJnBorg6dZFsAOI9grEOGSoqe22-WNzi6s03hFR0FbGtM1FPJYVh1rzGkOSFNhsS4ju_B5bJxyw204LegGIsPmQFCQxglz6WDB3zX2dZ9eWcr5zoDLbNoouZdv7wTw9iymvUH3uCofyp5aqjT4JNHniWh3BlQFngB57ss5T-aIxrRjHJbFJqDOT8T1Niiu11limSjv3uQlGTj_r12NpPoyKnrhgL8N8SJP70WrnzN5G6r8KPpG68V4A_Q"
*/
@Data
public class WorkflowTokenRequest {
private String clientId;
private String exchangeRequest;
}

View File

@ -0,0 +1,50 @@
package com.chinaunicom.mall.ebtp.common.workflow.entity;
import lombok.Data;
/**
*
"token": "5f50b59a-faf8-4ea2-b7e9-2e4fa04c46fa",
"id": 7000458,
"userId": 7180012,
"loginName": "dingx23",
"loginPassword": null,
"userName": "丁侠",
"userMail": "dingx23@chinaunicom.cn",
"userPhone": "",
"userStatus": "1",
"userType": "1",
"createId": "0",
"createTime": "2023-07-18T16:23:28",
"updateId": "0",
"updateTime": "2025-05-07T19:07:19",
"attributes": {
"oaOrgInfo": null,
"oaEmpCode": "0958168",
"siteInfo": "4,999,1,联通软件研究院-公共平台与架构研发事业部,主岗,"
*/
@Data
public class WorkflowTokenResponse {
private String token;
private Long id;
private Long userId;
private String loginName;
private String loginPassword;
private String userName;
private String userMail;
private String userPhone;
private String userStatus;
private String userType;
private String createId;
private String createTime;
private String updateId;
private String updateTime;
private Attributes attributes;
@Data
public static class Attributes {
private String oaOrgInfo;
private String oaEmpCode;
private String siteInfo;
}
}

View File

@ -0,0 +1,19 @@
package com.chinaunicom.mall.ebtp.common.workflow.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class WorkflowUser {
private String loginName;
private String loginPassword;
private String userName;
private String userMail;
private String userPhone;
private String oaOrgInfo;
}

View File

@ -0,0 +1,15 @@
package com.chinaunicom.mall.ebtp.common.workflow.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class WorkflowVariable {
private String name;
private String value;
}

View File

@ -0,0 +1,15 @@
package com.chinaunicom.mall.ebtp.common.workflow.fallback;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
import com.chinaunicom.mall.ebtp.common.workflow.client.WorkflowFeignClient;
import com.chinaunicom.mall.ebtp.common.workflow.entity.WorkflowCreateResponse;
import org.springframework.stereotype.Component;
@Component
public class WorkflowFeignClientFallback implements WorkflowFeignClient {
@Override
public BaseResponse<WorkflowCreateResponse> create(String userEmail, String userName, String userOrgId, String modelId, String businessKey, String url) {
return null;
}
}