diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/client/IamClient.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/client/IamClient.java index 77559ee..70b8339 100644 --- a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/client/IamClient.java +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/client/IamClient.java @@ -1,15 +1,85 @@ package com.chinaunicom.mall.ebtp.extend.iam.client; -import com.chinaunicom.mall.ebtp.extend.iam.entity.AuthRequestDTO; -import com.chinaunicom.mall.ebtp.extend.iam.entity.AuthResponseDTO; +import com.chinaunicom.mall.ebtp.extend.iam.entity.*; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamEmployee; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamUser; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.cloud.openfeign.SpringQueryMap; +import org.springframework.web.bind.annotation.*; -@FeignClient(name = "iam-service", url = "${iam.service.url}") +@FeignClient(name = "iam-service", url = "${spring.iam.url}") public interface IamClient { @PostMapping("/access_token") AuthResponseDTO getAccessToken(@RequestBody AuthRequestDTO request); + + /** + * (获取code)oauth2认证接口-未认证跳转统一认证前端,已认证则发放code + * @param request 获取授权请求参数 + * @return + * {"statusCodeValue":0,"msg":null,"data":"http://10.11.4.13:9999/#/digital?code=501679ca-f036-4ed1-9414-585315d8627d"} + */ + @GetMapping("/authz/oauth/v20/authorize") + IamAuthResponseDTO authorize(@SpringQueryMap IamAuthRequestDTO request); + + /** + * jwt使用员工号免密登录 + * @param jwt 员工号jwt + * @return + * { + * "statusCodeValue": 0, + * "msg": null, + * "data": { + * "ticket": "string", + * "type": "string", + * "token": "string", + * "redirectUrl": null, + * "remeberMe": null, + * "id": "string", + * "name": "string", + * "username": "string", + * "displayName": "string", + * "email": "string", + * "instId": "string", + * "instName": null, + * "passwordSetType": 0, + * "authorities": [ + * "string" + * ], + * "refresh_token": "string", + * "expired": 0 + * } + * } + */ + @GetMapping("/login/jwt/employee") + IamAuthResponseDTO employee(@RequestParam("jwt") String jwt); + + /** + * 获取用户信息接口 + * @param authorization Bearer Token + * @return IamUserDTO 用户信息 + */ + @GetMapping("/api/oauth/v20/me") + IamUser me(@RequestHeader("Authorization") String authorization); + + /** + * code换token + * @param request 获取iamToken + * grant_type * string 固定值 authorization_code + * code * string 跳转Url带的code参数 43d9b6ea-a130-4680-b98c-a5bfec87168d + * redirect_uri * string 跳转地址 http%3A%2F%2F10.11.4.13%3A9999%2F%23%2Fdigital + * client_id * string 应用id 1018630382704132096 + * client_secret * string 应用密钥 hT2MMDcwODIwMjQxODM0MzQxMDYsHE + * @return + * { + * "access_token": "efc3ae0f-7a66-40aa-916b-010d83bf46fb", + * "token_type": "bearer", + * "expires_in": 16503, + * "scope": "read all" + * } + */ + @GetMapping("/authz/oauth/v20/token") + IamToken token(@RequestHeader("Authorization") String authorization, IamTokenRequestDTO request); + } diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/constant/IamEnum.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/constant/IamEnum.java new file mode 100644 index 0000000..bed4788 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/constant/IamEnum.java @@ -0,0 +1,26 @@ +package com.chinaunicom.mall.ebtp.extend.iam.constant; + +import lombok.Getter; + +/** + * IAM响应码枚举 + * 定义与IAM相关的响应码和描述 + */ +@Getter +public enum IamEnum { + IAM_RESP_SUCCESS_CODE(0, "IAM响应成功"), + IAM_RESP_SYSTEM_BUSY_CODE(-1, "IAM系统繁忙错误码"), + IAM_RESP_AUTH_ERROR_CODE(400401, "IAM鉴权错误码"), + IAM_RESP_NO_PERMISSION_CODE(400403, "IAM无权限操作错误码"), + IAM_RESP_NOT_FOUND_CODE(400404, "IAM请求资源不存在错误码"), + IAM_RESP_CONFLICT_CODE(400409, "IAM唯一属性被占用错误码"); + + private final int code; + private final String desc; + + IamEnum(int code, String desc) { + this.code = code; + this.desc = desc; + } + +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamAuthController.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamAuthController.java index 0fb5f0e..caa109a 100644 --- a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamAuthController.java +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamAuthController.java @@ -1,13 +1,20 @@ package com.chinaunicom.mall.ebtp.extend.iam.controller; +import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse; import com.chinaunicom.mall.ebtp.extend.iam.client.BidRatioClient; +import com.chinaunicom.mall.ebtp.extend.iam.constant.IamEnum; +import com.chinaunicom.mall.ebtp.extend.iam.entity.*; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamEmployee; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamUser; import com.chinaunicom.mall.ebtp.extend.iam.service.IamAuthService; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import java.util.Objects; @RestController +@Api(tags = "IAM单点登陆接口") @RequestMapping("/iam/auth") public class IamAuthController { @@ -35,4 +42,63 @@ public class IamAuthController { public String getBidRatio(@PathVariable("id") String id) { return bidRatioClient.getBidRatio(id); } + + /** + * IAM单点登陆 - (获取code)oauth2认证接口-未认证跳转统一认证前端,已认证则发放code + * @see com.chinaunicom.mall.ebtp.extend.iam.client.IamClient#authorize(IamAuthRequestDTO) + * @param request 获取授权请求参数 + * @return IAM授权响应 + */ + @ApiOperation("IAM单点登陆 - (获取code)oauth2认证接口-未认证跳转统一认证前端,已认证则发放code") + @GetMapping("/authorize") + public BaseResponse authorize(IamAuthRequestDTO request){ + IamAuthResponseDTO authorize = iamAuthService.authorize(request); + if (Objects.equals(authorize.getStatusCodeValue(), IamEnum.IAM_RESP_SUCCESS_CODE.getCode())) { + return BaseResponse.success(authorize.getMsg(), authorize.getData()); + } else { + return BaseResponse.fail(authorize.getMsg(), authorize.getData()); + } + } + + /** + * IAM单点登陆 - jwt使用员工号免密登录 + * @see com.chinaunicom.mall.ebtp.extend.iam.client.IamClient#employee(String) + * @param jwt 员工号jwt + * @return IAM员工信息 + */ + @ApiOperation("IAM单点登陆 - jwt使用员工号免密登录") + @GetMapping("/jwt") + public BaseResponse employee(@RequestParam("jwt") String jwt) { + IamAuthResponseDTO response = iamAuthService.employee(jwt); + if (Objects.equals(response.getStatusCodeValue(), IamEnum.IAM_RESP_SUCCESS_CODE.getCode())) { + return BaseResponse.success(response.getMsg(), response.getData()); + } else { + return BaseResponse.fail(response.getMsg(), response.getData()); + } + } + + + /** + * IAM单点登陆 - 获取用户信息接口 + * @see com.chinaunicom.mall.ebtp.extend.iam.client.IamClient#me(String) + * @return iam用户信息 + */ + @ApiOperation("IAM单点登陆 - 获取用户信息接口") + @GetMapping("/getUser") + public BaseResponse getUser(){ + return BaseResponse.success(iamAuthService.me()); + } + + /** + * IAM单点登陆 - code换token + * @see com.chinaunicom.mall.ebtp.extend.iam.client.IamClient#token(String, IamTokenRequestDTO) + * @param request 获取iamToken + * @return iamToken + */ + @ApiOperation("IAM单点登陆 - code换token") + @GetMapping("/getTokenByCode") + public BaseResponse getTokenByCode(IamTokenRequestDTO request) { + String authorization = ""; + return BaseResponse.success(iamAuthService.getToken(authorization, request)); + } } diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamDepartmentController.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamDepartmentController.java new file mode 100644 index 0000000..b8f5605 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamDepartmentController.java @@ -0,0 +1,148 @@ +package com.chinaunicom.mall.ebtp.extend.iam.controller; + +import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO; +import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiResponseDTO; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiDepartment; +import com.chinaunicom.mall.ebtp.extend.iam.service.IamDepartmentService; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 参考:IAM系统组织架构同步接口标准.docx + * 提供给IAM的同步组织的接口 + * 组织架构管理接口 + * - 获取组织架构列表接口 + * - 新增组织架构接口 + * - 更新组织架构接口 + * - 删除/停用组织架构接口 + */ +@RestController +@Api(tags = "IAM同步组织架构接口") +@RequestMapping("/iam/api") +@Slf4j +public class IamDepartmentController { + + @Resource + private IamDepartmentService iamDepartmentService; + + /** + * 获取人员列表接口 + * 请求方式:GET + * 请求地址: + * {url}/departments?pageIndex={pageIndex}&pageSize={pageSize}&startTime={startTime}&endTime={endTime} + * @param departmentRequestDTO 组织架构列表请求参数实体 + * 名称 格式 描述 + * url string 合作方应用接口地址,例如 文档样例 本地接口 + * pageIndex number 分页索引(从0开始) + * pageSize number 分页大小(支持至少300) + * startTime number 最近变更时间的起始时间(unix毫秒时间戳,用于增量) + * endTime number 最近变更时间的终止时间(unix毫秒时间戳,用于增量) + * @return 组织架构列表信息 样例: + * { + * "errorCode": 0, // success + * "total":100,//组织架构总数 + * "data":[ + * { + * "id":"xxx", + * "name":"xxx", + * "parentId":"xxx"//上级组织架构的ID + * "status":"xxx"//标识组织架构的停启用 + * }, + * …… + * ] + * } + */ + @ApiOperation("获取组织架构列表接口") + @GetMapping("/departments") + public IamApiResponseDTO> getDepartments(IamApiRequestDTO departmentRequestDTO){ + log.debug("departments请求参数:{}", departmentRequestDTO); + IPage page = iamDepartmentService.getDepartments(departmentRequestDTO); + List depts = page.getRecords(); + log.debug("departments返回结果:{}", depts); + IamApiResponseDTO> iamApiResponse = IamApiResponseDTO.success(depts); + iamApiResponse.setTotal((int) page.getTotal()); + return iamApiResponse; + } + + /** + * 新增组织架构接口 + * 请求方式:POST + * 请求地址: + * {url}/user + * @param iamApiDepartment 组织架构请求参数实体 + * 请求体(Request Body) + * { + * "name":"xxx", + * "parentId":"xxx"//上级组织架构的ID + * } + * @return 新增组织架构ID 样例: + * 请求返回体(Response Body) + * { + * "errorCode": 0, // success + * "errorMsg":null,//若errorCode不为0,此处应有错误描述 + * "id":"xxx"//返回新增的组织架构的id(必须) + * } + */ + @ApiOperation("新增组织架构接口") + @PostMapping("/department") + public IamApiResponseDTO saveDepartment(@RequestBody IamApiDepartment iamApiDepartment){ + log.debug("saveUser请求参数:{}", iamApiDepartment); + Boolean saveResult = iamDepartmentService.save(iamApiDepartment); + log.debug("saveUser返回结果:{}, {}", saveResult, iamApiDepartment); + return IamApiResponseDTO.success(iamApiDepartment.getId()); + } + + /** + * 更新组织架构接口 + * 请求方式:PUT + * 请求地址: + * {url}/user/{id} + * @param iamApiDepartment 组织架构请求参数实体 + * 请求体(Request Body) + * { + * "name":"xxx", + * "parentId":"xxx"//上级组织架构的ID + * } + * @return 更新结果 样例: + * { + * "errorCode": 0, // success + * "errorMsg":null//若errorCode不为0,此处应有错误描述 + * } + */ + @ApiOperation("更新组织架构接口") + @PutMapping("/department") + public IamApiResponseDTO updateDepartment(@RequestBody IamApiDepartment iamApiDepartment) { + log.debug("updateDepartment请求参数:{}", iamApiDepartment); + boolean updateResult = iamDepartmentService.updateById(iamApiDepartment); + log.debug("updateDepartment返回结果:{}", updateResult); + return IamApiResponseDTO.success(); + } + + /** + * 删除/停用组织架构接口 + * 请求方式:DELETE + * 请求地址: + * {url}/department/{id} + * @param id 组织架构ID + * @return 删除/停用结果 样例: + * { + * "errorCode": 0, // success + * "errorMsg":null//若errorCode不为0,此处应有错误描述 + * } + */ + @ApiOperation("删除/停用组织架构接口") + @DeleteMapping("/department/{id}") + public IamApiResponseDTO deleteDepartment(@PathVariable("id") String id) { + log.debug("deleteDepartment请求参数:{}", id); + boolean deleteResult = iamDepartmentService.removeById(id); + log.debug("deleteDepartment返回结果:{}", deleteResult); + return IamApiResponseDTO.success(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamUserController.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamUserController.java new file mode 100644 index 0000000..c87ed16 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/controller/IamUserController.java @@ -0,0 +1,155 @@ +package com.chinaunicom.mall.ebtp.extend.iam.controller; + +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiUser; +import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiResponseDTO; +import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO; +import com.chinaunicom.mall.ebtp.extend.iam.service.IamUserService; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 参考:IAM系统组织架构同步接口标准.docx + * 提供给IAM的同步人员的接口 + * 人员管理接口 + * - 获取人员列表接口 + * - 新增人员接口 + * - 更新人员接口 + * - 删除/停用人员接口 + */ +@RestController +@Api(tags = "IAM同步人员接口") +@RequestMapping("/iam/api") +@Slf4j +public class IamUserController { + + @Resource + private IamUserService iamUserService; + + /** + * 获取人员列表接口 + * 请求方式:GET + * 请求地址: + * {url}/users?pageIndex={pageIndex}&pageSize={pageSize}&startTime={startTime}&endTime={endTime} + * @param userRequestDTO 人员列表请求参数实体 + * 名称 格式 描述 + * url string 合作方应用接口地址,例如 文档样例 本地接口 + * pageIndex number 分页索引(从0开始) + * pageSize number 分页大小(支持至少300) + * startTime number 最近变更时间的起始时间(unix毫秒时间戳,用于增量) + * endTime number 最近变更时间的终止时间(unix毫秒时间戳,用于增量) + * @return 人员列表信息 样例: + * { + * "errorCode": 0, // success + * "total":1000,//人员总数 + * "data":[ + * { + * "id":"xxx", + * "name":"xxx", + * "email":"xxx", + * "mobile":"xxx", + * "departmentId":"xxx"//所在组织架构的 ID + * "status":"xxx"//标识人员的停启用 + * }, + * …… + * ] + * } + */ + @ApiOperation("获取人员列表接口") + @GetMapping("/users") + public IamApiResponseDTO> getUsers(IamApiRequestDTO userRequestDTO){ + log.debug("users请求参数:{}", userRequestDTO); + IPage page = iamUserService.getUsers(userRequestDTO); + List users = page.getRecords(); + log.debug("users返回结果:{}", users); + IamApiResponseDTO> iamApiResponse = IamApiResponseDTO.success(users); + iamApiResponse.setTotal((int) page.getTotal()); + return iamApiResponse; + } + + /** + * 新增人员接口 + * 请求方式:POST + * 请求地址: + * {url}/user + * @param iamApiUser 人员请求参数实体 + * 请求体(Request Body) + * { + * "name":"xxx", + * "email":"xxx", + * "mobile":"xxx", + * "departmentId":"xxx"//所在组织架构的ID + * } + * @return 新增人员ID 样例: + * 请求返回体(Response Body) + * { + * "errorCode": 0, // success + * "errorMsg":null,//若errorCode不为0,此处应有错误描述 + * "id":"xxx"//返回新增的人员的id(必须) + * } + */ + @ApiOperation("新增人员接口") + @PostMapping("/user") + public IamApiResponseDTO saveUser(@RequestBody IamApiUser iamApiUser){ + log.debug("saveUser请求参数:{}", iamApiUser); + Boolean saveResult = iamUserService.save(iamApiUser); + log.debug("saveUser返回结果:{}, {}", saveResult, iamApiUser); + return IamApiResponseDTO.success(iamApiUser.getId()); + } + + /** + * 更新人员接口 + * 请求方式:PUT + * 请求地址: + * {url}/user/{id} + * @param iamApiUser 人员请求参数实体 + * 请求体(Request Body) + * { + * "name":"xxx", + * "email":"xxx", + * "mobile":"xxx", + * "departmentId":"xxx"//所在组织架构的ID + * } + * @return 更新结果 样例: + * { + * "errorCode": 0, // success + * "errorMsg":null,//若errorCode不为0,此处应有错误描述 + * } + */ + @ApiOperation("更新人员接口") + @PutMapping("/user/{id}") + public IamApiResponseDTO updateUser(@PathVariable("id") String id, @RequestBody IamApiUser iamApiUser) { + log.debug("updateUser请求参数:id={}, user={}", id, iamApiUser); + iamApiUser.setId(id); + boolean updateResult = iamUserService.updateById(iamApiUser); + log.debug("updateUser返回结果:{}", updateResult); + return IamApiResponseDTO.success(); + } + + /** + * 删除/停用人员接口 + * 请求方式:DELETE + * 请求地址: + * {url}/user/{id} + * @param id 人员ID + * @return 删除/停用结果 样例: + * { + * "errorCode": 0, // success + * "errorMsg":null//若errorCode不为0,此处应有错误描述 + * } + */ + @ApiOperation("删除/停用人员接口") + @DeleteMapping("/user/{id}") + public IamApiResponseDTO deleteUser(@PathVariable("id") String id) { + log.debug("deleteUser请求参数:{}", id); + boolean deleteResult = iamUserService.removeById(id); + log.debug("deleteUser返回结果:{}", deleteResult); + return IamApiResponseDTO.success(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/dao/IamDepartmentMapper.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/dao/IamDepartmentMapper.java new file mode 100644 index 0000000..cdf40c7 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/dao/IamDepartmentMapper.java @@ -0,0 +1,7 @@ +package com.chinaunicom.mall.ebtp.extend.iam.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiDepartment; + +public interface IamDepartmentMapper extends BaseMapper { +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/dao/IamUserMapper.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/dao/IamUserMapper.java new file mode 100644 index 0000000..7ff4a9e --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/dao/IamUserMapper.java @@ -0,0 +1,7 @@ +package com.chinaunicom.mall.ebtp.extend.iam.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiUser; + +public interface IamUserMapper extends BaseMapper { +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamApiRequestDTO.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamApiRequestDTO.java new file mode 100644 index 0000000..b31cfc2 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamApiRequestDTO.java @@ -0,0 +1,20 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity; + +import lombok.Data; + +/** + * IAM用户请求DTO + * 用于分页查询IAM用户信息 + */ +@Data +public class IamApiRequestDTO { + /* 分页索引(从0开始) */ + private Integer pageIndex = 0; + /* 分页大小(支持至少300) */ + private Integer pageSize = 10; + + /* 最近变更时间的起始时间(unix毫秒时间戳,用于增量) */ + private Long startTime; + /* 最近变更时间的终止时间(unix毫秒时间戳,用于增量) */ + private Long endTime; +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamApiResponseDTO.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamApiResponseDTO.java new file mode 100644 index 0000000..a0346a1 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamApiResponseDTO.java @@ -0,0 +1,116 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.io.Serializable; + +/** + * IAM基础响应DTO + * 用于统一处理IAM接口的响应格式 + * @param 响应数据类型 + */ +@Data +public class IamApiResponseDTO implements Serializable { + private static final long serialVersionUID = 6769157532172136264L; + /** + * 错误码 + * 0表示成功,其他值表示失败 + */ + private Integer errorCode; + /** + * 错误信息 + */ + private String errorMsg; + /** + * 总记录数 + */ + @JsonInclude(JsonInclude.Include.NON_NULL) + private Integer total; + /** + * 响应数据 + * 泛型类型,具体数据结构由调用方定义 + */ + @JsonInclude(JsonInclude.Include.NON_NULL) + private T data; + + public static IamApiResponseDTO success() { + IamApiResponseDTO resp = new IamApiResponseDTO<>(); + resp.setErrorCode(0); + resp.setErrorMsg(null); + return resp; + } + + public static IamApiResponseDTO success(T data) { + IamApiResponseDTO resp = new IamApiResponseDTO<>(); + resp.setErrorCode(0); + resp.setErrorMsg(null); + resp.setData(data); + return resp; + } + + public static IamApiResponseDTO success(String errorMsg, T data) { + IamApiResponseDTO resp = new IamApiResponseDTO<>(); + resp.setErrorCode(0); + resp.setErrorMsg(errorMsg); + resp.setData(data); + return resp; + } + + public static IamApiResponseDTO fail() { + IamApiResponseDTO resp = new IamApiResponseDTO<>(); + resp.setErrorCode(-1); + resp.setErrorMsg("error"); + return resp; + } + + public static IamApiResponseDTO fail(String errorMsg) { + IamApiResponseDTO resp = new IamApiResponseDTO<>(); + resp.setErrorCode(-1); + resp.setErrorMsg(errorMsg); + resp.setData(null); + return resp; + } + + public static IamApiResponseDTO fail(Integer errorCode, String errorMsg) { + IamApiResponseDTO resp = new IamApiResponseDTO<>(); + resp.setErrorCode(errorCode); + resp.setErrorMsg(errorMsg); + resp.setData(null); + return resp; + } + + public static IamApiResponseDTO fail(T data) { + IamApiResponseDTO resp = new IamApiResponseDTO<>(); + resp.setErrorCode(-1); + resp.setErrorMsg("error"); + resp.setData(null); + return resp; + } + + public static IamApiResponseDTO fail(String errorMsg, T data) { + IamApiResponseDTO resp = new IamApiResponseDTO<>(); + resp.setErrorCode(-1); + resp.setErrorMsg(errorMsg); + resp.setData(null); + return resp; + } + + public static IamApiResponseDTO fail(Integer errorCode, String errorMsg, T data) { + IamApiResponseDTO resp = new IamApiResponseDTO<>(); + resp.setErrorCode(errorCode); + resp.setErrorMsg(errorMsg); + resp.setData(null); + return resp; + } + + public IamApiResponseDTO() { + } + + public IamApiResponseDTO(final Integer errorCode, final String errorMsg, final Integer total, final T data) { + this.errorCode = errorCode; + this.errorMsg = errorMsg; + this.total = total; + this.data = data; + } +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamAuthRequestDTO.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamAuthRequestDTO.java new file mode 100644 index 0000000..65b7310 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamAuthRequestDTO.java @@ -0,0 +1,12 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity; + +import lombok.Data; + +@Data +public class IamAuthRequestDTO { + private String client_id; + private String response_type = "code"; + private String redirect_uri; + private String approval_prompt = "auto"; + private String approved = "true"; +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamAuthResponseDTO.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamAuthResponseDTO.java new file mode 100644 index 0000000..846c79d --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamAuthResponseDTO.java @@ -0,0 +1,44 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity; + +import lombok.Data; + +/** + * (获取code)oauth2认证接口-未认证跳转统一认证前端,已认证则发放code + * { + * "statusCodeValue":0, + * "msg":null, + * "data":"http://10.11.4.13:9999/#/digital?code=501679ca-f036-4ed1-9414-585315d8627d" + * } + * jwt使用员工号免密登录 + * { + * "statusCodeValue": 0, + * "msg": null, + * "data": { + * "ticket": "string", + * "type": "string", + * "token": "string", + * "redirectUrl": null, + * "remeberMe": null, + * "id": "string", + * "name": "string", + * "username": "string", + * "displayName": "string", + * "email": "string", + * "instId": "string", + * "instName": null, + * "passwordSetType": 0, + * "authorities": [ + * "string" + * ], + * "refresh_token": "string", + * "expired": 0 + * } + * } + */ +@Data +public class IamAuthResponseDTO { + private T data; + private String msg; + private Integer statusCodeValue; + +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamToken.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamToken.java new file mode 100644 index 0000000..9161f0e --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamToken.java @@ -0,0 +1,20 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity; + +import lombok.Data; + +/** + * IAM单点登陆Token令牌实体类 + */ +@Data +public class IamToken { + // 访问令牌 + private String access_token; + // 刷新令牌 + private String refresh_token; + // 令牌类型 + private String token_type; + // 过期时间(秒) + private Integer expires_in; + // 授权范围 + private String scope; +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamTokenRequestDTO.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamTokenRequestDTO.java new file mode 100644 index 0000000..dc22ac3 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/IamTokenRequestDTO.java @@ -0,0 +1,30 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity; + +import lombok.Data; + +/** + * 获取IAM token的请求实体 + */ +@Data +public class IamTokenRequestDTO { + /** + * 固定值 authorization_code + */ + private String grant_type; + /** + * 跳转Url带的code参数 + */ + private String code; + /** + * 跳转地址 + */ + private String redirect_uri; + /** + * 应用id + */ + private String client_id; + /** + * 应用密钥 + */ + private String client_secret; +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamApiDepartment.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamApiDepartment.java new file mode 100644 index 0000000..355dd1d --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamApiDepartment.java @@ -0,0 +1,43 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity.data; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * { + * "errorCode": 0, // success + * "total":100,//组织架构总数 + * "data":[ + * { + * "id":"xxx", + * "name":"xxx", + * "parentId":"xxx"//上级组织架构的ID + * "status":"xxx"//标识组织架构的停启用 + * }, + * …… + * ] + * } + */ +@Data +@Accessors(chain = true) +@TableName(value = "iam_api_department", autoResultMap = true) +@ApiModel(value = "IamApiDepartment对象", description = "组织架构基本信息表") +public class IamApiDepartment { + + @TableId(value = "id", type = IdType.ASSIGN_UUID) + private String id; + private String name; + private String parentId; // 上级组织架构的ID + private String status; // 标识组织架构的停启用 + + /** 创建时间 */ + private Date createTime; + /** 修改时间 */ + private Date updateTime; +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamApiUser.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamApiUser.java new file mode 100644 index 0000000..ce4339e --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamApiUser.java @@ -0,0 +1,38 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity.data; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * 提供给IAM同步的用户信息实体 + */ +@Data +@Accessors(chain = true) +@TableName(value = "iam_api_user", autoResultMap = true) +@ApiModel(value = "IamApiUser对象", description = "人员基本信息表") +public class IamApiUser { + /** 用户ID */ + @TableId(value = "id", type = IdType.ASSIGN_UUID) + private String id; + /** 用户名 */ + private String name; + /** 邮箱 */ + private String email; + /** 手机号 */ + private String mobile; + /** 所在组织架构的ID */ + private String departmentId; + /** 标识人员的停启用 */ + private String status; + + /** 创建时间 */ + private Date createTime; + /** 修改时间 */ + private Date updateTime; +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamEmployee.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamEmployee.java new file mode 100644 index 0000000..79a47d1 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamEmployee.java @@ -0,0 +1,23 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity.data; + +import lombok.Data; + +@Data +public class IamEmployee { + private String[] authorities; + private String displayName; + private String email; + private long expired; + private String id; + private String instId; + private Object instName; + private String name; + private long passwordSetType; + private Object redirectUrl; + private String refreshToken; + private Object remeberMe; + private String ticket; + private String token; + private String type; + private String username; +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamUser.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamUser.java new file mode 100644 index 0000000..7b43b17 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/entity/data/IamUser.java @@ -0,0 +1,47 @@ +package com.chinaunicom.mall.ebtp.extend.iam.entity.data; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * IAM单点登录用户信息实体 + */ +@Data +@Accessors(chain = true) +@ApiModel(value = "IamUser对象", description = "人员基本信息表") +public class IamUser implements Serializable { + private static final long serialVersionUID = 1L; + /** 生日 */ + private String birthday; + /** 性别 */ + private Integer gender; + /** 展示名称 */ + private String displayName; + /** 创建日期 */ + private String createdate; + /** 职务 */ + private String title; + /** 用户唯一标识 */ + private String userId; + /** 在线票据 */ + private String online_ticket; + /** 工号 */ + private String employeeNumber; + /** 真实姓名 */ + private String realname; + /** 机构ID */ + private String institution; + /** 随机ID */ + private String randomId; + /** 所在省市/州 */ + private String state; + /** 部门名称 */ + private String department; + /** 用户名(登录名) */ + private String user; + /** 用户名(登录名,冗余) */ + private String username; +} \ No newline at end of file diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamAuthService.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamAuthService.java index b8c3b16..2fb385a 100644 --- a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamAuthService.java +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamAuthService.java @@ -1,8 +1,9 @@ package com.chinaunicom.mall.ebtp.extend.iam.service; import com.chinaunicom.mall.ebtp.extend.iam.client.IamClient; -import com.chinaunicom.mall.ebtp.extend.iam.entity.AuthRequestDTO; -import com.chinaunicom.mall.ebtp.extend.iam.entity.AuthResponseDTO; +import com.chinaunicom.mall.ebtp.extend.iam.entity.*; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamEmployee; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamUser; import org.springframework.stereotype.Service; @Service @@ -24,4 +25,21 @@ public class IamAuthService { } throw new RuntimeException("Failed to get access token, error code: " + response.getErrorCode()); } + + public IamAuthResponseDTO authorize(IamAuthRequestDTO request) { + return iamClient.authorize(request); + } + + public IamAuthResponseDTO employee(String jwt) { + return iamClient.employee(jwt); + } + + public IamUser me(){ + String authToken = "your_auth_token_here"; // Replace with actual auth token retrieval logic + return iamClient.me(authToken); + } + + public IamToken getToken(String authorization, IamTokenRequestDTO request) { + return iamClient.token(authorization, request); + } } diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamDepartmentService.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamDepartmentService.java new file mode 100644 index 0000000..a2ce354 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamDepartmentService.java @@ -0,0 +1,13 @@ +package com.chinaunicom.mall.ebtp.extend.iam.service; + +import com.chinaunicom.mall.ebtp.common.base.service.IBaseService; +import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiDepartment; +import com.baomidou.mybatisplus.core.metadata.IPage; + +import java.util.List; + +public interface IamDepartmentService extends IBaseService { + + IPage getDepartments(IamApiRequestDTO iamDepartmentRequestDTO); +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamUserService.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamUserService.java new file mode 100644 index 0000000..2d196a1 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/IamUserService.java @@ -0,0 +1,13 @@ +package com.chinaunicom.mall.ebtp.extend.iam.service; + +import com.chinaunicom.mall.ebtp.common.base.service.IBaseService; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiUser; +import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO; +import com.baomidou.mybatisplus.core.metadata.IPage; + +import java.util.List; + +public interface IamUserService extends IBaseService { + + IPage getUsers(IamApiRequestDTO iamUserRequestDTO); +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/impl/IamDepartmentServiceImpl.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/impl/IamDepartmentServiceImpl.java new file mode 100644 index 0000000..7ed6efb --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/impl/IamDepartmentServiceImpl.java @@ -0,0 +1,39 @@ +package com.chinaunicom.mall.ebtp.extend.iam.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.chinaunicom.mall.ebtp.extend.iam.dao.IamDepartmentMapper; +import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiDepartment; +import com.chinaunicom.mall.ebtp.extend.iam.service.IamDepartmentService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Collections; +import java.util.List; + +@Service +public class IamDepartmentServiceImpl extends ServiceImpl implements IamDepartmentService { + + @Resource + private IamDepartmentMapper iamDepartmentMapper; + + + @Override + public IPage getDepartments(IamApiRequestDTO iamDepartmentRequestDTO) { + int pageIndex = iamDepartmentRequestDTO.getPageIndex() != null ? iamDepartmentRequestDTO.getPageIndex() : 0; + int pageSize = iamDepartmentRequestDTO.getPageSize() != null ? iamDepartmentRequestDTO.getPageSize() : 10; + Page page = new Page<>(pageIndex + 1, pageSize); // MyBatis-Plus页码从1开始 + QueryWrapper queryWrapper = new QueryWrapper<>(); + // 可根据startTime、endTime等条件添加查询条件 + if (iamDepartmentRequestDTO.getStartTime() != null) { + queryWrapper.ge("update_time", iamDepartmentRequestDTO.getStartTime()); + } + if (iamDepartmentRequestDTO.getEndTime() != null) { + queryWrapper.le("update_time", iamDepartmentRequestDTO.getEndTime()); + } + return iamDepartmentMapper.selectPage(page, queryWrapper); + } +} \ No newline at end of file diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/impl/IamUserServiceImpl.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/impl/IamUserServiceImpl.java new file mode 100644 index 0000000..2a54a6a --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/iam/service/impl/IamUserServiceImpl.java @@ -0,0 +1,37 @@ +package com.chinaunicom.mall.ebtp.extend.iam.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.chinaunicom.mall.ebtp.extend.iam.dao.IamUserMapper; +import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiUser; +import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO; +import com.chinaunicom.mall.ebtp.extend.iam.service.IamUserService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +public class IamUserServiceImpl extends ServiceImpl implements IamUserService { + + @Resource + private IamUserMapper iamUserMapper; + + + @Override + public IPage getUsers(IamApiRequestDTO iamUserRequestDTO) { + int pageIndex = iamUserRequestDTO.getPageIndex() != null ? iamUserRequestDTO.getPageIndex() : 0; + int pageSize = iamUserRequestDTO.getPageSize() != null ? iamUserRequestDTO.getPageSize() : 10; + Page page = new Page<>(pageIndex + 1, pageSize); // MyBatis-Plus页码从1开始,接口从0开始 + QueryWrapper queryWrapper = new QueryWrapper<>(); + // 可根据startTime、endTime等条件添加查询条件 + if (iamUserRequestDTO.getStartTime() != null) { + queryWrapper.ge("update_time", iamUserRequestDTO.getStartTime()); + } + if (iamUserRequestDTO.getEndTime() != null) { + queryWrapper.le("update_time", iamUserRequestDTO.getEndTime()); + } + return iamUserMapper.selectPage(page, queryWrapper); + } +} \ No newline at end of file