diff --git a/demo-athenaopt_backend/develop/conf/application.properties b/demo-athenaopt_backend/develop/conf/application.properties index 9756e34..45d1380 100644 --- a/demo-athenaopt_backend/develop/conf/application.properties +++ b/demo-athenaopt_backend/develop/conf/application.properties @@ -1,4 +1,4 @@ -appId=athena +appId=@appId@ configCenterUrl=@configCenterUrl@ configPolicy=@configPolicy@ isRemoteConfigOn=@isRemoteConfigOn@ @@ -9,6 +9,7 @@ configGroup=@configGroup@ #SMALLVERSION=@SMALLVERSION@ #springConfigFileNames=xxx.xml,xxx.xml iamApToken=@iamApToken@ +iamApTokenForLogin=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MzczMjY2ODk0NjEsInNpZCI6NDA3MTI4ODI1NTM0NDY0MSwiaWQiOiJEaWdpd2luQ2xvdWQifQ.XGPl3brNeNTCivWN_bIYj8TfcxqlkQ0sFV2woPOr0TY dmcUserName=@dmcUserName@ dmcPwd=@dmcPwd@ dmcBucketName=@dmcBucketName@ @@ -93,3 +94,5 @@ domain.lmc=@lmcUrl@ opt.mybatisPlus.enable=true +eventCenterUrl=@eventCenterUrl@ + diff --git a/demo-athenaopt_backend/develop/conf/log4j2.xml b/demo-athenaopt_backend/develop/conf/log4j2.xml index c3be72c..1aa79d7 100644 --- a/demo-athenaopt_backend/develop/conf/log4j2.xml +++ b/demo-athenaopt_backend/develop/conf/log4j2.xml @@ -61,7 +61,7 @@ - + diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/constant/GlobalConstants.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/constant/GlobalConstants.java new file mode 100644 index 0000000..9e54c18 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/constant/GlobalConstants.java @@ -0,0 +1,103 @@ +package com.digiwin.athena.app.infra.constant; + +/** + * 全局常量 + * + * @author fobgochod + * @date 2020/4/27 + */ +public class GlobalConstants { + + /** + * 访问凭证 + */ + public static final String DIGI_MIDDLEWARE_AUTH_ACCESS = "digi-middleware-auth-access"; + /** + * 在HttpHeader中传递的User信息 + */ + public static final String AUTH_USER = "digi-middleware-auth-user-data"; + /** + * 在HttpHeader中传递的App信息 + */ + public static final String APP = "digi-middleware-auth-app-data"; + /** + * 在HttpHeader中传递的OTA Token信息 + */ + public static final String HTTP_HEADER_OTA_TOKEN_KEY = "digi-middleware-auth-ota"; + /** + * 在HttpHeader中传递的Access Token信息 + */ + public static final String HTTP_HEADER_ACCESS_TOKEN_KEY = "digi-middleware-auth-access"; + /** + * 在HttpHeader中传递的User Token信息 + */ + public static final String HTTP_HEADER_USER_TOKEN_KEY = "digi-middleware-auth-user"; + /** + * 在HttpHeader中传递的APP Token信息 + */ + public static final String HTTP_HEADER_APP_TOKEN_KEY = "digi-middleware-auth-app"; + /** + * 在HttpHeader中传递的Driver Token信息 + */ + public static final String HTTP_HEADER_DRIVE_TOKEN_KEY = "digi-middleware-drive-access"; + /** + * 在HttpHeader中传递 是都需要加密 + */ + public static final String HTTP_HEADER_DATA_MASK = "digi-middleware-data-mask"; + /** + * 在HttpHeader中传递 租户ID + */ + public static final String HTTP_HEADER_TENANT_ID = "tenantId"; + /** + * 在HttpHeader中传递 设备信息 + */ + public static final String HTTP_HEADER_CLIENT_AGENT = "Client-Agent"; + + /** + * 查询时,若為歸戶資料,請填入固定值: iam-mapping + */ + public static final String QUERY_PARAMETER_MAPPING = "iam-mapping"; + public static final String ZONE_OFF_SET = "+8"; + public static final String DEV_ACTIVE = "dev"; + + public static final String EMPTY_STR = "[empty]"; + + public static final String UPDATE_ALL = "all"; + public static final String UPDATE_ONLY_APPEND = "onlyAppend"; + + public static final String ADMINISTRATORS = "administrators"; + public static final String ADMINISTRATOR = "administrator"; + public static final String INTEGRATION = "integration"; + public static final String SUPERADMIN = "superadmin"; + public static final String GUEST = "guest"; + + public static final String ERROR_MESSAGE = "Server internal error"; + public static final String ENV_DEV = "dev"; + public static final String ENV_PROD = "prod"; + public static final String ENV_TEST = "test"; + public static final char AT = '@'; + public static final char DOT = '.'; + public static final char TAB = '\t'; + public static final char DASH = '-'; + public static final char COLON = ':'; + public static final char COMMA = ','; + public static final char DOLLAR = '$'; + public static final char PERCENT = '%'; + public static final char ESCAPE = '\\'; + public static final char ASTERISK = '*'; + public static final char SEMICOLON = ';'; + public static final char CURLY_LEFT = '{'; + public static final char CURLY_RIGHT = '}'; + public static final char DOUBLE_QUOTE = '"'; + public static final char SINGLE_QUOTE = '\''; + public static final char LEFT_PARENTHESIS = '('; + public static final char RIGHT_PARENTHESIS = ')'; + public static final String EMPTY = ""; + public static final String TRUE = "true"; + public static final String FALSE = "false"; + public static final String DEFAULT_VALUE_SEPARATOR = ":-"; + public static final String DEFAULT_CONTEXT_NAME = "default"; + public static final String LINE_SEPARATOR = System.getProperty("line.separator"); + public static final String ACCEPT_LANGUAGE = "Accept-Language"; + public static final String LOCALE = "Locale"; +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/entity/DigiwinSummit.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/entity/DigiwinSummit.java new file mode 100644 index 0000000..2d1859f --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/entity/DigiwinSummit.java @@ -0,0 +1,39 @@ +/* + * Author: DONGSK + * Datetime: 2024/4/25 16:43 + * Description: + * History: + * 作者姓名 --修改时间 --版本号--描述 + */ +package com.digiwin.athena.app.infra.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.io.Serializable; + +/** + * DigiwinSummit + * + * @author DONGSK 2024/4/25 16:43 + * @since 1.0.0 + */ +@Data +@TableName(value = "digiwin_summit", autoResultMap = true) +public class DigiwinSummit extends Model implements Serializable { + Long id; + @TableField(value = "user_id") + String userId; + @TableField(value = "tenant_id") + String tenantId; + @TableField(value = "ref_prod") + String refProd; + @TableField(value = "ref_user_id") + String refUserId; + @TableField(value = "ref_tenant_sid") + String refTenantSid; + @TableField(value = "ref_user_password") + String refUserPassword; +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/entity/LayoutConfig.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/entity/LayoutConfig.java new file mode 100644 index 0000000..f0907cc --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/entity/LayoutConfig.java @@ -0,0 +1,48 @@ +/* + * Author: DONGSK + * Datetime: 2024/4/25 16:43 + * Description: + * History: + * 作者姓名 --修改时间 --版本号--描述 + */ +package com.digiwin.athena.app.infra.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.io.Serializable; + +/** + * DigiwinSummit + * + * @author DONGSK 2024/4/25 16:43 + * @since 1.0.0 + */ +@Data +@TableName(value = "layout_config", autoResultMap = true) +public class LayoutConfig extends Model implements Serializable { + @TableField(value = "sys_id") + String sysId; + @TableField(value = "user_id") + String userId; + @TableField(value = "tenant_id") + String tenantId; + @TableField(value = "top_px") + String top; + @TableField(value = "left_px") + String left; + @TableField(value = "height_px") + String height; + @TableField(value = "width_px") + String width; + @TableField(value = "width_percent") + String widthPercent; + @TableField(value = "height_percent") + String heightPercent; + @TableField(value = "top_percent") + String topPercent; + @TableField(value = "left_percent") + String leftPercent; +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/repository/DigiwinSummitRepository.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/repository/DigiwinSummitRepository.java new file mode 100644 index 0000000..fa96455 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/repository/DigiwinSummitRepository.java @@ -0,0 +1,20 @@ +/* + * Author: DONGSK + * Datetime: 2024/4/25 16:49 + * Description: + * History: + * 作者姓名 --修改时间 --版本号--描述 + */ +package com.digiwin.athena.app.infra.repository; + +import com.digiwin.athena.app.infra.entity.DigiwinSummit; +import com.digiwin.athena.opt.persistence.repository.BaseRepository; + +/** + * DigiwinSummitRepository + * + * @author DONGSK 2024/4/25 16:49 + * @since 1.0.0 + */ +public interface DigiwinSummitRepository extends BaseRepository { +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/repository/LayoutConfigRepository.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/repository/LayoutConfigRepository.java new file mode 100644 index 0000000..e05ebc6 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/repository/LayoutConfigRepository.java @@ -0,0 +1,20 @@ +/* + * Author: DONGSK + * Datetime: 2024/4/25 16:49 + * Description: + * History: + * 作者姓名 --修改时间 --版本号--描述 + */ +package com.digiwin.athena.app.infra.repository; + +import com.digiwin.athena.app.infra.entity.LayoutConfig; +import com.digiwin.athena.opt.persistence.repository.BaseRepository; + +/** + * DigiwinSummitRepository + * + * @author DONGSK 2024/4/25 16:49 + * @since 1.0.0 + */ +public interface LayoutConfigRepository extends BaseRepository { +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/DigiwinSummitService.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/DigiwinSummitService.java new file mode 100644 index 0000000..ee28292 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/DigiwinSummitService.java @@ -0,0 +1,7 @@ +package com.digiwin.athena.app.infra.service; + +import com.digiwin.athena.app.infra.entity.DigiwinSummit; +import com.digiwin.athena.opt.persistence.service.IBaseService; + +public interface DigiwinSummitService extends IBaseService { +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/Impl/DigiwinSummitServiceImpl.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/Impl/DigiwinSummitServiceImpl.java new file mode 100644 index 0000000..60fc358 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/Impl/DigiwinSummitServiceImpl.java @@ -0,0 +1,16 @@ +package com.digiwin.athena.app.infra.service.Impl; + +import com.digiwin.athena.app.infra.entity.DigiwinSummit; +import com.digiwin.athena.app.infra.repository.DigiwinSummitRepository; +import com.digiwin.athena.app.infra.service.DigiwinSummitService; +import com.digiwin.athena.opt.persistence.service.impl.AbsBaseService; +import org.springframework.stereotype.Service; + +/** + * @author zhenggl + * create: 2023-04-28 + * Description: + */ +@Service +public class DigiwinSummitServiceImpl extends AbsBaseService implements DigiwinSummitService { +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/Impl/LayoutConfigServiceImpl.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/Impl/LayoutConfigServiceImpl.java new file mode 100644 index 0000000..7158a33 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/Impl/LayoutConfigServiceImpl.java @@ -0,0 +1,16 @@ +package com.digiwin.athena.app.infra.service.Impl; + +import com.digiwin.athena.app.infra.entity.LayoutConfig; +import com.digiwin.athena.app.infra.repository.LayoutConfigRepository; +import com.digiwin.athena.app.infra.service.LayoutConfigService; +import com.digiwin.athena.opt.persistence.service.impl.AbsBaseService; +import org.springframework.stereotype.Service; + +/** + * @author zhenggl + * create: 2023-04-28 + * Description: + */ +@Service +public class LayoutConfigServiceImpl extends AbsBaseService implements LayoutConfigService { +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/LayoutConfigService.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/LayoutConfigService.java new file mode 100644 index 0000000..212cfa3 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/infra/service/LayoutConfigService.java @@ -0,0 +1,7 @@ +package com.digiwin.athena.app.infra.service; + +import com.digiwin.athena.app.infra.entity.LayoutConfig; +import com.digiwin.athena.opt.persistence.service.IBaseService; + +public interface LayoutConfigService extends IBaseService { +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/BasicApiService.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/BasicApiService.java index e57a962..d85d61b 100644 --- a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/BasicApiService.java +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/BasicApiService.java @@ -13,6 +13,7 @@ import com.digiwin.app.service.restful.DWPathVariable; import com.digiwin.app.service.restful.DWRequestMapping; import com.digiwin.app.service.restful.DWRequestMethod; import com.digiwin.app.service.restful.DWRestfulService; +import com.digiwin.athena.app.infra.entity.LayoutConfig; import java.util.Map; @@ -32,4 +33,21 @@ public interface BasicApiService extends DWService { @DWRequestMapping(path = "/EAIService/{serviceName}", method = DWRequestMethod.POST) Object mockEAIExecutor(@DWPathVariable String serviceName, Map requestParameter) throws Exception; + + @AllowAnonymous + @DWRequestMapping(path = "/api/default/login", method = DWRequestMethod.POST) + Object login(String userId, String tenantId, String productKey) throws Exception; + + @AllowAnonymous + @DWRequestMapping(path = "/api/clear/login", method = DWRequestMethod.GET) + Object clearLogin() throws Exception; + + @AllowAnonymous + @DWRequestMapping(path = "/api/517/config/save", method = DWRequestMethod.POST) + Object layoutConfig(LayoutConfig layoutConfig) throws Exception; + + @AllowAnonymous + @DWRequestMapping(path = "/api/517/config/list", method = DWRequestMethod.POST) + Object layoutConfig(String userId, String tenantId, String sysId) throws Exception; + } \ No newline at end of file diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/QuotationRequirementEAIService.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/QuotationRequirementEAIService.java new file mode 100644 index 0000000..f498bf6 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/QuotationRequirementEAIService.java @@ -0,0 +1,29 @@ +package com.digiwin.athena.app.provider; + +import com.digiwin.app.service.AllowAnonymous; +import com.digiwin.app.service.DWEAIResult; +import com.digiwin.app.service.DWService; +import com.digiwin.app.service.eai.EAIService; +import com.digiwin.athena.app.service.quotation.QuotationUtil; + +import java.util.Map; + +/** + * @author lz + * @version 1.0 + * @title QuotationRequirementEAIService + * @description + * @create 2024/4/29 10:20 + */ +public interface QuotationRequirementEAIService extends DWService { + + /** + * 报价需求查询 + * @param headers + * @param messageBody + * @return + * @throws Exception + */ + @EAIService(id = QuotationUtil.DEMO_ATHENAOPT_REQUIREMENT_INFO_GET) + DWEAIResult get(Map headers, String messageBody) throws Exception; +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/impl/BasicApiServiceImpl.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/impl/BasicApiServiceImpl.java index 5d2e172..bebf2cd 100644 --- a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/impl/BasicApiServiceImpl.java +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/impl/BasicApiServiceImpl.java @@ -9,12 +9,18 @@ package com.digiwin.athena.app.provider.impl; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.digiwin.app.service.DWServiceContext; +import com.digiwin.athena.app.infra.entity.LayoutConfig; +import com.digiwin.athena.app.infra.service.LayoutConfigService; import com.digiwin.athena.app.provider.BasicApiService; +import com.digiwin.athena.app.service.basic.LoginService; import com.digiwin.athena.opt.common.eai.service.EAIServiceContext; +import org.apache.commons.lang.StringUtils; import javax.annotation.Resource; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -28,6 +34,12 @@ public class BasicApiServiceImpl implements BasicApiService { @Resource EAIServiceContext eaiServiceContext; + @Resource + LoginService loginService; + + @Resource + LayoutConfigService layoutConfigService; + @Override public String helloWord(String name) throws Exception { return "hello ," + name; @@ -41,10 +53,72 @@ public class BasicApiServiceImpl implements BasicApiService { }); DWServiceContext.getContext().setStandardResult(false); /** 直接返回,不再包装,入参可以体现 serviceName - Map eaiResult = new HashMap<>(); - eaiResult.put("service", serviceName); - eaiResult.put("response", eaiServiceContext.execute(serviceName, headers, JSON.toJSONString(requestParameter))); - */ - return eaiServiceContext.execute(serviceName, headers, JSON.toJSONString(requestParameter)); + Map eaiResult = new HashMap<>(); + eaiResult.put("service", serviceName); + eaiResult.put("response", eaiServiceContext.execute(serviceName, headers, JSON.toJSONString(requestParameter))); + */ + return eaiServiceContext.execute(serviceName, headers, JSON.toJSONString(requestParameter)); } + + @Override + public Object login(String userId, String tenantId, String productKey) throws Exception { + return loginService.login(userId, tenantId, productKey); + } + + @Override + public Object clearLogin() throws Exception { + loginService.clearLoginMap(); + return "ok"; + } + + @Override + public Object layoutConfig(LayoutConfig layoutConfig) throws Exception { + LambdaQueryChainWrapper lambdaQuery = layoutConfigService.lambdaQuery() + .eq(LayoutConfig::getUserId, layoutConfig.getUserId()) + .eq(LayoutConfig::getTenantId, layoutConfig.getTenantId()) + .eq(LayoutConfig::getSysId, layoutConfig.getSysId()); + if (lambdaQuery.exists()) { + return layoutConfigService.lambdaUpdate() + .set(LayoutConfig::getTop, layoutConfig.getTop()) + .set(LayoutConfig::getLeft, layoutConfig.getLeft()) + .set(LayoutConfig::getWidth, layoutConfig.getWidth()) + .set(LayoutConfig::getHeight, layoutConfig.getHeight()) + .set(LayoutConfig::getTopPercent, layoutConfig.getTopPercent()) + .set(LayoutConfig::getLeftPercent, layoutConfig.getLeftPercent()) + .set(LayoutConfig::getWidthPercent, layoutConfig.getWidthPercent()) + .set(LayoutConfig::getHeightPercent, layoutConfig.getHeightPercent()) + .eq(LayoutConfig::getUserId, layoutConfig.getUserId()) + .eq(LayoutConfig::getTenantId, layoutConfig.getTenantId()) + .eq(LayoutConfig::getSysId, layoutConfig.getSysId()) + .update(); + } else { + return layoutConfigService.save(layoutConfig); + } + } + + @Override + public Object layoutConfig(String userId, String tenantId, String sysId) throws Exception { + + LambdaQueryChainWrapper lambdaQuery = layoutConfigService.lambdaQuery(); + lambdaQuery.eq(LayoutConfig::getUserId, userId); + lambdaQuery.eq(LayoutConfig::getTenantId, tenantId); + if (StringUtils.isNotBlank(sysId)) { + lambdaQuery.eq(LayoutConfig::getSysId, sysId); + } + + List list = lambdaQuery.list(); + + if (list.isEmpty()) { + LambdaQueryChainWrapper lambdaQueryX = layoutConfigService.lambdaQuery(); + lambdaQueryX.eq(LayoutConfig::getUserId, "default"); + lambdaQueryX.eq(LayoutConfig::getTenantId, tenantId); + if (StringUtils.isNotBlank(sysId)) { + lambdaQueryX.eq(LayoutConfig::getSysId, sysId); + } + list = lambdaQueryX.list(); + } + + return list; + } + } diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/impl/QuotationRequirementEAIServiceImpl.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/impl/QuotationRequirementEAIServiceImpl.java new file mode 100644 index 0000000..2a1da06 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/provider/impl/QuotationRequirementEAIServiceImpl.java @@ -0,0 +1,27 @@ +package com.digiwin.athena.app.provider.impl; + +import com.digiwin.app.service.DWEAIResult; +import com.digiwin.athena.app.provider.QuotationRequirementEAIService; +import com.digiwin.athena.app.service.quotation.QuotationUtil; +import com.digiwin.athena.opt.common.eai.service.EAIServiceContext; + +import javax.annotation.Resource; +import java.util.Map; + +/** + * @author lz + * @version 1.0 + * @title PurchaseDemoEAIServiceImpl + * @description + * @create 2023/8/30 16:50 + */ +public class QuotationRequirementEAIServiceImpl implements QuotationRequirementEAIService { + + @Resource + private EAIServiceContext eaiServiceContext; + + @Override + public DWEAIResult get(Map headers, String messageBody) throws Exception { + return eaiServiceContext.execute(QuotationUtil.DEMO_ATHENAOPT_REQUIREMENT_INFO_GET , headers, messageBody); + } +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/basic/AESUtils.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/basic/AESUtils.java new file mode 100644 index 0000000..76e3716 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/basic/AESUtils.java @@ -0,0 +1,86 @@ +package com.digiwin.athena.app.service.basic; + +import org.apache.commons.codec.binary.Hex; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +public class AESUtils { + + + private static final Logger logger = LoggerFactory.getLogger(AESUtils.class); + private static final String IV_STRING = "ghUb#er57HBh(u%g"; + + /** + * 加密 + * 加密失败返回原文 2021-7-21 + * + * @param src 加密字段 + * @param aesKey aesKey 长度16 + * @return 密文 string + */ + public static String aesEncryptByBase64(String src, String aesKey) { + try { + SecretKeySpec key = new SecretKeySpec(aesKey.getBytes(StandardCharsets.UTF_8), "AES"); + + byte[] initParam = IV_STRING.getBytes(StandardCharsets.UTF_8); + IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec); + + byte[] cleartext = src.getBytes(StandardCharsets.UTF_8); + byte[] ciphertextBytes = cipher.doFinal(cleartext); + Base64.Encoder encoder = Base64.getEncoder(); + return encoder.encodeToString(ciphertextBytes); + } catch (Exception ex) { + logger.error("AES加密失败[{}]", src); + return src; + } + + } + + public static String aesEncrypt(String src, String aesKey) { + try { + // 生成和mysql一致的加密数据 + SecretKeySpec key = generateMySQLAESKey(aesKey); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, key); + + byte[] cleartext = src.getBytes(StandardCharsets.UTF_8); + byte[] ciphertextBytes = cipher.doFinal(cleartext); + return new String(Hex.encodeHexString(ciphertextBytes)).toUpperCase(); + } catch (Exception ex) { + logger.error("AES加密失败[{}]", src); + return src; + } + } + + public static String aesDecrypt(String content, String aesKey) { + try { + SecretKey key = generateMySQLAESKey(aesKey); + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, key); + byte[] cleartext = Hex.decodeHex(content.toCharArray()); + byte[] ciphertextBytes = cipher.doFinal(cleartext); + return new String(ciphertextBytes, StandardCharsets.UTF_8); + } catch (Exception ex) { + logger.error("AES解密失败[{}]", content); + return content; + } + } + + public static SecretKeySpec generateMySQLAESKey(final String key) { + final byte[] finalKey = new byte[16]; + int i = 0; + for (byte b : key.getBytes(StandardCharsets.UTF_8)) { + finalKey[i++ % 16] ^= b; + } + return new SecretKeySpec(finalKey, "AES"); + } +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/basic/LoginService.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/basic/LoginService.java new file mode 100644 index 0000000..0728040 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/basic/LoginService.java @@ -0,0 +1,176 @@ +/* + * Author: DONGSK + * Datetime: 2024/4/25 14:08 + * Description: 登录服务 + * History: + * 作者姓名 --修改时间 --版本号--描述 + */ +package com.digiwin.athena.app.service.basic; + +import com.digiwin.athena.app.infra.constant.GlobalConstants; +import com.digiwin.athena.app.infra.entity.DigiwinSummit; +import com.digiwin.athena.app.infra.service.DigiwinSummitService; +import org.apache.commons.codec.binary.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.*; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; + +/** + * LoginService + * 登录服务 + * + * @author DONGSK 2024/4/25 14:08 + * @since 1.0.0 + */ +@Service +public class LoginService { + + private static final Logger logger = LoggerFactory.getLogger(LoginService.class); + + public static final Map loginDataMap = new HashMap<>(); + + public static final String mapKey = "%s_%s_%s"; + + @Value("${iamApTokenForLogin}") + private String iamApToken; + + @Value("${iamUrl}") + private String iamURL; + + @Resource + RestTemplate restTemplate; + + @Resource + DigiwinSummitService digiwinSummitService; + + public Object login(String userId, String tenantId, String productKey) { + String uri = iamURL + "/api/iam/v2/identity/login"; + try { + initLoginMap(); + + String mapKey = String.format(LoginService.mapKey, userId, tenantId, productKey); + DigiwinSummit digiwinSummit = loginDataMap.get(mapKey); + + if (digiwinSummit == null) { + return null; + } + // password + String password = digiwinSummit.getRefUserPassword(); + //1.客户端生成公私钥 + HashMap keyMap = getKeyPairMap(); + String clientPublicKey = keyMap.get("publicKey"); + String privateKey = keyMap.get("privateKey"); + //2.获取服务端公钥 + String serverPublicKey = getServerPublicKey(); + //3.根据服务端公钥加密客户端公钥 + String encryptPublicKey = RSAUtils.encryptByPublicKey(clientPublicKey, serverPublicKey); + //4.获取加密后的AES的key值 + String encryptAesKey = getAesPublicKey(encryptPublicKey); + //5.根据客户端私有解密加密的aes的key值 + String aesKey = new String(RSAUtils.decryptByPrivateKey(Base64.decodeBase64(encryptAesKey), privateKey)); + String passwordHash = AESUtils.aesEncryptByBase64(password, aesKey); + //6.登录 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add(GlobalConstants.HTTP_HEADER_APP_TOKEN_KEY, iamApToken); + Map requestEntity = new HashMap<>(3); + requestEntity.put("identityType", "token"); + requestEntity.put("userId", digiwinSummit.getRefUserId()); + requestEntity.put("passwordHash", passwordHash); + requestEntity.put("clientEncryptPublicKey", encryptPublicKey); + HttpEntity> httpEntity = new HttpEntity<>(requestEntity, headers); + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.POST, httpEntity, Map.class); + // 切租户 + return changeTenant(Long.valueOf(digiwinSummit.getRefTenantSid()), response.getBody().get("token").toString()); + + } catch (Exception ex) { + logger.error("登录失败:{}", ex.getMessage(), ex); + } + return null; + } + + private Object changeTenant(Long sid, String userToken) { + String uri = iamURL + "/api/iam/v2/identity/token/refresh/tenant"; + try { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add(GlobalConstants.HTTP_HEADER_APP_TOKEN_KEY, iamApToken); + headers.add(GlobalConstants.HTTP_HEADER_USER_TOKEN_KEY, userToken); + Map requestEntity = new HashMap<>(); + requestEntity.put("tenantSid", sid); + HttpEntity> httpEntity = new HttpEntity<>(requestEntity, headers); + ResponseEntity exchange = restTemplate.exchange(uri, HttpMethod.POST, httpEntity, Map.class); + return exchange.getBody(); + } catch (Exception e) { + logger.error("切换失败:{}", e.getMessage(), e); + } + return ""; + } + + private HashMap getKeyPairMap() throws NoSuchAlgorithmException { + KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); + generator.initialize(1024); + KeyPair keyPair = generator.generateKeyPair(); + String privateKey = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded())); + String publicKey = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded())); + HashMap keyMap = new HashMap<>(); + keyMap.put("privateKey", privateKey); + keyMap.put("publicKey", publicKey); + return keyMap; + } + + private String getServerPublicKey() { + String uri = iamURL + "/api/iam/v2/identity/publickey"; + try { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add(GlobalConstants.HTTP_HEADER_APP_TOKEN_KEY, iamApToken); + HttpEntity> httpEntity = new HttpEntity<>(headers); + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, httpEntity, Map.class); + return String.valueOf(response.getBody().get("publicKey")); + } catch (Exception e) { + logger.error("登录失败:{}", e.getMessage(), e); + } + return ""; + } + + private String getAesPublicKey(String encryptPublicKey) { + String uri = iamURL + "/api/iam/v2/identity/aeskey"; + try { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add(GlobalConstants.HTTP_HEADER_APP_TOKEN_KEY, iamApToken); + Map requestEntity = new HashMap<>(1); + requestEntity.put("clientEncryptPublicKey", encryptPublicKey); + HttpEntity> httpEntity = new HttpEntity<>(requestEntity, headers); + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.POST, httpEntity, Map.class); + return String.valueOf(response.getBody().get("encryptAesKey")); + } catch (Exception e) { + logger.error("登录失败:{}", e.getMessage(), e); + } + return ""; + } + + private void initLoginMap() { + if (loginDataMap.isEmpty()) { + digiwinSummitService.list().forEach(item -> { + loginDataMap.put(String.format(mapKey, item.getUserId(), item.getTenantId(), item.getRefProd()), item); + }); + } + } + + public void clearLoginMap() { + loginDataMap.clear(); + } + +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/basic/RSAUtils.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/basic/RSAUtils.java new file mode 100644 index 0000000..a183fa5 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/basic/RSAUtils.java @@ -0,0 +1,118 @@ +package com.digiwin.athena.app.service.basic; + + +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.Cipher; +import java.io.ByteArrayOutputStream; +import java.security.Key; +import java.security.KeyFactory; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * @author zhuzcz + */ +public class RSAUtils { + /** + * 加密算法RSA + */ + public static final String KEY_ALGORITHM = "RSA"; + + /** + * RSA最大加密明文大小 + */ + private static final int MAX_ENCRYPT_BLOCK = 245; + + /** + * RSA最大解密密文大小 + */ + private static final int MAX_DECRYPT_BLOCK = 256; + + + /** */ + /** + *

+ * 私钥解密 + *

+ * + * @param encryptedData 已加密数据 + * @param privateKey 私钥(BASE64编码) + * @return + * @throws Exception + */ + public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { + byte[] keyBytes = Base64.decodeBase64(privateKey); + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, privateK); + int inputLen = encryptedData.length; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + int offSet = 0; + byte[] cache; + int i = 0; + // 对数据分段解密 + while (inputLen - offSet > 0) { + if (inputLen - offSet > MAX_DECRYPT_BLOCK) { + cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); + } else { + cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); + } + out.write(cache, 0, cache.length); + i++; + offSet = i * MAX_DECRYPT_BLOCK; + } + byte[] decryptedData = out.toByteArray(); + out.close(); + return decryptedData; + } + + + /** */ + /** + *

+ * 公钥加密 + *

+ * + * @param data 源数据 + * @param publicKey 公钥(BASE64编码) + * @return + * @throws Exception + */ + public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception { + byte[] keyBytes = Base64.decodeBase64(publicKey); + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + Key publicK = keyFactory.generatePublic(x509KeySpec); + // 对数据加密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, publicK); + int inputLen = data.length; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + int offSet = 0; + byte[] cache; + int i = 0; + // 对数据分段加密 + while (inputLen - offSet > 0) { + if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { + cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); + } else { + cache = cipher.doFinal(data, offSet, inputLen - offSet); + } + out.write(cache, 0, cache.length); + i++; + offSet = i * MAX_ENCRYPT_BLOCK; + } + byte[] encryptedData = out.toByteArray(); + out.close(); + return encryptedData; + } + + public static String encryptByPublicKey(String data, String clientPublicKey) throws Exception { + data = Base64.encodeBase64String(encryptByPublicKey(data.getBytes(), clientPublicKey)); + return data; + } + +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/quotation/QuotationRequirementInfoGetService.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/quotation/QuotationRequirementInfoGetService.java new file mode 100644 index 0000000..78d8f30 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/quotation/QuotationRequirementInfoGetService.java @@ -0,0 +1,109 @@ +package com.digiwin.athena.app.service.quotation; + +import com.alibaba.fastjson.JSONObject; +import com.digiwin.app.service.DWEAIResult; +import com.digiwin.athena.opt.common.eai.EAIUtil; +import com.digiwin.athena.opt.common.eai.service.AbsEAIService; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * @author lz + * @version 1.0 + * @title QuotationRequirement + * @description mock需求数据 + * @create 2024/4/29 10:00 + */ +@Service +public class QuotationRequirementInfoGetService extends AbsEAIService { + + @Override + public String getServiceName() { + return QuotationUtil.DEMO_ATHENAOPT_REQUIREMENT_INFO_GET; + } + + @Override + public DWEAIResult execute(Map headers, String messageBody) throws Exception { + + List> requirementInfo = getRequirementInfo(); + + return EAIUtil.buildEAIResult(new JSONObject().fluentPut("requirement_info", requirementInfo)); + } + + + /** + * @description mock需求数据 + * @author lz + * @throws + * @time 2024/4/29 10:16 + */ + public static List> getRequirementInfo() { + List> requirementInfo = new ArrayList<>(); + + // 第一个需求 + Map requirement1 = new HashMap<>(); + List correlationCode1 = Arrays.asList("100203"); + requirement1.put("correlation_code", correlationCode1); + requirement1.put("requirement_no", "100203"); + requirement1.put("requirement_name", "产品色"); + requirement1.put("requirement_description", ""); + requirementInfo.add(requirement1); + + // 第二个需求 + Map requirement2 = new HashMap<>(); + List correlationCode2 = Arrays.asList("100203", "1-1"); + requirement2.put("correlation_code", correlationCode2); + requirement2.put("requirement_no", "100203"); + requirement2.put("requirement_name", "是否定制-客户定制色或工厂标准色"); + requirement2.put("requirement_description", ""); + requirementInfo.add(requirement2); + + // 第三个需求 + Map requirement3 = new HashMap<>(); + List correlationCode3 = Arrays.asList("100203", "2-1"); + requirement3.put("correlation_code", correlationCode3); + requirement3.put("requirement_no", "100203"); + requirement3.put("requirement_name", "产品色系-2"); + requirement3.put("requirement_description", ""); + requirementInfo.add(requirement3); + + // 第四个需求 + Map requirement4 = new HashMap<>(); + List correlationCode4 = Arrays.asList("100203", "3-1"); + requirement4.put("correlation_code", correlationCode4); + requirement4.put("requirement_no", "100203"); + requirement4.put("requirement_name", "每色MOQ-2"); + requirement4.put("requirement_description", ""); + requirementInfo.add(requirement4); + + // 第五个需求 + Map requirement5 = new HashMap<>(); + List correlationCode5 = Arrays.asList("100203", "4-1"); + requirement5.put("correlation_code", correlationCode5); + requirement5.put("requirement_no", "100203"); + requirement5.put("requirement_name", "是否有文件,若有,需附上文件-2"); + requirement5.put("requirement_description", ""); + requirementInfo.add(requirement5); + + // 第六个需求 + Map requirement6 = new HashMap<>(); + List correlationCode6 = Arrays.asList("100204"); + requirement6.put("correlation_code", correlationCode6); + requirement6.put("requirement_no", "100204"); + requirement6.put("requirement_name", "是否有文件,若有,需附上文件-2"); + requirement6.put("requirement_description", ""); + requirementInfo.add(requirement6); + + // 第七个需求 + Map requirement7 = new HashMap<>(); + List correlationCode7 = Arrays.asList("100204", "5-1"); + requirement7.put("correlation_code", correlationCode7); + requirement7.put("requirement_no", "100204"); + requirement7.put("requirement_name", "需求名称"); + requirement7.put("requirement_description", ""); + requirementInfo.add(requirement7); + + return requirementInfo; + } +} diff --git a/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/quotation/QuotationUtil.java b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/quotation/QuotationUtil.java new file mode 100644 index 0000000..8cd2009 --- /dev/null +++ b/demo-athenaopt_backend/develop/src/main/java/com/digiwin/athena/app/service/quotation/QuotationUtil.java @@ -0,0 +1,15 @@ +package com.digiwin.athena.app.service.quotation; + +/** + * @author lz + * @version 1.0 + * @title QuotationUtil + * @description + * @create 2024/4/29 10:01 + */ +public class QuotationUtil { + + public static final String DEMO_ATHENAOPT_REQUIREMENT_INFO_GET= "demo.athenaopt.requirement.info.get"; + + +} diff --git a/demo-athenaopt_backend/pom.xml b/demo-athenaopt_backend/pom.xml index 7a61d32..d7421df 100644 --- a/demo-athenaopt_backend/pom.xml +++ b/demo-athenaopt_backend/pom.xml @@ -67,7 +67,7 @@ com.digiwin.lcdp lcdp-modeldriven - 1.0.1.17 + 1.0.1.40 diff --git a/version_control/BUILD b/version_control/BUILD index a6905f8..49efa1e 100644 --- a/version_control/BUILD +++ b/version_control/BUILD @@ -1 +1 @@ -999 +1020