Browse Source

Merge pull request '20240103发布' (#171) from test into main

Reviewed-on: http://39.105.23.186:3000/develop/digimeta-MultiSaas/pulls/171
tags/B.2.6.1_20240104_release
bogemail 1 year ago
parent
commit
bada89af6c
100 changed files with 3109 additions and 579 deletions
  1. +3
    -2
      xueyi-api/xueyi-api-file/src/main/java/com/xueyi/file/api/feign/RemoteFileService.java
  2. +2
    -1
      xueyi-api/xueyi-api-file/src/main/java/com/xueyi/file/api/feign/factory/RemoteFileFallbackFactory.java
  3. +22
    -0
      xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/domain/vo/response/DmKnowledgeResponse.java
  4. +22
    -0
      xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/domain/vo/response/DmKnowledgeResultResponse.java
  5. +3
    -1
      xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/feign/RemoteQAService.java
  6. +24
    -0
      xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/feign/RemoteSeniverseService.java
  7. +4
    -2
      xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/feign/factory/RemoteQAFallbackFactory.java
  8. +30
    -0
      xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/feign/factory/RemoteSeniverseFallbackFactory.java
  9. +1
    -0
      xueyi-api/xueyi-api-nlt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  10. +6
    -0
      xueyi-api/xueyi-api-system/pom.xml
  11. +3
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/authority/feign/RemoteLoginService.java
  12. +5
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/authority/feign/factory/RemoteLoginFallbackFactory.java
  13. +0
    -13
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/device/domain/vo/DeviceTenantSourceMergeVo.java
  14. +1
    -1
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/device/feign/RemoteDeviceTenantMergeService.java
  15. +2
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/po/DmManDevicePo.java
  16. +1
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/po/DmVisitRecordsPo.java
  17. +8
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/po/DmVisitorsPo.java
  18. +19
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/vo/DmTipVo.java
  19. +3
    -2
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/feign/RemoteDigitalmanService.java
  20. +7
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/feign/RemoteQuestionanswersService.java
  21. +16
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/interfaces/airport/domain/vo/PlaneMessageVo.java
  22. +18
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/interfaces/airport/feign/RemotePlaneController.java
  23. +24
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/interfaces/airport/feign/factory/RemotePlaneFallbackFactory.java
  24. +16
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/staff/domain/dto/DmVisitCommonDto.java
  25. +5
    -6
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/staff/domain/po/DmStaffPo.java
  26. +4
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/staff/feign/RemoteStaffService.java
  27. +2
    -0
      xueyi-api/xueyi-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  28. +19
    -0
      xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/domain/dto/SysEnterpriseStaffDto.java
  29. +30
    -0
      xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/domain/po/SysEnterpriseStaff.java
  30. +14
    -0
      xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/domain/po/TeTenantPo.java
  31. +21
    -0
      xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/domain/query/SysEnterpriseStaffQuery.java
  32. +13
    -0
      xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/feign/RemoteTenantService.java
  33. +18
    -0
      xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/feign/factory/RemoteTenantFallbackFactory.java
  34. +5
    -0
      xueyi-auth/pom.xml
  35. +91
    -0
      xueyi-auth/src/main/java/com/xueyi/auth/controller/TokenController.java
  36. +21
    -0
      xueyi-auth/src/main/java/com/xueyi/auth/form/PhoneLoginBody.java
  37. +17
    -0
      xueyi-auth/src/main/java/com/xueyi/auth/service/SysLoginService.java
  38. +1
    -0
      xueyi-auth/src/main/resources/bootstrap.yml
  39. +1
    -0
      xueyi-common/xueyi-common-apiauth/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  40. +2
    -1
      xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/constant/digitalman/SkillConstants.java
  41. +88
    -0
      xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/DecodeRequestUtils.java
  42. +42
    -0
      xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/core/CryptoUtil.java
  43. +28
    -0
      xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/core/NumberUtil.java
  44. +20
    -0
      xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/core/ObjectUtil.java
  45. +6
    -0
      xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/core/StrUtil.java
  46. +16
    -0
      xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/web/vo/DeviceTenantSourceMergeVo.java
  47. +7
    -1
      xueyi-common/xueyi-common-security/src/main/java/com/xueyi/common/security/service/BaseTokenService.java
  48. +1
    -4
      xueyi-common/xueyi-common-sms/src/main/java/com/xueyi/common/sms/service/SmsService.java
  49. +40
    -0
      xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/config/WebApiMvcConfig.java
  50. +39
    -1
      xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/controller/BaseApiController.java
  51. +45
    -0
      xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/entity/domain/BaseReq.java
  52. +21
    -0
      xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/entity/domain/mapper/DeviceTenantMergeMapper.java
  53. +14
    -0
      xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/entity/domain/provider/DeviceTenantSqlProvider.java
  54. +82
    -0
      xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/interceptor/ApiRequestInterceptor.java
  55. +355
    -330
      xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/utils/DateUtils.java
  56. +3
    -1
      xueyi-common/xueyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  57. +5
    -4
      xueyi-gateway/src/main/java/com/xueyi/gateway/filter/AuthFilter.java
  58. +6
    -0
      xueyi-modules/xueyi-file/pom.xml
  59. +54
    -0
      xueyi-modules/xueyi-file/src/main/java/com/xueyi/file/config/QiNiuConfig.java
  60. +4
    -3
      xueyi-modules/xueyi-file/src/main/java/com/xueyi/file/controller/SysFileController.java
  61. +22
    -6
      xueyi-modules/xueyi-file/src/main/java/com/xueyi/file/service/MinioSysFileServiceImpl.java
  62. +207
    -0
      xueyi-modules/xueyi-file/src/main/java/com/xueyi/file/service/QiNiuSysFileServiceImpl.java
  63. +5
    -1
      xueyi-modules/xueyi-job/src/main/java/com/xueyi/job/task/DmRecognizedRecordsCleanTask.java
  64. +5
    -0
      xueyi-modules/xueyi-message/pom.xml
  65. +1
    -1
      xueyi-modules/xueyi-message/src/main/java/com/xueyi/message/handler/MqttTopicHandle.java
  66. +46
    -13
      xueyi-modules/xueyi-message/src/main/java/com/xueyi/message/transfer/controller/ApiController.java
  67. +1
    -1
      xueyi-modules/xueyi-modules-auth/src/main/java/com/xueyi/modules/auth/controller/SkillAuthApiController.java
  68. +1
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/XueYiNltApplication.java
  69. +173
    -72
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/client/WebSocketClient.java
  70. +31
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/ServerInitializer.java
  71. +79
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/WebsocketServer.java
  72. +15
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/config/ServerConfig.java
  73. +204
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/handler/ChatServerHandler.java
  74. +32
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/handler/HeartbeatHandler.java
  75. +124
    -38
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/controller/DmIntentController.java
  76. +1
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/domain/LlmContext.java
  77. +1
    -1
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/kafka/KafkaMessageConsumer.java
  78. +1
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/service/ISysLlmService.java
  79. +8
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/service/impl/SparkServiceImpl.java
  80. +166
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/template/FlightMessageTemplate.java
  81. +85
    -28
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/template/FreeChatTemplate.java
  82. +34
    -14
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/template/MeetingOrderTemplate.java
  83. +26
    -0
      xueyi-modules/xueyi-system/pom.xml
  84. +73
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/authority/controller/SysLoginController.java
  85. +2
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/authority/service/ISysLoginService.java
  86. +32
    -1
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/authority/service/impl/SysLoginServiceImpl.java
  87. +4
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/common/service/IDmHolidayService.java
  88. +8
    -1
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/common/service/impl/IDmHolidayServiceImpl.java
  89. +10
    -2
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/device/controller/DmDeviceTenantMergeController.java
  90. +31
    -1
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/controller/DmDigitalmanController.java
  91. +0
    -9
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/controller/DmManDeviceController.java
  92. +11
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/controller/DmQuestionsController.java
  93. +6
    -2
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/controller/api/DmMenuApiController.java
  94. +15
    -15
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/manager/impl/DmModelManager.java
  95. +4
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/service/IDmQuestionsService.java
  96. +32
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/service/impl/DmQuestionsServiceImpl.java
  97. +42
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/interfaces/airport/bean/FlightsQueryReq.java
  98. +33
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/interfaces/airport/bean/PlaneQueryReq.java
  99. +127
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/interfaces/airport/controller/PlaneController.java
  100. +31
    -0
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/interfaces/airport/controller/VideoTalkController.java

+ 3
- 2
xueyi-api/xueyi-api-file/src/main/java/com/xueyi/file/api/feign/RemoteFileService.java View File

@@ -62,6 +62,7 @@ public interface RemoteFileService {
R<Boolean> delete(@RequestParam (value = "url") String url);


@DeleteMapping(value = "/inner/delete-files")
R<Boolean> deleteFiles(@RequestParam (value = "urls") List<String> urls);
@PostMapping(value = "/inner/delete-files")
@Async
R<Boolean> deleteFiles(@RequestParam("urls") String[] urls);
}

+ 2
- 1
xueyi-api/xueyi-api-file/src/main/java/com/xueyi/file/api/feign/factory/RemoteFileFallbackFactory.java View File

@@ -6,6 +6,7 @@ import com.xueyi.file.api.feign.RemoteFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
@@ -54,7 +55,7 @@ public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileServ
}

@Override
public R<Boolean> deleteFiles(List<String> urls) {
public R<Boolean> deleteFiles(@RequestParam("urls") String[] urls) {
return R.fail("删除文件失败:" + throwable.getMessage() );
}
};


+ 22
- 0
xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/domain/vo/response/DmKnowledgeResponse.java View File

@@ -0,0 +1,22 @@
package com.xueyi.nlt.api.nlt.domain.vo.response;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serial;
import java.io.Serializable;
import java.util.List;

@Data
@NoArgsConstructor
public class DmKnowledgeResponse implements Serializable {

@Serial
private static final long serialVersionUID = 1L;

private Integer accurate;
private String llm;
private String question;
private List<DmKnowledgeResultResponse> result;
private Integer target;
}

+ 22
- 0
xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/domain/vo/response/DmKnowledgeResultResponse.java View File

@@ -0,0 +1,22 @@
package com.xueyi.nlt.api.nlt.domain.vo.response;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serial;
import java.io.Serializable;

@Data
@NoArgsConstructor
public class DmKnowledgeResultResponse implements Serializable {

@Serial
private static final long serialVersionUID = 1L;

private String answer;
private Integer highlight;
private String id;
private String knowledgeLib;
private Integer modelType;
private String name;
}

+ 3
- 1
xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/feign/RemoteQAService.java View File

@@ -2,7 +2,9 @@ package com.xueyi.nlt.api.nlt.feign;

import com.alibaba.fastjson.JSONObject;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.nlt.api.nlt.domain.vo.KnowledgeVo;
import com.xueyi.nlt.api.nlt.domain.vo.response.DmKnowledgeResponse;
import com.xueyi.nlt.api.nlt.feign.factory.RemoteQAFallbackFactory;
import com.xueyi.system.api.sms.domain.vo.SmsReqEntity;
import com.xueyi.system.api.sms.feign.factory.RemoteSmsFallbackFactory;
@@ -25,6 +27,6 @@ public interface RemoteQAService {
@GetMapping("/knowledge")
AjaxResult query(@RequestParam(value = "man_code") String manCode, @RequestParam(value = "question") String question, @RequestParam(value = "tenant_id") Long tenantId);
@PostMapping ("/knowledge")
AjaxResult query(@RequestBody KnowledgeVo vo);
R<DmKnowledgeResponse> query(@RequestBody KnowledgeVo vo);

}

+ 24
- 0
xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/feign/RemoteSeniverseService.java View File

@@ -0,0 +1,24 @@
package com.xueyi.nlt.api.nlt.feign;


import com.alibaba.fastjson2.JSONObject;
import com.xueyi.nlt.api.nlt.domain.vo.WenxinErnieBotResponse;
import com.xueyi.nlt.api.nlt.feign.factory.RemoteLandingLlmFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(url = "${notification.seniverse.url}",name = "seniverse", fallbackFactory = RemoteLandingLlmFallbackFactory.class)
public interface RemoteSeniverseService {

@GetMapping("/v3/weather/now.json")
JSONObject now(@RequestParam("key") String key,
@RequestParam("location") String location,
@RequestParam("language") String language,
@RequestParam("unit") String unit);



}

+ 4
- 2
xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/feign/factory/RemoteQAFallbackFactory.java View File

@@ -1,7 +1,9 @@
package com.xueyi.nlt.api.nlt.feign.factory;

import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.nlt.api.nlt.domain.vo.KnowledgeVo;
import com.xueyi.nlt.api.nlt.domain.vo.response.DmKnowledgeResponse;
import com.xueyi.nlt.api.nlt.feign.RemoteQAService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -26,8 +28,8 @@ public class RemoteQAFallbackFactory implements FallbackFactory<RemoteQAService>
}

@Override
public AjaxResult query(KnowledgeVo vo) {
return AjaxResult.error("查询失败");
public R<DmKnowledgeResponse> query(KnowledgeVo vo) {
return R.fail("知识库查询失败");
}
};
}

+ 30
- 0
xueyi-api/xueyi-api-nlt/src/main/java/com/xueyi/nlt/api/nlt/feign/factory/RemoteSeniverseFallbackFactory.java View File

@@ -0,0 +1,30 @@
package com.xueyi.nlt.api.nlt.feign.factory;

import com.alibaba.fastjson2.JSONObject;
import com.xueyi.nlt.api.nlt.domain.vo.DmLandingLlmVo;
import com.xueyi.nlt.api.nlt.feign.RemoteLandingLlmService;
import com.xueyi.nlt.api.nlt.feign.RemoteSeniverseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

/**
* 会议室服务 降级处理
*
* @author xueyi
*/
@Slf4j
@Component
public class RemoteSeniverseFallbackFactory implements FallbackFactory<RemoteSeniverseService> {

@Override
public RemoteSeniverseService create(Throwable throwable) {
log.error("短信服务调用失败:{}", throwable.getMessage());
return new RemoteSeniverseService() {
@Override
public JSONObject now(String key, String location, String language, String unit) {
return null;
}
};
}
}

+ 1
- 0
xueyi-api/xueyi-api-nlt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports View File

@@ -1,3 +1,4 @@
com.xueyi.nlt.api.nlt.feign.factory.RemoteIntentFallbackFactory
com.xueyi.nlt.api.nlt.feign.factory.RemoteQAFallbackFactory
com.xueyi.nlt.api.nlt.feign.factory.RemoteLandingLlmFallbackFactory
com.xueyi.nlt.api.nlt.feign.factory.RemoteSeniverseFallbackFactory

+ 6
- 0
xueyi-api/xueyi-api-system/pom.xml View File

@@ -39,6 +39,12 @@
<artifactId>xueyi-api-tenant</artifactId>
</dependency>

<dependency>
<groupId>io.github.graphql-java</groupId>
<artifactId>graphql-java-annotations</artifactId>
<version>21.1</version>
</dependency>

</dependencies>

</project>

+ 3
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/authority/feign/RemoteLoginService.java View File

@@ -30,4 +30,7 @@ public interface RemoteLoginService {
@GetMapping("/login/inner/loginInfo/{enterpriseName}/{userName}/{password}")
R<LoginUser> getLoginInfoInner(@PathVariable("enterpriseName") String enterpriseName, @PathVariable("userName") String userName, @PathVariable("password") String password, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

@GetMapping("/login/inner/loginByPhone/{phone}")
R<LoginUser> getLoginInfoInnerByPhone(@PathVariable("phone") String phone, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

}

+ 5
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/authority/feign/factory/RemoteLoginFallbackFactory.java View File

@@ -24,6 +24,11 @@ public class RemoteLoginFallbackFactory implements FallbackFactory<RemoteLoginSe
public R<LoginUser> getLoginInfoInner(String enterpriseName, String userName, String password, String source) {
return R.fail("获取登录信息失败:" + throwable.getMessage());
}

@Override
public R<LoginUser> getLoginInfoInnerByPhone(String phone, String source) {
return R.fail("获取登录信息失败:" + throwable.getMessage());
}
};
}
}

+ 0
- 13
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/device/domain/vo/DeviceTenantSourceMergeVo.java View File

@@ -1,13 +0,0 @@
package com.xueyi.system.api.device.domain.vo;


import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class DeviceTenantSourceMergeVo {

Long tenantId;
String sourceSlave;
}

+ 1
- 1
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/device/feign/RemoteDeviceTenantMergeService.java View File

@@ -2,8 +2,8 @@ package com.xueyi.system.api.device.feign;

import com.xueyi.common.core.constant.basic.ServiceConstants;
import com.xueyi.common.core.web.result.R;
import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.system.api.device.domain.po.DmDeviceTenantMergePo;
import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo;
import com.xueyi.system.api.organize.feign.factory.RemoteUserFallbackFactory;
import com.xueyi.tenant.api.source.domain.po.TeSourcePo;
import org.springframework.cloud.openfeign.FeignClient;


+ 2
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/po/DmManDevicePo.java View File

@@ -67,4 +67,6 @@ public class DmManDevicePo extends BaseEntity {
/* 推流地址 */
@Excel(name = "推流地址")
protected String streamUrl;

protected String configCreated;
}

+ 1
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/po/DmVisitRecordsPo.java View File

@@ -77,6 +77,7 @@ public class DmVisitRecordsPo extends TBaseEntity {




public String toString(){
return new StringBuilder("VisitorId: ").append(visitorId).append(", UserId: ").append(userId).append(", VisitDate: ").append(visitDate).append(", VisitTime: ").append(visitTime).append(", Duration: ").append(duration).append(", RecordStatus: ").append(recordStatus).append(", DeptId: ").append(deptId).append(", Num: ").append(num).toString();
}

+ 8
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/po/DmVisitorsPo.java View File

@@ -3,6 +3,7 @@ package com.xueyi.system.api.digitalmans.domain.po;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xueyi.common.core.annotation.Excel;
import com.xueyi.common.core.web.tenant.base.TBaseEntity;
import graphql.annotations.annotationTypes.GraphQLField;
import lombok.Data;
import lombok.EqualsAndHashCode;

@@ -30,10 +31,12 @@ public class DmVisitorsPo extends TBaseEntity {
protected Long roomId;

/** 访客电话 */
@GraphQLField
@Excel(name = "访客电话")
protected String phone;

/** 1:男;2:女 */
@GraphQLField
@Excel(name = "1:男;2:女")
protected Integer gender;

@@ -42,10 +45,12 @@ public class DmVisitorsPo extends TBaseEntity {
protected Integer age;

/** 访客公司 */
@GraphQLField
@Excel(name = "访客公司")
protected String visitorCompany;

/** 访客称呼 */
@GraphQLField
@Excel(name = "访客称呼")
protected String nickname;

@@ -54,13 +59,16 @@ public class DmVisitorsPo extends TBaseEntity {
protected Long deptId;

/** 访客类型 */
@GraphQLField
@Excel(name = "访客类型")
protected Long type;

/** 上传头像 */
@GraphQLField
@Excel(name = "上传头像")
protected String avatar;

@GraphQLField
protected Long resourceId;



+ 19
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/vo/DmTipVo.java View File

@@ -0,0 +1,19 @@
package com.xueyi.system.api.digitalmans.domain.vo;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serial;

@Data
@NoArgsConstructor
public class DmTipVo {
@Serial
private static final long serialVersionUID = 1L;
private Long id;

private String name;

//类型 0-播报知识库 1-大模型
private Integer type;
}

+ 3
- 2
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/feign/RemoteDigitalmanService.java View File

@@ -3,6 +3,7 @@ package com.xueyi.system.api.digitalmans.feign;
import com.alibaba.fastjson2.JSONObject;
import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.constant.basic.ServiceConstants;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.system.api.digitalmans.domain.dto.DmManDeviceDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmSyncDigitalmanDto;
@@ -53,7 +54,7 @@ public interface RemoteDigitalmanService {
@GetMapping("/man/api/mansInfo")
public R<JSONObject> mansInfo();

@GetMapping("/man/delRecognizedRecords")
public R<JSONObject> delRecognizedRecords(@RequestParam(value = "day") Integer days);
@GetMapping("/man/api/delRecognizedRecords")
public AjaxResult delRecognizedRecords(@RequestParam(value = "day") Integer days);

}

+ 7
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/feign/RemoteQuestionanswersService.java View File

@@ -6,10 +6,13 @@ import com.xueyi.common.core.constant.basic.ServiceConstants;
import com.xueyi.common.core.web.result.R;
import com.xueyi.system.api.digitalmans.domain.vo.DmBatchQuestionsVo;
import com.xueyi.system.api.digitalmans.domain.vo.DmReceptionVo;
import com.xueyi.system.api.digitalmans.domain.vo.DmTipVo;
import com.xueyi.system.api.organize.feign.factory.RemoteUserFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@FeignClient(contextId = "remoteQuestionanswersService", value = ServiceConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteQuestionanswersService {

@@ -19,4 +22,8 @@ public interface RemoteQuestionanswersService {
public R<DmReceptionVo> batchInsertInner(@RequestBody DmBatchQuestionsVo dmBatchQuestionsVo,
@RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

@GetMapping("/questions/inner/tipList")
@ResponseBody
R<List<DmTipVo>> tipList(@RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

}

+ 16
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/interfaces/airport/domain/vo/PlaneMessageVo.java View File

@@ -0,0 +1,16 @@
package com.xueyi.system.api.interfaces.airport.domain.vo;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serial;

@Data
@NoArgsConstructor
public class PlaneMessageVo {
@Serial
private static final long serialVersionUID = 1L;

private String fNum;
private String date;
}

+ 18
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/interfaces/airport/feign/RemotePlaneController.java View File

@@ -0,0 +1,18 @@
package com.xueyi.system.api.interfaces.airport.feign;

import com.alibaba.fastjson2.JSONObject;
import com.xueyi.common.core.constant.basic.ServiceConstants;
import com.xueyi.system.api.interfaces.airport.domain.vo.PlaneMessageVo;
import com.xueyi.system.api.interfaces.airport.feign.factory.RemotePlaneFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;

@FeignClient(contextId = "remotePlaneController", value = ServiceConstants.SYSTEM_SERVICE, fallbackFactory = RemotePlaneFallbackFactory.class)
public interface RemotePlaneController {

@PostMapping("/plane/api/query-flight")
public JSONObject queryFlight(@RequestBody(required = true)PlaneMessageVo planeMessageVo,
@RequestHeader("ts") String timestamp, @RequestHeader("sign") String sign);
}

+ 24
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/interfaces/airport/feign/factory/RemotePlaneFallbackFactory.java View File

@@ -0,0 +1,24 @@
package com.xueyi.system.api.interfaces.airport.feign.factory;

import com.alibaba.fastjson2.JSONObject;
import com.xueyi.common.core.web.result.R;
import com.xueyi.system.api.interfaces.airport.domain.vo.PlaneMessageVo;
import com.xueyi.system.api.interfaces.airport.feign.RemotePlaneController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class RemotePlaneFallbackFactory implements FallbackFactory<RemotePlaneController> {
@Override
public RemotePlaneController create(Throwable throwable) {
log.error("航信服务调用失败:{}", throwable.getMessage());
return new RemotePlaneController() {
@Override
public JSONObject queryFlight(PlaneMessageVo planeMessageVo,String timeStamp, String sign){
return R.fail("航班信息服务调用失败:" + throwable.getMessage()).toJson();
}
};
}
}

+ 16
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/staff/domain/dto/DmVisitCommonDto.java View File

@@ -1,5 +1,6 @@
package com.xueyi.system.api.staff.domain.dto;

import com.alibaba.fastjson2.JSONObject;
import lombok.Data;

/**
@@ -35,6 +36,21 @@ public class DmVisitCommonDto {
private String visitorBase64Img;


public String toSmsJson(String code, String name, String companyName, String companyAddress, String parkInfo){
JSONObject json = new JSONObject();
json.put("code", code);
json.put("nickName", this.getVisitorName());
json.put("robotName", name);
json.put("dateTime", this.getVisitDate());
json.put("companyName", companyName);
json.put("companyAddr", companyAddress);
json.put("receiverName", this.getEmpName());
json.put("receiverPhone", this.getEmpTel());
json.put("parkInfo", parkInfo);
return json.toJSONString();
}


@Override
public String toString() {
return "DmVisitCommonDto{" +


+ 5
- 6
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/staff/domain/po/DmStaffPo.java View File

@@ -1,16 +1,13 @@
package com.xueyi.system.api.staff.domain.po;

import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xueyi.common.core.web.tenant.base.TBaseEntity;
import com.xueyi.common.core.annotation.Excel;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xueyi.common.core.annotation.Excel;
import com.xueyi.common.core.web.tenant.base.TBaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serial;

import static com.xueyi.common.core.constant.basic.EntityConstants.NAME;
import java.util.Date;

/**
* 人员 持久化对象
@@ -95,4 +92,6 @@ public class DmStaffPo extends TBaseEntity {
@Excel(name = "入职日期")
protected Date hireDate;


private Long tenantId;
}

+ 4
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/staff/feign/RemoteStaffService.java View File

@@ -53,4 +53,8 @@ public interface RemoteStaffService {

@GetMapping("/staff/api/inner-recognized-records")
R<List<DmRecognizedRecordsPo>> _recognizedRecords(@RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

@GetMapping("/staff/api/inner-del-recognized-records-img")
@ResponseBody
R delRecognizedRecordsImg(@RequestParam("day") Integer day, @RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

+ 2
- 0
xueyi-api/xueyi-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports View File

@@ -9,3 +9,5 @@ com.xueyi.system.api.dict.feign.factory.RemoteConfigFallbackFactory
com.xueyi.system.api.log.feign.factory.RemoteLogFallbackFactory
com.xueyi.system.api.meeting.feign.factory.RemoteMeetingFallbackFactory
com.xueyi.system.api.resource.feign.factory.RemoteH5ConfigFallbackFactory
com.xueyi.system.api.interfaces.airport.feign.factory.RemotePlaneFallbackFactory
com.xueyi.system.api.sms.feign.factory.RemoteSmsFallbackFactory

+ 19
- 0
xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/domain/dto/SysEnterpriseStaffDto.java View File

@@ -0,0 +1,19 @@
package com.xueyi.tenant.api.tenant.domain.dto;

import com.xueyi.tenant.api.tenant.domain.po.SysEnterpriseStaff;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
* 租户 数据传输对象
*
* @author xueyi
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class SysEnterpriseStaffDto extends SysEnterpriseStaff {
private static final long serialVersionUID = 1L;
private String oldPhone;


}

+ 30
- 0
xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/domain/po/SysEnterpriseStaff.java View File

@@ -0,0 +1,30 @@
package com.xueyi.tenant.api.tenant.domain.po;

import com.baomidou.mybatisplus.annotation.TableName;
import com.xueyi.common.core.web.tenant.base.TBaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serial;

/**
* 人员 持久化对象
*
* @author xueyi
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName(value = "dm_enterprise_staff")
public class SysEnterpriseStaff extends TBaseEntity {

@Serial
private static final long serialVersionUID = 1L;

protected Long staffId;

protected String phone;

private Long tenantId;

private String openid;
}

+ 14
- 0
xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/domain/po/TeTenantPo.java View File

@@ -63,4 +63,18 @@ public class TeTenantPo extends BaseEntity {
@TableField(updateStrategy = FieldStrategy.NEVER)
protected String isDefault;

@Override
public String toString(){
return "TeTenantPo{" +
"strategyId=" + strategyId +
", name='" + name + '\'' +
", systemName='" + systemName + '\'' +
", nick='" + nick + '\'' +
", logo='" + logo + '\'' +
", nameFrequency=" + nameFrequency +
", isLessor='" + isLessor + '\'' +
", isDefault='" + isDefault + '\'' +
'}';
}

}

+ 21
- 0
xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/domain/query/SysEnterpriseStaffQuery.java View File

@@ -0,0 +1,21 @@
package com.xueyi.tenant.api.tenant.domain.query;

import com.xueyi.tenant.api.tenant.domain.po.SysEnterpriseStaff;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serial;

/**
* 租户 数据查询对象
*
* @author xueyi
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class SysEnterpriseStaffQuery extends SysEnterpriseStaff {

@Serial
private static final long serialVersionUID = 1L;

}

+ 13
- 0
xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/feign/RemoteTenantService.java View File

@@ -5,6 +5,7 @@ import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.constant.basic.ServiceConstants;
import com.xueyi.common.core.web.result.R;
import com.xueyi.tenant.api.tenant.domain.dto.TeTenantDto;
import com.xueyi.tenant.api.tenant.domain.po.SysEnterpriseStaff;
import com.xueyi.tenant.api.tenant.domain.po.TeTenantPo;
import com.xueyi.tenant.api.tenant.feign.factory.RemoteTenantFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
@@ -12,6 +13,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@@ -36,4 +38,15 @@ public interface RemoteTenantService {
@GetMapping("/tenant/tenant_list")
R<List<TeTenantDto>> tenantList();

@GetMapping("/tenant/one")
R<TeTenantPo> tenant(@RequestParam ("phone") String phone, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);


@GetMapping("/tenant/staff")
R<SysEnterpriseStaff> existStaff(@RequestParam ("phone") String phone, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);


@PostMapping("/tenant/staff")
R<SysEnterpriseStaff> saveEnterpriseStaff(@RequestBody SysEnterpriseStaff staff, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

}

+ 18
- 0
xueyi-api/xueyi-api-tenant/src/main/java/com/xueyi/tenant/api/tenant/feign/factory/RemoteTenantFallbackFactory.java View File

@@ -3,6 +3,8 @@ package com.xueyi.tenant.api.tenant.feign.factory;
import com.alibaba.fastjson2.JSONObject;
import com.xueyi.common.core.web.result.R;
import com.xueyi.tenant.api.tenant.domain.dto.TeTenantDto;
import com.xueyi.tenant.api.tenant.domain.po.SysEnterpriseStaff;
import com.xueyi.tenant.api.tenant.domain.po.TeTenantPo;
import com.xueyi.tenant.api.tenant.feign.RemoteTenantService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -34,6 +36,22 @@ public class RemoteTenantFallbackFactory implements FallbackFactory<RemoteTenant
public R<List<TeTenantDto>> tenantList() {
return null;
}


@Override
public R<TeTenantPo> tenant(String phone, String source) {
return R.fail("获取租户失败:" + throwable.getMessage());
}

@Override
public R<SysEnterpriseStaff> existStaff(String phone, String source) {
return R.fail("验证用户手机号失败:" + throwable.getMessage());
}

@Override
public R<SysEnterpriseStaff> saveEnterpriseStaff(SysEnterpriseStaff staff, String source) {
return null;
}
};
}
}

+ 5
- 0
xueyi-auth/pom.xml View File

@@ -51,6 +51,11 @@
<groupId>com.xueyi</groupId>
<artifactId>xueyi-common-security</artifactId>
</dependency>

<dependency>
<groupId>com.xueyi</groupId>
<artifactId>xueyi-common-sms</artifactId>
</dependency>
</dependencies>


+ 91
- 0
xueyi-auth/src/main/java/com/xueyi/auth/controller/TokenController.java View File

@@ -1,24 +1,41 @@
package com.xueyi.auth.controller;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xueyi.auth.form.LoginBody;
import com.xueyi.auth.form.PhoneLoginBody;
import com.xueyi.auth.form.RegisterBody;
import com.xueyi.auth.service.SysLoginService;
import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.constant.basic.TenantConstants;
import com.xueyi.common.core.utils.JwtUtil;
import com.xueyi.common.core.utils.core.ObjectUtil;
import com.xueyi.common.core.utils.core.StrUtil;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.common.redis.service.RedisService;
import com.xueyi.common.security.auth.AuthUtil;
import com.xueyi.common.security.service.TokenService;
import com.xueyi.common.security.utils.SecurityUtils;
import com.xueyi.common.sms.configure.SmsProperties;
import com.xueyi.system.api.model.LoginUser;
import com.xueyi.system.api.sms.domain.vo.SmsReqEntity;
import com.xueyi.system.api.sms.feign.RemoteSmsService;
import com.xueyi.tenant.api.tenant.domain.po.SysEnterpriseStaff;
import com.xueyi.tenant.api.tenant.feign.RemoteTenantService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

/**
* token 控制
@@ -28,12 +45,36 @@ import javax.servlet.http.HttpServletRequest;
@RestController
public class TokenController {

private final Logger log = org.slf4j.LoggerFactory.getLogger(this.getClass());

@Autowired
private TokenService tokenService;

@Autowired
private SysLoginService sysLoginService;


@Autowired
private RemoteSmsService smsService;

@Autowired
private RemoteSmsService remoteSmsService;

@Autowired
private SmsProperties smsProperties;

@Autowired
private RedisService redisService;

@Autowired
private RemoteTenantService tenantService;

@Autowired
private RedisTemplate<String, String> redisTemplate;


private final String REDIS_LOGIN_CODE_PIX = "saas:login:code:";

@PostMapping("login")
public AjaxResult login(@RequestBody LoginBody form) {
// 用户登录
@@ -42,6 +83,25 @@ public class TokenController {
return AjaxResult.success(tokenService.createToken(userInfo));
}

@PostMapping("phoneLogin")
public AjaxResult loginByPhone(@Valid @RequestBody PhoneLoginBody form) {
/*if (!RedisUtil.existed(REDIS_LOGIN_CODE_PIX + form.getPhone())) {
return AjaxResult.error("手机号输入错误或验证码已过期");
} else {
Integer code = (Integer) RedisUtil.getVal(REDIS_LOGIN_CODE_PIX + form.getPhone());
if (null != code && !form.getCode().equals(code.toString())) {
return AjaxResult.error("验证码输入不正确");
}
}*/
// 用户手机号验证登录
LoginUser userInfo = sysLoginService.loginByPhone(form.getPhone());
if (null == userInfo) {
return AjaxResult.error("手机号不正确,清查验");
}
// 获取登录token
return AjaxResult.success(tokenService.createToken(userInfo));
}

@DeleteMapping("logout")
public AjaxResult logout(HttpServletRequest request) {
String token = SecurityUtils.getToken(request);
@@ -76,4 +136,35 @@ public class TokenController {
sysLoginService.register(registerBody);
return AjaxResult.success();
}


@GetMapping("validCode")
public R validCode(@RequestParam String phone) {
R<SysEnterpriseStaff> staff = tenantService.existStaff(phone, SecurityConstants.INNER);
if (staff.getData() == null) {
return R.fail("手机号不存在,请查验");
}
SmsReqEntity smsReqEntity = new SmsReqEntity();
smsReqEntity.setPhone(phone);
String str = StrUtil.generateCode();

if (StringUtils.isEmpty(phone)){
return R.fail("手机号为空");
} else {
if (redisService.hasKey(REDIS_LOGIN_CODE_PIX + phone)) {
return R.fail("之前请求的验证码并未失效,请查看短信或稍后重试");
} else {
redisTemplate.opsForValue().setIfAbsent(REDIS_LOGIN_CODE_PIX + phone, str, 5, TimeUnit.MINUTES);
}
smsReqEntity.setTemplate(smsProperties.getCodeTemplate());
JSONObject map = new JSONObject();
map.put("code", str);
smsReqEntity.setDataMap(map.toJSONString());
log.info("发送验证码成功,手机号:{},验证码:{}, sendReq:{}", phone, str, smsReqEntity.toJson().toJSONString());
remoteSmsService.sendSms(smsReqEntity);
}
return R.ok("验证码发送成功,请查看短信");
}


}

+ 21
- 0
xueyi-auth/src/main/java/com/xueyi/auth/form/PhoneLoginBody.java View File

@@ -0,0 +1,21 @@
package com.xueyi.auth.form;

import lombok.Data;

import javax.validation.constraints.NotEmpty;

/**
* 用户登录对象
*
* @author xueyi
*/
@Data
public class PhoneLoginBody {

@NotEmpty(message = "手机号不能为空")
private String phone;

private String code;


}

+ 17
- 0
xueyi-auth/src/main/java/com/xueyi/auth/service/SysLoginService.java View File

@@ -18,6 +18,8 @@ import com.xueyi.system.api.log.feign.RemoteLogService;
import com.xueyi.system.api.model.LoginUser;
import com.xueyi.system.api.organize.domain.dto.SysUserDto;
import com.xueyi.tenant.api.tenant.feign.RemoteTenantService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@@ -29,6 +31,8 @@ import org.springframework.stereotype.Component;
@Component
public class SysLoginService {

private final Logger logger = LoggerFactory.getLogger(SysLoginService.class);

@Autowired
private RemoteLogService remoteLogService;

@@ -165,4 +169,17 @@ public class SysLoginService {
}
remoteLogService.saveLoginInfo(loginInfo, enterpriseId, sourceName, SecurityConstants.INNER);
}

public LoginUser loginByPhone(String phone) {
logger.info("phone:{}", phone);
R<LoginUser> loginInfoResult = remoteLoginService.getLoginInfoInnerByPhone(phone, SecurityConstants.INNER);


if (ObjectUtil.isNull(loginInfoResult.getData())) {
AjaxResult.warn("手机号可能输错,请查证后重试!");
}
return loginInfoResult.getData();
}


}

+ 1
- 0
xueyi-auth/src/main/resources/bootstrap.yml View File

@@ -27,3 +27,4 @@ spring:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
- application-secret-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
- application-datasource-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
- ali-sms.yml

+ 1
- 0
xueyi-common/xueyi-common-apiauth/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports View File

@@ -0,0 +1 @@
com.xueyi.common.web.entity.domain.mapper.DeviceTenantMergeMapper

+ 2
- 1
xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/constant/digitalman/SkillConstants.java View File

@@ -21,7 +21,8 @@ public class SkillConstants {
INTRODUCE_STRANGER("24", "熟人介绍生人"),
BROADCAST_DISPLAY("25", "播报展示"),
OPEN_DOOR("26", "开门"),
DELIVERY("33", "寄快递");
DELIVERY("33", "寄快递"),
FLIGHT("34", "航班信息");

private final String code;
private final String info;


+ 88
- 0
xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/DecodeRequestUtils.java View File

@@ -0,0 +1,88 @@
package com.xueyi.common.core.utils;

import com.alibaba.fastjson.JSONObject;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class DecodeRequestUtils {

/**
* 获取Request中的JSON字符串
*
* @param request
* @return
* @throws IOException
*/
public static String getRequestPostStr(HttpServletRequest request) throws IOException {
byte[] buffer = getRequestPostBytes(request);
if (buffer == null) {
return "";
}
String charEncoding = request.getCharacterEncoding();
if (charEncoding == null) {
charEncoding = "UTF-8";
}
return new String(buffer, charEncoding);
}

private static byte[] getRequestPostBytes(HttpServletRequest request) throws IOException {
int contentLength = request.getContentLength();
if (contentLength < 0) {
return null;
}
byte[] buffer = new byte[contentLength];
for (int i = 0; i < contentLength; ) {
int readlen = request.getInputStream().read(buffer, i,
contentLength - i);
if (readlen == -1) {
break;
}
i += readlen;
}
return buffer;
}

/**
* JSON对象转为网址传参格式(按key的首字母从小到大排序)
*
* @param jsonObject
* @return
*/
public static String json2pathValue(JSONObject jsonObject) {
Map map = jsonObject.toJavaObject(Map.class);
Set<String> set = map.keySet();
List<String> keyList = new ArrayList<>(set);
List<String> collect = keyList.stream().sorted().collect(Collectors.toList());
StringBuilder stringBuilder = new StringBuilder();
for (String s : collect) {
String value = map.get(s).toString();
stringBuilder.append(s).append("=").append(value).append("&");
}
stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("&"));
return stringBuilder.toString();
}

/**
* 计算sign签名
*
* @param jsonObject
* @param genKey
* @return
*/
public static String calculateSign(JSONObject jsonObject, String genKey) {
String pathvalue = json2pathValue(jsonObject);
System.out.println(pathvalue);
pathvalue = pathvalue + "&gen_key=" + genKey;
System.out.println(pathvalue);
String sign = DigestUtils.md5DigestAsHex(pathvalue.getBytes(StandardCharsets.UTF_8));
return sign;
}
}

+ 42
- 0
xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/core/CryptoUtil.java View File

@@ -0,0 +1,42 @@
package com.xueyi.common.core.utils.core;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Base64;

/**
* @author yk
* @description
* @date 2024-01-03 18:48
*/
public class CryptoUtil {
public static final String DEFAULT_KEY = "7uw823wuyeuwiyeehbsuuwgwvsyyeuii";

public static String encrypt(String data) throws Exception{
Key k = new SecretKeySpec(DEFAULT_KEY.getBytes(), "AES");

// 创建 Cipher 对象
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

// 初始化 Cipher 对象
cipher.init(Cipher.ENCRYPT_MODE, k);

// 加密数据
byte[] ciphertext = cipher.doFinal(data.getBytes());

// 输出密文
return Base64.getEncoder().encodeToString(ciphertext);
}


public static String decrypt(String encryptedData) throws Exception {
byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData);
Key k = new SecretKeySpec(DEFAULT_KEY.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, k);
byte[] decryptedBytes = cipher.doFinal(encryptedDataBytes);
//base64加密
return new String(decryptedBytes);
}
}

+ 28
- 0
xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/core/NumberUtil.java View File

@@ -20,4 +20,32 @@ public class NumberUtil extends cn.hutool.core.util.NumberUtil implements Number
return number == null ? 0 : number;
}


/**
* @Author yangkai
* @Description 将int类型的数据转化成X小时Y分钟的形式
* @Date 2023/9/21
* @Param
* @return
**/
public static String convertMinutesToHoursMinutes(int minutes) {
if (minutes < 0) {
throw new IllegalArgumentException("分钟数不能为负数");
}

int hours = minutes / 60;
int remainingMinutes = minutes % 60;
String hourMin = String.format("%d小时%d分钟", hours, remainingMinutes);
//如果小时数为0,则不显示"小时"
if (hours == 0) {
hourMin = String.format("%d分钟", remainingMinutes);
}
//如果分钟数为0,则不显示"分钟"
if (remainingMinutes == 0) {
hourMin = String.format("%d小时", hours);
}

return hourMin;
}

}

+ 20
- 0
xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/core/ObjectUtil.java View File

@@ -1,9 +1,29 @@
package com.xueyi.common.core.utils.core;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;

/**
* 对象工具类
*
* @author xueyi
*/
public class ObjectUtil extends cn.hutool.core.util.ObjectUtil {

public static Set<String> findAnnotatedFields(Class<?> clazz, Class<? extends Annotation> annotationClass) {
Set<String> annotatedFields = new HashSet<String>();

for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(annotationClass)) {
annotatedFields.add(field.getName());
}
}

return annotatedFields;
}



}

+ 6
- 0
xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/utils/core/StrUtil.java View File

@@ -190,4 +190,10 @@ public class StrUtil extends cn.hutool.core.util.StrUtil implements StrPool {
return result.toString();
}

public static String generateCode() {
String timeStr = String.valueOf(System.currentTimeMillis());
return timeStr.substring(timeStr.length() - 4 );
}


}

+ 16
- 0
xueyi-common/xueyi-common-core/src/main/java/com/xueyi/common/core/web/vo/DeviceTenantSourceMergeVo.java View File

@@ -0,0 +1,16 @@
package com.xueyi.common.core.web.vo;


import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
public class DeviceTenantSourceMergeVo implements Serializable {

Long tenantId;
String sourceSlave;
String devId;
}

+ 7
- 1
xueyi-common/xueyi-common-security/src/main/java/com/xueyi/common/security/service/BaseTokenService.java View File

@@ -106,6 +106,7 @@ public class BaseTokenService<User, LoginUser extends BaseLoginUser<User>> {
Map<String, Object> rspMap = new HashMap<>();
rspMap.put("access_token", JwtUtil.createToken(claimsMap));
rspMap.put("expires_in", getTacitExpireTime());
rspMap.put("tenant_id", enterpriseId);
return rspMap;
}

@@ -141,6 +142,7 @@ public class BaseTokenService<User, LoginUser extends BaseLoginUser<User>> {
return redisService.getCacheMapValue(getTokenKey(userKey), SecurityConstants.BaseSecurity.ENTERPRISE.getCode());
}
} catch (Exception ignored) {
System.err.println(ignored.getMessage());;
}
return null;
}
@@ -177,6 +179,7 @@ public class BaseTokenService<User, LoginUser extends BaseLoginUser<User>> {
return redisService.getCacheMapValue(getTokenKey(userKey), SecurityConstants.BaseSecurity.USER.getCode());
}
} catch (Exception ignored) {
System.err.println(ignored.getMessage());;
}
return null;
}
@@ -213,6 +216,7 @@ public class BaseTokenService<User, LoginUser extends BaseLoginUser<User>> {
return redisService.getCacheMapValue(getTokenKey(userKey), SecurityConstants.BaseSecurity.LOGIN_USER.getCode());
}
} catch (Exception ignored) {
System.err.println(ignored.getMessage());;
}
return null;
}
@@ -260,6 +264,7 @@ public class BaseTokenService<User, LoginUser extends BaseLoginUser<User>> {
return redisService.getCacheMapValue(getTokenKey(userKey), SecurityConstants.BaseSecurity.SOURCE.getCode());
}
} catch (Exception ignored) {
System.err.println(ignored.getMessage());;
}
return null;
}
@@ -297,6 +302,7 @@ public class BaseTokenService<User, LoginUser extends BaseLoginUser<User>> {
return redisService.getCacheMapValue(getTokenKey(userKey), SecurityConstants.BaseSecurity.EXPIRE_TIME.getCode());
}
} catch (Exception ignored) {
System.err.println(ignored.getMessage());;
}
return null;
}
@@ -329,7 +335,7 @@ public class BaseTokenService<User, LoginUser extends BaseLoginUser<User>> {
*/
public void refreshToken(HttpServletRequest request) {
String token = SecurityUtils.getToken(request);
refreshToken(SecurityUtils.getToken(request));
refreshToken(token);
}

/**


+ 1
- 4
xueyi-common/xueyi-common-sms/src/main/java/com/xueyi/common/sms/service/SmsService.java View File

@@ -4,9 +4,6 @@ import com.xueyi.common.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/**
* spring sms 工具类
*
@@ -19,6 +16,7 @@ public class SmsService {
@Autowired
private RedisService redisService;


/**
* @Author yangkai
* @Description //发送验证码,取时间戳后四位
@@ -27,7 +25,6 @@ public class SmsService {
* @return
**/
public String sendCode(){
Set<String> codes = new HashSet<>();
String code = "";
//确保不重复
while(true) {


+ 40
- 0
xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/config/WebApiMvcConfig.java View File

@@ -0,0 +1,40 @@
package com.xueyi.common.web.config;

import com.xueyi.common.web.interceptor.ApiRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
* 拦截器配置
*
* @author xueyi
*/
@Configuration
public class WebApiMvcConfig implements WebMvcConfigurer {

/**
* 不需要拦截地址
*/
public static final String[] excludeUrls = {"/login", "/logout", "/refresh"};

@Override
public void addInterceptors(InterceptorRegistry registry) {
System.err.println("WebMvcConfig.addInterceptors======================hshshkbb");

registry.addInterceptor(getApiInterceptor())
.addPathPatterns("/8888")
// .addPathPatterns("/**")
.excludePathPatterns(excludeUrls)
.order(1);
}

/**
* 自定义请求头拦截器
*/
@Bean
public ApiRequestInterceptor getApiInterceptor() {
return new ApiRequestInterceptor();
}
}

+ 39
- 1
xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/controller/BaseApiController.java View File

@@ -2,9 +2,10 @@ package com.xueyi.common.web.controller;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.collect.Lists;
import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.common.web.constant.ResponseCode;
import com.xueyi.common.web.entity.domain.BaseReq;
import com.xueyi.common.web.response.MyResponse;
import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo;
import com.xueyi.system.api.device.feign.RemoteDeviceTenantMergeService;
import org.springframework.beans.factory.annotation.Autowired;

@@ -21,6 +22,43 @@ public class BaseApiController {
private MyResponse message = null;


public MyResponse checkSign(Object t, String sign, String ts){
System.err.println("----------header check start----------");
if (ts == null || ts.isEmpty()) {
return output(400, "ts is null");
}
if (sign == null || sign.isEmpty()) {
return new MyResponse(400, "sign is null");
}
ts.replace(".", "");
Long tsVal = Long.parseLong(ts);
if (ts.length() == 10) {
// 将10位时间戳转为13位
tsVal *= 1000;
}
Long currentTs = System.currentTimeMillis();

if (currentTs - tsVal > 1000 * 60 || tsVal - currentTs > 1000 * 60){//时间误差正负1分钟内为合法
return new MyResponse(400, "请求时间戳ts非法");
}
System.err.println("----------header check complete----------");
BaseReq req = null;
String signStr = "";
if (t instanceof BaseReq) {
req = (BaseReq) t;
signStr = req.getSign(ts);
}
System.err.println(signStr);
System.err.println(sign);
System.err.println("----------sign check end----------");

if (!sign.equals(signStr)) {
return output(ResponseCode.AUTH_NOT_PASS);
}
return new MyResponse(200);
}


public DeviceTenantSourceMergeVo getDeviceTenantSourceMergeVo(String devId){
return remoteDeviceTenantMergeService.selectDeviceTenantSourceMerge(devId);
}


+ 45
- 0
xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/entity/domain/BaseReq.java View File

@@ -0,0 +1,45 @@
package com.xueyi.common.web.entity.domain;

import lombok.Data;
import org.springframework.util.DigestUtils;

import java.lang.reflect.Field;
import java.util.Arrays;

/**
* @author yk
* @description
* @date 2023-12-06 11:45
*/
@Data
public class BaseReq {

public String getSign(String ts){
Field[] fields = this.getClass().getDeclaredFields();
StringBuilder sb = new StringBuilder();
//fields按name字典排序
Arrays.sort(fields, (o1, o2) -> o1.getName().compareTo(o2.getName()));
for (Field field : fields) {
//设置允许通过反射访问私有变量
field.setAccessible(true);
//获取字段属性名称
String name = field.getName();
//获取字段的值
String value = null;
try {
value = field.get(this).toString();
sb.append(value);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
//其他自定义操作
System.out.println("字段的属性名称:"+name);
System.out.println("字段的值:"+value);
}
String parmas = sb.toString()+ts;
System.err.println("加密前的参数:"+parmas);
//返回md5加密后的值
return DigestUtils.md5DigestAsHex(parmas.getBytes());
}

}

+ 21
- 0
xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/entity/domain/mapper/DeviceTenantMergeMapper.java View File

@@ -0,0 +1,21 @@
package com.xueyi.common.web.entity.domain.mapper;

import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.common.web.annotation.TenantIgnore;
import com.xueyi.common.web.entity.domain.provider.DeviceTenantSqlProvider;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;

/**
* 设备租户(企业)关联管理 数据封装层
*
* @author xueyi
*/
@Mapper
public interface DeviceTenantMergeMapper {

@TenantIgnore(tenantLine = true)
@SelectProvider(type= DeviceTenantSqlProvider.class, method="selectDeviceTenant")
DeviceTenantSourceMergeVo selectByDeviceId(@Param("deviceId") String deviceId);
}

+ 14
- 0
xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/entity/domain/provider/DeviceTenantSqlProvider.java View File

@@ -0,0 +1,14 @@
package com.xueyi.common.web.entity.domain.provider;

import org.apache.ibatis.annotations.Param;

/**
* @author yk
* @description
* @date 2023-11-25 11:15
*/
public class DeviceTenantSqlProvider {
public String selectDeviceTenant(@Param("deviceId") String deviceId) {
return "SELECT ddtm.dev_id, ddtm.tenant_id, s.source_slave FROM dm_device_tenant_merge ddtm JOIN te_tenant t ON t.id=ddtm.tenant_id JOIN te_strategy s ON s.id=t.strategy_id AND dev_id= #{deviceId}";
}
}

+ 82
- 0
xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/interceptor/ApiRequestInterceptor.java View File

@@ -0,0 +1,82 @@
package com.xueyi.common.web.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.context.SecurityContextHolder;
import com.xueyi.common.core.utils.DecodeRequestUtils;
import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.common.web.entity.domain.mapper.DeviceTenantMergeMapper;
import com.xueyi.system.api.device.feign.RemoteDeviceTenantMergeService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

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

/**
* 自定义API拦截器,验证api请求权限
* 会根据传入的deviceId值,验证权限
*
* @author xueyi
*/
public class ApiRequestInterceptor implements HandlerInterceptor {

private static final Logger logger = LoggerFactory.getLogger(ApiRequestInterceptor.class);

@Autowired
RemoteDeviceTenantMergeService remoteDeviceTenantMergeService;


@Autowired
private DeviceTenantMergeMapper mergeMapper;

//为以下方法加行级注释
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}

String str = DecodeRequestUtils.getRequestPostStr(request);

logger.info("请求参数:{}", str);

JSONObject jsonObject = null;
if (str.indexOf("{")>-1) {
jsonObject = JSONObject.parseObject(str);// 解析请求参数
}

if ((request.getParameterMap().containsKey("deviceId")||request.getParameterMap().containsKey("devId")) || (jsonObject!=null && (jsonObject.containsKey("deviceId")||jsonObject.containsKey("devId")))) {
String devId = request.getParameter("deviceId");
devId = StringUtils.isEmpty(devId) ? request.getParameter("devId") : devId;
if (StringUtils.isEmpty(devId) && jsonObject != null) {
devId = jsonObject.getString("deviceId");
devId = StringUtils.isEmpty(devId) ? jsonObject.getString("devId") : devId;
}

/*DeviceTenantSourceMergeVo vo = null;
if (RedisUtil.existed("saas:source:device:" + devId)) {
vo = (DeviceTenantSourceMergeVo) RedisUtil.getVal("saas:source:device:" + devId);
} else {
vo = remoteDeviceTenantMergeService.selectDeviceTenantSourceMerge(devId);
RedisUtil.setVal("saas:source:device:" + devId, vo);
}*/

DeviceTenantSourceMergeVo vo = mergeMapper.selectByDeviceId(devId);// 查询设备与租户、来源的关联关系
SecurityContextHolder.setEnterpriseId(vo.getTenantId().toString());// 设置企业ID
SecurityContextHolder.setSourceName(vo.getSourceSlave());// 设置数据源名称
SecurityContextHolder.set(SecurityConstants.FROM_SOURCE, SecurityConstants.INNER);// 设置数据来源

}
return true;
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
SecurityContextHolder.remove();
}
}

+ 355
- 330
xueyi-common/xueyi-common-web/src/main/java/com/xueyi/common/web/utils/DateUtils.java View File

@@ -7,6 +7,7 @@ import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
@@ -16,334 +17,358 @@ import java.util.GregorianCalendar;
import java.util.List;

public class DateUtils extends org.apache.commons.lang.time.DateUtils {
public DateUtils() {
}

public static Date getPushForwardDate(Date date, Integer num) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(5, -(num - 1));
calendar.set(11, 0);
calendar.set(12, 0);
calendar.set(13, 0);
calendar.set(14, 0);
return calendar.getTime();
}
}

public static Date getFixedPushForwardDate(Date date, Integer num) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(5, -(num));
calendar.set(11, 0);
calendar.set(12, 0);
calendar.set(13, 0);
calendar.set(14, 0);
return calendar.getTime();
}
}

public static Date getOfDayFirst(Date date) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(11, 0);
calendar.set(12, 0);
calendar.set(13, 0);
calendar.set(14, 0);
return calendar.getTime();
}
}

public static Date getOfDayLast(Date date) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(11, 23);
calendar.set(12, 59);
calendar.set(13, 59);
calendar.set(14, 999);
return calendar.getTime();
}
}

public static Date getPageDayLast(Date date) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(5, -1);
calendar.set(11, 23);
calendar.set(12, 59);
calendar.set(13, 59);
calendar.set(14, 999);
return calendar.getTime();
}
}

public static Date getFirstDayOfMonth(Date date) {
new SimpleDateFormat("yyyy-MM-dd ");
GregorianCalendar gcLast = (GregorianCalendar)Calendar.getInstance();
gcLast.setTime(date);
gcLast.set(Calendar.DAY_OF_MONTH, 1);
return gcLast.getTime();
}

public static Date getLastDayOfMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
return calendar.getTime();
}

public static Date getAttendanceTime(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(5, -2);
calendar.set(11, 23);
return calendar.getTime();
}

public static String getStartTime() {
Date dNow = new Date();
new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(dNow);
calendar.add(5, -1);
Date dBefore = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(dBefore);
}

/*/**
* @Author yangkai
* @Description 根据字符串日期返回星期几
* @Param [datetime]
* @return java.lang.String
**/
public static String dateToWeek(String datetime) {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
String[] weekDays = new String[]{"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
Calendar cal = Calendar.getInstance();
Date datet = null;

try {
datet = f.parse(datetime);
cal.setTime(datet);
} catch (ParseException var6) {
var6.printStackTrace();
}

int w = cal.get(7) - 1;
if (w < 0) {
w = 0;
}

return weekDays[w];
}

public static String getDatePoor(Date endDate, Date nowDate) {
long nd = 86400000L;
long nh = 3600000L;
long nm = 60000L;
long diff = endDate.getTime() - nowDate.getTime();
long day = diff / nd;
long hour = diff % nd / nh;
long min = diff % nd % nh / nm;
return day + ":" + hour;
}

/**
* 1 2 3 4 5 6 7
* 日 一 二 三 四 五 六
* @param date
* @return
*/
public static Integer getDayOfWeek(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.DAY_OF_WEEK);
}

public static List<String> generateNearlyDateString(Date currentDate, Integer nearlyDays) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(currentDate);
List<String> dateStringList = Lists.newLinkedList();

for(int i = 0; i < nearlyDays; ++i) {
calendar.add(5, i == 0 ? 0 : -1);
dateStringList.add(formatDate(calendar.getTime(), "yyyy-MM-dd"));
}

return dateStringList;
}

public static String dateDiff(Date startDate, Date endDate) {
if (null != startDate && null != endDate) {
Long mills = endDate.getTime() - startDate.getTime();
Integer minuteDiff = mills.intValue() / '\uea60';
Integer hours = minuteDiff / 60;
Integer minutes = minuteDiff % 60;
String hoursStr = hours + "h";
String minutesStr = minutes == 0 ? "" : minutes + "m";
return hoursStr + minutesStr;
} else {
return "0h";
}
}

public static Integer dateDiffMin(Date startDate, Date endDate) {
if (null != startDate && null != endDate) {
Long mills = endDate.getTime() - startDate.getTime();
Integer minuteDiff = mills.intValue() / '\uea60';
Integer hours = minuteDiff / 60;
Integer minutes = minuteDiff % 60;
return hours * 60 + minutes;
} else {
return 0;
}
}

public static String intToHourMin(Integer minuteDiff) {
Integer hours = minuteDiff / 60;
Integer minutes = minuteDiff % 60;
return hours+"小时"+ minutes+"分";
}

public static String formatDate(Date date, String pattern) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(date);
}

public static Date praseStringToDate(String dateStr) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat();
return sdf.parse(dateStr);
}

public static Date parseLongToDate(Long dateLong) throws ParseException {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(dateLong);
return calendar.getTime();
}

public static Date parseLongToDate(String dateLong) throws ParseException {
BigDecimal number = new BigDecimal(dateLong);
return parseLongToDate(number.doubleValue());
}
public static Date parseLongToDate(Double dateLong) throws ParseException {
Calendar calendar = Calendar.getInstance();
DecimalFormat df = new DecimalFormat("#"); // 创建DecimalFormat对象
String str = df.format(dateLong);
if (str.indexOf(".")>-1) {
str = str.replace(".","");
}
str = str.substring(0,13);
BigDecimal number = new BigDecimal(str);
calendar.setTimeInMillis(number.longValue());
return calendar.getTime();
}

public static String praseLongToDateString(Long dateLong) throws ParseException {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(dateLong);
Date date = calendar.getTime();
return formatDate(date, "yyyy-MM-dd HH:mm:ss");
}

public static String getMillsSecondsDouble() {
Long cutime = System.currentTimeMillis();
String cutimeStr = String.valueOf(cutime);
BigDecimal d = new BigDecimal(cutimeStr.substring(0, 10) + "." + cutimeStr.substring(10));
return d.stripTrailingZeros().toPlainString();
}

/**
*
* @param time 2018-07-06 19:35:23
* @param pattern yyyy-MM-dd HH:mm:ss
* @return
*/
public static Date parseStrToDate(String time, String pattern) {
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
ParsePosition pos = new ParsePosition(0);
return formatter.parse(time, pos);
}


//形如yyyy-MM-dd格式的时间串,赠加或减少几天
//如2022-06-06 增加一天 返回 2022-06-07
public static String dateStrAdd(String dateStr, int addDays){
Date date1 = DateUtils.parseStrToDate(dateStr, "yyyy-MM-dd");
Date date2 = DateUtils.addDays(date1, addDays);
String dateStr2 = DateUtils.formatDate(date2, "yyyy-MM-dd");
return dateStr2;
}

public static int dateStrDiff(String startDateStr, String endDateStr) {
Date date1 = DateUtils.parseStrToDate(startDateStr, "yyyy-MM-dd");
Date date2 = DateUtils.parseStrToDate(endDateStr, "yyyy-MM-dd");

Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);

Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
int day1= cal1.get(Calendar.DAY_OF_YEAR);
int day2 = cal2.get(Calendar.DAY_OF_YEAR);

int year1 = cal1.get(Calendar.YEAR);
int year2 = cal2.get(Calendar.YEAR);
if (year1 != year2) {//同一年
int timeDistance = 0;
for (int i = year1; i < year2; i++) {
if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) //闰年
{
timeDistance += 366;
} else {
timeDistance += 365;
}
}

return timeDistance + (day2 - day1);
} else {// 不同年
return day2 - day1;
}
}


public static LocalDateTime currentDateToLocalDateTime(){
Date todayDate = new Date();
return dateToLocalDateTime(todayDate);
}

public static LocalDateTime dateToLocalDateTime(Date date){

LocalDateTime ldt = date.toInstant()
.atZone( ZoneId.systemDefault() )
.toLocalDateTime();

return ldt;
}

public static String isAmPm(){
//判断当前时间是上午还是下午,上午返回am,下午返回pm
LocalTime currentTime = LocalTime.now();

if (currentTime.isBefore(LocalTime.NOON)) {
return "am";
} else {
return "pm";
}
}
public DateUtils() {
}

public static Date getPushForwardDate(Date date, Integer num) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(5, -(num - 1));
calendar.set(11, 0);
calendar.set(12, 0);
calendar.set(13, 0);
calendar.set(14, 0);
return calendar.getTime();
}
}

public static Date getFixedPushForwardDate(Date date, Integer num) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(5, -(num));
calendar.set(11, 0);
calendar.set(12, 0);
calendar.set(13, 0);
calendar.set(14, 0);
return calendar.getTime();
}
}

public static Date getOfDayFirst(Date date) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(11, 0);
calendar.set(12, 0);
calendar.set(13, 0);
calendar.set(14, 0);
return calendar.getTime();
}
}

public static Date getOfDayLast(Date date) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(11, 23);
calendar.set(12, 59);
calendar.set(13, 59);
calendar.set(14, 999);
return calendar.getTime();
}
}

public static Date getPageDayLast(Date date) {
if (date == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(5, -1);
calendar.set(11, 23);
calendar.set(12, 59);
calendar.set(13, 59);
calendar.set(14, 999);
return calendar.getTime();
}
}

public static Date getFirstDayOfMonth(Date date) {
new SimpleDateFormat("yyyy-MM-dd ");
GregorianCalendar gcLast = (GregorianCalendar) Calendar.getInstance();
gcLast.setTime(date);
gcLast.set(Calendar.DAY_OF_MONTH, 1);
return gcLast.getTime();
}

public static Date getLastDayOfMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
return calendar.getTime();
}

public static Date getAttendanceTime(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(5, -2);
calendar.set(11, 23);
return calendar.getTime();
}

public static String getStartTime() {
Date dNow = new Date();
new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(dNow);
calendar.add(5, -1);
Date dBefore = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(dBefore);
}

/*/**
* @Author yangkai
* @Description 根据字符串日期返回星期几
* @Param [datetime]
* @return java.lang.String
**/
public static String dateToWeek(String datetime) {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
String[] weekDays = new String[]{"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
Calendar cal = Calendar.getInstance();
Date datet = null;

try {
datet = f.parse(datetime);
cal.setTime(datet);
} catch (ParseException var6) {
var6.printStackTrace();
}

int w = cal.get(7) - 1;
if (w < 0) {
w = 0;
}

return weekDays[w];
}

public static String getDatePoor(Date endDate, Date nowDate) {
long nd = 86400000L;
long nh = 3600000L;
long nm = 60000L;
long diff = endDate.getTime() - nowDate.getTime();
long day = diff / nd;
long hour = diff % nd / nh;
long min = diff % nd % nh / nm;
return day + ":" + hour;
}

/**
* 1 2 3 4 5 6 7
* 日 一 二 三 四 五 六
*
* @param date
* @return
*/
public static Integer getDayOfWeek(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.DAY_OF_WEEK);
}

public static List<String> generateNearlyDateString(Date currentDate, Integer nearlyDays) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(currentDate);
List<String> dateStringList = Lists.newLinkedList();

for (int i = 0; i < nearlyDays; ++i) {
calendar.add(5, i == 0 ? 0 : -1);
dateStringList.add(formatDate(calendar.getTime(), "yyyy-MM-dd"));
}

return dateStringList;
}

public static String dateDiff(Date startDate, Date endDate) {
if (null != startDate && null != endDate) {
Long mills = endDate.getTime() - startDate.getTime();
Integer minuteDiff = mills.intValue() / '\uea60';
Integer hours = minuteDiff / 60;
Integer minutes = minuteDiff % 60;
String hoursStr = hours + "h";
String minutesStr = minutes == 0 ? "" : minutes + "m";
return hoursStr + minutesStr;
} else {
return "0h";
}
}

public static Integer dateDiffMin(Date startDate, Date endDate) {
if (null != startDate && null != endDate) {
Long mills = endDate.getTime() - startDate.getTime();
Integer minuteDiff = mills.intValue() / '\uea60';
Integer hours = minuteDiff / 60;
Integer minutes = minuteDiff % 60;
return hours * 60 + minutes;
} else {
return 0;
}
}

public static String intToHourMin(Integer minuteDiff) {
Integer hours = minuteDiff / 60;
Integer minutes = minuteDiff % 60;
return hours + "小时" + minutes + "分";
}

public static String formatDate(Date date, String pattern) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(date);
}

public static Date praseStringToDate(String dateStr) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat();
return sdf.parse(dateStr);
}

public static Date parseLongToDate(Long dateLong) throws ParseException {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(dateLong);
return calendar.getTime();
}

public static Date parseLongToDate(String dateLong) throws ParseException {
BigDecimal number = new BigDecimal(dateLong);
return parseLongToDate(number.doubleValue());
}

public static Date parseLongToDate(Double dateLong) throws ParseException {
Calendar calendar = Calendar.getInstance();
DecimalFormat df = new DecimalFormat("#"); // 创建DecimalFormat对象
String str = df.format(dateLong);
if (str.indexOf(".") > -1) {
str = str.replace(".", "");
}
str = str.substring(0, 13);
BigDecimal number = new BigDecimal(str);
calendar.setTimeInMillis(number.longValue());
return calendar.getTime();
}

public static String praseLongToDateString(Long dateLong) throws ParseException {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(dateLong);
Date date = calendar.getTime();
return formatDate(date, "yyyy-MM-dd HH:mm:ss");
}

public static String getMillsSecondsDouble() {
Long cutime = System.currentTimeMillis();
String cutimeStr = String.valueOf(cutime);
BigDecimal d = new BigDecimal(cutimeStr.substring(0, 10) + "." + cutimeStr.substring(10));
return d.stripTrailingZeros().toPlainString();
}

/**
* @param time 2018-07-06 19:35:23
* @param pattern yyyy-MM-dd HH:mm:ss
* @return
*/
public static Date parseStrToDate(String time, String pattern) {
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
ParsePosition pos = new ParsePosition(0);
return formatter.parse(time, pos);
}


//形如yyyy-MM-dd格式的时间串,赠加或减少几天
//如2022-06-06 增加一天 返回 2022-06-07
public static String dateStrAdd(String dateStr, int addDays) {
Date date1 = DateUtils.parseStrToDate(dateStr, "yyyy-MM-dd");
Date date2 = DateUtils.addDays(date1, addDays);
String dateStr2 = DateUtils.formatDate(date2, "yyyy-MM-dd");
return dateStr2;
}

public static int dateStrDiff(String startDateStr, String endDateStr) {
Date date1 = DateUtils.parseStrToDate(startDateStr, "yyyy-MM-dd");
Date date2 = DateUtils.parseStrToDate(endDateStr, "yyyy-MM-dd");

Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);

Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
int day1 = cal1.get(Calendar.DAY_OF_YEAR);
int day2 = cal2.get(Calendar.DAY_OF_YEAR);

int year1 = cal1.get(Calendar.YEAR);
int year2 = cal2.get(Calendar.YEAR);
if (year1 != year2) {//同一年
int timeDistance = 0;
for (int i = year1; i < year2; i++) {
if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) //闰年
{
timeDistance += 366;
} else {
timeDistance += 365;
}
}

return timeDistance + (day2 - day1);
} else {// 不同年
return day2 - day1;
}
}


public static LocalDateTime currentDateToLocalDateTime() {
Date todayDate = new Date();
return dateToLocalDateTime(todayDate);
}

public static LocalDateTime dateToLocalDateTime(Date date) {

LocalDateTime ldt = date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();

return ldt;
}

public static String isAmPm() {
//判断当前时间是上午还是下午,上午返回am,下午返回pm
LocalTime currentTime = LocalTime.now();

if (currentTime.isBefore(LocalTime.NOON)) {
return "am";
} else {
return "pm";
}
}

public static String getChineseWeek(Date date) {
int week = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(date)).getDayOfWeek().getValue();
switch (week) {
case 1:
return "周一";
case 2:
return "周二";
case 3:
return "周三";
case 4:
return "周四";
case 5:
return "周五";
case 6:
return "周六";
case 7:
return "周日";
default:
return "";
}

}
}

+ 3
- 1
xueyi-common/xueyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports View File

@@ -3,4 +3,6 @@ com.xueyi.common.web.config.XueYiMyBatisPlusConfig
com.xueyi.common.web.config.XueYiMyRespConfig
com.xueyi.common.web.handler.XueYiMetaObjectHandler
com.xueyi.common.web.handler.TenantLineHandler
com.xueyi.common.web.aspect.AutoInjectAspect
com.xueyi.common.web.aspect.AutoInjectAspect
com.xueyi.common.web.config.WebApiMvcConfig
com.xueyi.common.web.interceptor.ApiRequestInterceptor

+ 5
- 4
xueyi-gateway/src/main/java/com/xueyi/gateway/filter/AuthFilter.java View File

@@ -37,7 +37,8 @@ public class AuthFilter implements GlobalFilter, Ordered {
@Autowired
private RedisService redisService;

private static final String[] whitePrefix = {"/message/api", "/pass/api", "/meeting/api", "/visit/api", "/file/api","/staff/api","/apkversion/api","/man/api","/holiday/api", "/skill/api", "/intent/api","/system/api","/dept/api"};
//TODO. 需要删除,通过nacos配置管理白名单
// private static final String[] whitePrefix = {"/message/api", "/pass/api", "/visit/api", "/file/api","/staff/api","/apkversion/api","/man/api","/device/api","/holiday/api", "/skill/api", "/intent/api","/system/api"};

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
@@ -49,9 +50,9 @@ public class AuthFilter implements GlobalFilter, Ordered {
if (StrUtil.matches(url, ignoreWhite.getWhites())) {
return chain.filter(exchange);
}
// 跳过不需要验证的路径.
for (String item : whitePrefix)
if (url.contains(item)) return chain.filter(exchange);
// TODO. 需要删除 跳过不需要验证的路径.
/*for (String item : whitePrefix)
if (url.contains(item)) return chain.filter(exchange);*/

String token = getToken(request);
if (StrUtil.isEmpty(token)) {


+ 6
- 0
xueyi-modules/xueyi-file/pom.xml View File

@@ -78,6 +78,12 @@
<version>2.0.29</version>
</dependency>

<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.13.0, 7.13.99]</version>
</dependency>

</dependencies>

<build>


+ 54
- 0
xueyi-modules/xueyi-file/src/main/java/com/xueyi/file/config/QiNiuConfig.java View File

@@ -0,0 +1,54 @@
package com.xueyi.file.config;

import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Minio 配置信息
*
* @author xueyi
*/
@Configuration
@ConfigurationProperties(prefix = "qiniu")
@Data
public class QiNiuConfig {

/** accessKey */
private String accessKey;

/** secretKey */
private String secretKey;

/** bucket */
private String bucket;


private String tempBucket;

public String qiNiuUploadToken() {
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
return upToken;
}

public String qiNiuTempUploadToken() {
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(tempBucket);
return upToken;
}



@Bean
public UploadManager uploadManager() {
com.qiniu.storage.Configuration cfg = new com.qiniu.storage.Configuration(Region.region1());
cfg.resumableUploadAPIVersion = com.qiniu.storage.Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
//...其他参数参考类注释
return new UploadManager(cfg);
}
}

+ 4
- 3
xueyi-modules/xueyi-file/src/main/java/com/xueyi/file/controller/SysFileController.java View File

@@ -33,6 +33,7 @@ import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
@@ -249,10 +250,10 @@ public class SysFileController {
}
}

@DeleteMapping(value = "/inner/delete-files")
public R<Boolean> deleteFilesInner(@RequestParam(value = "urls") List<String> urls) {
@PostMapping(value = "/inner/delete-files")
public R<Boolean> deleteFilesInner(@RequestParam("urls") String[] urls) {
try {
Boolean result = minioSysFileService.deleteFiles(urls);
Boolean result = minioSysFileService.deleteFiles(Arrays.stream(urls).toList());
return R.ok(result);
} catch (Exception e) {
log.error("文件删除失败", e);


+ 22
- 6
xueyi-modules/xueyi-file/src/main/java/com/xueyi/file/service/MinioSysFileServiceImpl.java View File

@@ -99,7 +99,23 @@ public class MinioSysFileServiceImpl implements ISysFileService {

@Override
public String uploadTempFile(MultipartFile file) throws Exception {
return null;
String fileName = FileUploadUtils.extractFilename(file);

//fileName = URLEncoder.encode(fileName, "UTF-8");
log.info("Minio filename: {}" , fileName);
PutObjectArgs args = PutObjectArgs.builder()
.bucket(minioConfig.getTempBucketName())
.object(fileName)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(file.getContentType())
.build();
client.putObject(args);
log.info("Minio 文件上传成功");
// 获取fileName的最后一个'/'的位置的字符串,并用URLEncoder进行UTF-8编码后,再拼接到fileName中
String splitStr = fileName.substring(fileName.lastIndexOf("/") + 1);
splitStr = URLEncoder.encode(splitStr, "UTF-8");
fileName = fileName.substring(0, fileName.lastIndexOf("/") + 1) + splitStr;
return minioConfig.getUrl() + "/" + minioConfig.getTempBucketName() + "/" + fileName;
}

@Override
@@ -113,7 +129,7 @@ public class MinioSysFileServiceImpl implements ISysFileService {
byte[] fileBytes = IOUtils.toByteArray(inputStream);

// 上传文件到MinIO
String minioFileName = uploadFileToMinIO(fileName, fileBytes);
String minioFileName = uploadFileToMinIO(fileName, fileBytes, minioConfig.getBucketName());

log.info("MinIO 文件上传成功,Minio 文件名:{}" , minioFileName);

@@ -136,7 +152,7 @@ public class MinioSysFileServiceImpl implements ISysFileService {
byte[] fileBytes = IOUtils.toByteArray(inputStream);

// 上传文件到MinIO
String minioFileName = uploadFileToMinIO(fileName, fileBytes);
String minioFileName = uploadFileToMinIO(fileName, fileBytes, minioConfig.getTempBucketName());

log.info("MinIO Temp文件上传成功,Minio 文件名:{}", minioFileName);

@@ -145,13 +161,13 @@ public class MinioSysFileServiceImpl implements ISysFileService {
splitStr = URLEncoder.encode(splitStr, "UTF-8");
fileName = fileName.substring(0, fileName.lastIndexOf("/") + 1) + splitStr;

return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
return minioConfig.getUrl() + "/" + minioConfig.getTempBucketName() + "/" + fileName;
}

// 上传文件到MinIO
private String uploadFileToMinIO(String fileName, byte[] fileBytes) throws Exception {
private String uploadFileToMinIO(String fileName, byte[] fileBytes, String bucketName) throws Exception {
PutObjectArgs args = PutObjectArgs.builder()
.bucket(minioConfig.getBucketName())
.bucket(bucketName)
.object(fileName)
.stream(new ByteArrayInputStream(fileBytes), fileBytes.length, -1)
.contentType("application/octet-stream")


+ 207
- 0
xueyi-modules/xueyi-file/src/main/java/com/xueyi/file/service/QiNiuSysFileServiceImpl.java View File

@@ -0,0 +1,207 @@
package com.xueyi.file.service;

import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.xueyi.file.config.QiNiuConfig;
import com.xueyi.file.utils.FileUploadUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

/**
* QiNiu 文件存储
*
* @author xueyi
*/
@Primary
@Service
public class QiNiuSysFileServiceImpl implements ISysFileService {

private static final Logger log = LoggerFactory.getLogger(QiNiuSysFileServiceImpl.class);

@Autowired
private QiNiuConfig qiNiuConfig;

@Autowired
private UploadManager uploadManager;

/**
* 本地文件上传接口
*
* @param file 上传的文件
* @return 访问地址
*/
@Override
public String uploadFile(MultipartFile file) throws Exception {
String fileName = FileUploadUtils.extractFilename(file);

//将MultipartFile类型的文件转换为File类型
File localFile = new File(fileName);
IOUtils.copy(file.getInputStream(), new FileOutputStream(localFile));


//fileName = URLEncoder.encode(fileName, "UTF-8");
log.info("Minio filename: {}" , fileName);
try {
Response response = uploadManager.put(localFile.getAbsolutePath(), fileName, qiNiuConfig.qiNiuUploadToken());
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
return putRet.key;
} catch (QiniuException ex) {
ex.printStackTrace();
if (ex.response != null) {
System.err.println(ex.response);
try {
String body = ex.response.toString();
System.err.println(body);
} catch (Exception ignored) {
}
}
}
return null;
}


String uploadFileFun(String fileName, File file, boolean isTemp) throws Exception {
fileName = FileUploadUtils.extractFilename(fileName);
log.info("file original filename = {}" , fileName);
log.info("file size = {} " , file.length());
String token = isTemp ? qiNiuConfig.qiNiuTempUploadToken() : qiNiuConfig.qiNiuUploadToken();

log.info("Minio filename: {}" , fileName);
try {
Response response = uploadManager.put(file.getAbsolutePath(), fileName, token);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
return putRet.key;
} catch (QiniuException ex) {
ex.printStackTrace();
if (ex.response != null) {
System.err.println(ex.response);
try {
String body = ex.response.toString();
System.err.println(body);
} catch (Exception ignored) {
}
}
}
return null;
}


@Override
public String uploadExactFile(MultipartFile file, String extension) throws Exception {
String fileName = FileUploadUtils.extractFilename(file).replaceAll(extension, "");
fileName += extension;
File localFile = new File(fileName);
if (!localFile.exists()) {
if (!localFile.getParentFile().exists()) {
localFile.getParentFile().mkdirs();
}
}
IOUtils.copy(file.getInputStream(), new FileOutputStream(localFile));

//fileName = URLEncoder.encode(fileName, "UTF-8");
log.info("Minio filename: {}" , fileName);
try {
Response response = uploadManager.put(localFile.getAbsolutePath(), fileName, qiNiuConfig.qiNiuUploadToken());
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
return putRet.key;
} catch (QiniuException ex) {
ex.printStackTrace();
if (ex.response != null) {
System.err.println(ex.response);
try {
String body = ex.response.toString();
System.err.println(body);
} catch (Exception ignored) {
}
}
}
return null;
}

@Override
public String uploadTempFile(MultipartFile file) throws Exception {
String fileName = FileUploadUtils.extractFilename(file);

//fileName = URLEncoder.encode(fileName, "UTF-8");
File localFile = new File(fileName);
IOUtils.copy(file.getInputStream(), new FileOutputStream(localFile));


//fileName = URLEncoder.encode(fileName, "UTF-8");
log.info("Minio filename: {}" , fileName);
try {
Response response = uploadManager.put(localFile.getAbsolutePath(), fileName, qiNiuConfig.qiNiuUploadToken());
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
return putRet.key;
} catch (QiniuException ex) {
ex.printStackTrace();
if (ex.response != null) {
System.err.println(ex.response);
try {
String body = ex.response.toString();
System.err.println(body);
} catch (Exception ignored) {
}
}
}
return null;
}

@Override
public String uploadFile(String fileName, File file) throws Exception {
return uploadFileFun(fileName, file, false);
}


public String uploadTempFile(String fileName, File file) throws Exception {
return uploadFileFun(fileName, file, true);
}




public String uploadFile(File file) throws Exception {
return uploadFileFun(file.getName(), file, false);
}



/**
* 文件删除接口,通过minio的文件url进行删除
*
* @param url 文件url
* @return 结果
*/
public Boolean deleteFile(String url) throws Exception {

return true;
}

public Boolean deleteFiles(List<String> urls) throws Exception {
return true;
}
}

+ 5
- 1
xueyi-modules/xueyi-job/src/main/java/com/xueyi/job/task/DmRecognizedRecordsCleanTask.java View File

@@ -1,6 +1,8 @@
package com.xueyi.job.task;

import com.xueyi.system.api.digitalmans.feign.RemoteDigitalmanService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@@ -11,6 +13,7 @@ import org.springframework.stereotype.Component;
*/
@Component("dmRecognizedRecordsCleanTask")
public class DmRecognizedRecordsCleanTask {
private static final Logger log = LoggerFactory.getLogger(DmRecognizedRecordsCleanTask.class);
@Autowired
RemoteDigitalmanService remoteDigitalmanService;
/**
@@ -20,6 +23,7 @@ public class DmRecognizedRecordsCleanTask {


public void delOutDays() {
remoteDigitalmanService.delRecognizedRecords(5);
log.info("定时任务调度测试:删除过期通行记录照片");
remoteDigitalmanService.delRecognizedRecords(60);
}
}

+ 5
- 0
xueyi-modules/xueyi-message/pom.xml View File

@@ -100,6 +100,11 @@
<artifactId>xueyi-api-system</artifactId>
</dependency>

<dependency>
<groupId>com.xueyi</groupId>
<artifactId>xueyi-api-nlt</artifactId>
</dependency>

</dependencies>

<build>


+ 1
- 1
xueyi-modules/xueyi-message/src/main/java/com/xueyi/message/handler/MqttTopicHandle.java View File

@@ -3,10 +3,10 @@ package com.xueyi.message.handler;
import com.alibaba.fastjson2.JSONObject;
import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.web.result.R;
import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.common.mqtt.annotation.MqttService;
import com.xueyi.common.mqtt.annotation.MqttTopic;
import com.xueyi.message.api.transfer.domain.vo.DmDeployScheduleVo;
import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo;
import com.xueyi.system.api.device.feign.RemoteDeviceTenantMergeService;
import com.xueyi.system.api.digitalmans.feign.RemoteDigitalmanMqttService;
import com.xueyi.system.api.version.feign.RemoteReleaseManagerService;


+ 46
- 13
xueyi-modules/xueyi-message/src/main/java/com/xueyi/message/transfer/controller/ApiController.java View File

@@ -9,24 +9,22 @@ import com.xueyi.common.core.constant.digitalman.InitConstants;
import com.xueyi.common.core.constant.digitalman.MessageConstants;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.common.redis.utils.RedisUtil;
import com.xueyi.common.web.utils.DateUtils;
import com.xueyi.message.api.transfer.domain.vo.DmActiveVo;
import com.xueyi.message.api.transfer.domain.vo.DmDeviceVo;
import com.xueyi.message.transfer.service.impl.MessageQueueServiceImpl;
import com.xueyi.nlt.api.nlt.feign.RemoteSeniverseService;
import com.xueyi.system.api.authority.feign.RemoteLoginService;
import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo;
import com.xueyi.system.api.device.feign.RemoteDeviceTenantMergeService;
import com.xueyi.system.api.digitalmans.domain.dto.DmManDeviceDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmSkillDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmSyncDigitalmanDto;
import com.xueyi.system.api.digitalmans.domain.vo.DmBroadcastVo;
import com.xueyi.system.api.digitalmans.domain.vo.DmReceptionVo;
import com.xueyi.system.api.digitalmans.feign.RemoteBroadcastService;
import com.xueyi.system.api.digitalmans.feign.RemoteDigitalmanService;
import com.xueyi.system.api.digitalmans.feign.RemoteManDeviceService;
import com.xueyi.system.api.digitalmans.feign.RemoteReceptionService;
import com.xueyi.system.api.digitalmans.feign.RemoteSkillService;
import com.xueyi.system.api.digitalmans.domain.vo.DmTipVo;
import com.xueyi.system.api.digitalmans.feign.*;
import com.xueyi.system.api.model.Source;
import com.xueyi.system.api.organize.domain.dto.SysEnterpriseDto;
import com.xueyi.system.api.resource.feign.RemoteH5ConfigService;
@@ -35,14 +33,9 @@ import com.xueyi.system.api.staff.feign.RemoteStaffService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -91,6 +84,15 @@ public class ApiController {
@Autowired
RemoteH5ConfigService remoteH5ConfigService;

@Autowired
RemoteQuestionanswersService remoteQuestionanswersService;

@Autowired
RemoteSeniverseService remoteSeniverseService;

@Value("${notification.seniverse.key}")
private String seniverseKey;


@RequestMapping(value = "/heartbeat", method = {RequestMethod.POST})
@ResponseBody
@@ -441,4 +443,35 @@ public class ApiController {
}
return AjaxResult.success(propertyR.getData());
}

@RequestMapping(value = "/tip_list/{deviceId}", method = {RequestMethod.GET})
@ResponseBody
public AjaxResult tipList(@PathVariable(value = "deviceId") String deviceId, HttpServletResponse response) {
R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(deviceId);
if (manDeviceDtoR.isFail() || manDeviceDtoR.getData() == null) {
return AjaxResult.warn("设备号获取失败,请检查");
}
Source source = SourceUtil.getSourceCache(manDeviceDtoR.getData().getStrategyId());

R<List<DmTipVo>> listR = remoteQuestionanswersService.tipList(manDeviceDtoR.getData().getTId(), source.getMaster(), SecurityConstants.INNER);
if (listR.isFail()) {
return AjaxResult.warn("获取tip列表失败,请检查");
}
return AjaxResult.success(listR.getData());
}

/**
* 意图请求
列表
*/
@RequestMapping(value = "/weather",method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public AjaxResult weather(@RequestParam String city, HttpServletRequest request) {
log.info("weather:{}", city);
JSONObject result = remoteSeniverseService.now(seniverseKey,city,"zh-Hans","c");
log.info("weather:{}", result);

return AjaxResult.success(result.getJSONArray("results"));

}
}

+ 1
- 1
xueyi-modules/xueyi-modules-auth/src/main/java/com/xueyi/modules/auth/controller/SkillAuthApiController.java View File

@@ -3,10 +3,10 @@ package com.xueyi.modules.auth.controller;

import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.common.web.controller.BaseApiController;
import com.xueyi.modules.auth.api.domain.vo.IntentionReqDto;
import com.xueyi.modules.auth.api.feign.RemoteSkillAuthService;
import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;


+ 1
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/XueYiNltApplication.java View File

@@ -6,6 +6,7 @@ import com.xueyi.common.security.annotation.EnableRyFeignClients;
import com.xueyi.common.swagger.annotation.EnableCustomSwagger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableCustomConfig
@EnableCustomSwagger


+ 173
- 72
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/client/WebSocketClient.java View File

@@ -1,13 +1,22 @@
package com.xueyi.nlt.netty.client;

import cn.hutool.core.lang.Snowflake;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.alibaba.nacos.shaded.com.google.gson.JsonArray;
import com.alibaba.nacos.shaded.com.google.gson.JsonObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xueyi.common.core.utils.core.IdUtil;
import com.xueyi.common.web.interceptor.ApiRequestInterceptor;
import com.xueyi.nlt.api.netty.domain.vo.DmWebSocketMessageVo;
import com.xueyi.nlt.netty.server.config.ServerConfig;
import com.xueyi.nlt.nlt.domain.vo.LlmQueryVo;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import okhttp3.*;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
@@ -27,6 +36,7 @@ import java.util.*;
@Component
public class WebSocketClient extends WebSocketListener {

private static final Logger logger = LoggerFactory.getLogger(WebSocketClient.class);
public static WebSocketClient INSTANCE;
@Autowired
private RedisTemplate redisTemplate;
@@ -50,16 +60,20 @@ public class WebSocketClient extends WebSocketListener {
// public static String APIKEY = "7c217b3a313f4b66fcc14a8e97f85103";//从开放平台控制台中获取
// public static String APISecret = "ZTRiNDQwMTRlOTlmZDQwMDUwYTdjMDM0";//从开放平台控制台中获取

public static WebSocket webSocket;
public static String APPID = "948cf4b6";//从开放平台控制台中获取
public static String APIKEY = "54f6e81f40a31d66d976496de895a7a4";//从开放平台控制台中获取
public static String APISecret = "ZDYyMjNmMTlkYTE0YWRmOWUwZTYxNjYz";//从开放平台控制台中获取
public WebSocket webSocket;
public static final Gson json = new Gson();
// public static String question = "假设你是一位前台,你需要通过与其他人对话来获取会议相关信息,已知今天是2023-7-19,你需要获取会议日期,开始时间,持续时间,会议地点,会议主题。时间用类似00:00的格式输出。对方的话中可能不包含全部信息,对于未知的信息填充为none。如果所有信息都已知那么commit为true。否则为false。将你获得的信息输出为json格式。对方的话是:“明天下午开个会。从两点开到下午三点,在大会议室开,主题是访客接待”,只输出最后的json。输出只有一行,输出格式为{date:,start_time:,duration:,location:,theme:commit:}。";//可以修改question 内容,来向模型提问
public static String question = "请帮我安排五一出行计划";//可以修改question 内容,来向模型提问
public static String systemRole = "";
public static List<String> questions = new ArrayList<>();//可以修改question 内容,来向模型提问
// 定义内存共享变量traceId
public Long traceId;
public String question = "请帮我安排五一出行计划";//可以修改question 内容,来向模型提问
public String systemRole = "";
public List<String> questions = new ArrayList<>();//可以修改question 内容,来向模型提问

public boolean stream = false;
public String curUserId = null;
public String answer = "";
public String answerBuf = "";


@PostConstruct
public void init() {
@@ -73,7 +87,7 @@ public class WebSocketClient extends WebSocketListener {
synchronized (LOCK) {
try {
//构建鉴权httpurl
String authUrl = getAuthorizationUrl(INSTANCE.hostUrl, INSTANCE.apiKey, INSTANCE.apiSecret);
String authUrl = getAuthorizationUrl("https://spark-api.xf-yun.com/v3.1/chat", "54f6e81f40a31d66d976496de895a7a4", "ZDYyMjNmMTlkYTE0YWRmOWUwZTYxNjYz");
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
String url = authUrl.replace("https://","wss://").replace("http://","ws://");
Request request = new Request.Builder().url(url).build();
@@ -121,8 +135,12 @@ public class WebSocketClient extends WebSocketListener {
e.printStackTrace();
}
}

public void sendMsg(List<String> messages){
this.sendMsg(messages,false, null);
}
public void sendMsg(List<String> messages,boolean stream,String userId){
this.stream = stream;
this.curUserId = userId;
if (messages.size() / 2 > 0) {
systemRole = messages.get(0);
messages.remove(0);
@@ -136,7 +154,16 @@ public class WebSocketClient extends WebSocketListener {
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
String url = authUrl.replace("https://","wss://").replace("http://","ws://");
Request request = new Request.Builder().url(url).build();
webSocket = okHttpClient.newWebSocket(request,new WebSocketClient());
WebSocketClient wsc = new WebSocketClient();
wsc.stream = stream;
wsc.curUserId = userId;
wsc.questions = questions;
wsc.question = question;
wsc.systemRole = systemRole;
wsc.traceId = IdUtil.getSnowflakeNextId();
ServerConfig.currentTraceMap.put(curUserId,wsc.traceId);
System.out.println("wocket客户端:" + wsc.hashCode());
webSocket = okHttpClient.newWebSocket(request,wsc);

} catch (Exception e) {
e.printStackTrace();
@@ -251,78 +278,152 @@ public class WebSocketClient extends WebSocketListener {
public void onMessage(WebSocket webSocket, String text) {
super.onMessage(webSocket, text);
System.out.println("text:\n" + text);
if (!StringUtils.isEmpty(curUserId)) {
if (ServerConfig.currentTraceMap.containsKey(curUserId) && !ServerConfig.currentTraceMap.get(curUserId).equals(traceId)) {
return;
}
}

ResponseData responseData = json.fromJson(text,ResponseData.class);
synchronized (LOCK) {
try {
// System.out.println("code:\n" + responseData.getHeader().get("code"));
if (0 == responseData.getHeader().get("code").getAsInt()) {
System.out.println("###########");
System.out.println("getStatus: " + responseData.getHeader().get("status").getAsInt());
if (2 != responseData.getHeader().get("status").getAsInt()) {
System.out.println("****************");
Payload pl = json.fromJson(responseData.getPayload(), Payload.class);
JsonArray temp = (JsonArray) pl.getChoices().get("text");
JsonObject jo = (JsonObject) temp.get(0);
answer += jo.get("content").getAsString();
try {
// System.out.println("code:\n" + responseData.getHeader().get("code"));
if (0 == responseData.getHeader().get("code").getAsInt()) {
System.out.println("###########");
System.out.println("getStatus: " + responseData.getHeader().get("status").getAsInt());
if (2 != responseData.getHeader().get("status").getAsInt()) {
System.out.println("****************");
Payload pl = json.fromJson(responseData.getPayload(), Payload.class);
JsonArray temp = (JsonArray) pl.getChoices().get("text");
JsonObject jo = (JsonObject) temp.get(0);
answer += jo.get("content").getAsString();
answerBuf += jo.get("content").getAsString();
// System.out.println(answer);
} else {
Payload pl1 = json.fromJson(responseData.getPayload(), Payload.class);
JsonObject jsonObject = (JsonObject) pl1.getUsage().get("text");
int prompt_tokens = jsonObject.get("prompt_tokens").getAsInt();
JsonArray temp1 = (JsonArray) pl1.getChoices().get("text");
JsonObject jo = (JsonObject) temp1.get(0);
answer += jo.get("content").getAsString();
System.out.println("返回结果为:\n" + answer);

if (INSTANCE.redisTemplate.hasKey("gpt:websocket:1")) {
DmWebSocketMessageVo message = (DmWebSocketMessageVo) INSTANCE.redisTemplate.opsForValue().get("gpt:websocket:1");
if (message != null && StringUtils.isNotEmpty(message.getTemplate()) && message.getTemplate().equals("birthday")) {
JSONObject birthdayJo = new JSONObject();
birthdayJo.put("content", answer);
birthdayJo.put("timestamp", message.getFormat().get("timestamp"));
INSTANCE.stringRedisTemplate.opsForHash().put("group:nlp" + ":" + message.getFormat().getString("orderId"), "birthday", birthdayJo.toString());
INSTANCE.redisTemplate.delete("gpt:websocket:1");
return;
}
if (message!= null && StringUtils.isNotEmpty(message.getTemplate()) && message.getTemplate().equals("hireDate")) {
JSONObject birthdayJo = new JSONObject();
birthdayJo.put("content", answer);
birthdayJo.put("timestamp", message.getFormat().get("timestamp"));
INSTANCE.stringRedisTemplate.opsForHash().put("group:nlp" + ":" + message.getFormat().getString("orderId"), "hireDate", birthdayJo.toString());
INSTANCE.redisTemplate.delete("gpt:websocket:1");
return;
}
if (message != null) {
JSONObject preWebsocketJo = message.getFormat();
JSONObject meetingJo = new JSONObject();
meetingJo.put("timestamp",preWebsocketJo.get("timestamp"));
meetingJo.put("content",answer);
INSTANCE.stringRedisTemplate.opsForHash().put("group:nlp" + ":" + preWebsocketJo.getString("orderId"), "meeting", meetingJo.toString());
}
} else {
Payload pl1 = json.fromJson(responseData.getPayload(), Payload.class);
JsonObject jsonObject = (JsonObject) pl1.getUsage().get("text");
int prompt_tokens = jsonObject.get("prompt_tokens").getAsInt();
JsonArray temp1 = (JsonArray) pl1.getChoices().get("text");
JsonObject jo = (JsonObject) temp1.get(0);
answer += jo.get("content").getAsString();
answerBuf += jo.get("content").getAsString();
System.out.println("返回结果为:\n" + answer);

if (INSTANCE.redisTemplate.hasKey("gpt:websocket:1")) {
DmWebSocketMessageVo message = (DmWebSocketMessageVo) INSTANCE.redisTemplate.opsForValue().get("gpt:websocket:1");
if (message != null && StringUtils.isNotEmpty(message.getTemplate()) && message.getTemplate().equals("birthday")) {
JSONObject birthdayJo = new JSONObject();
birthdayJo.put("content", answer);
birthdayJo.put("timestamp", message.getFormat().get("timestamp"));
INSTANCE.stringRedisTemplate.opsForHash().put("group:nlp" + ":" + message.getFormat().getString("orderId"), "birthday", birthdayJo.toString());
INSTANCE.redisTemplate.delete("gpt:websocket:1");
// 清除systemRole
systemRole = "";

}else {
// 添加缓存
INSTANCE.stringRedisTemplate.opsForValue().set("group:websocket:content", answer);
LOCK.notifyAll();
return;
}
if (message!= null && StringUtils.isNotEmpty(message.getTemplate()) && message.getTemplate().equals("hireDate")) {
JSONObject birthdayJo = new JSONObject();
birthdayJo.put("content", answer);
birthdayJo.put("timestamp", message.getFormat().get("timestamp"));
INSTANCE.stringRedisTemplate.opsForHash().put("group:nlp" + ":" + message.getFormat().getString("orderId"), "hireDate", birthdayJo.toString());
INSTANCE.redisTemplate.delete("gpt:websocket:1");
return;
}
if (message != null) {
JSONObject preWebsocketJo = message.getFormat();
JSONObject meetingJo = new JSONObject();
meetingJo.put("timestamp",preWebsocketJo.get("timestamp"));
meetingJo.put("content",answer);
INSTANCE.stringRedisTemplate.opsForHash().put("group:nlp" + ":" + preWebsocketJo.getString("orderId"), "meeting", meetingJo.toString());
}
INSTANCE.redisTemplate.delete("gpt:websocket:1");
// 清除systemRole
systemRole = "";

}else {
// 添加上下文
INSTANCE.redisTemplate.opsForList().rightPush("group:nlp:null:-1", questions.get(questions.size() - 1));
INSTANCE.redisTemplate.opsForList().rightPush("group:nlp:null:-1", answer);
// 添加缓存
INSTANCE.stringRedisTemplate.opsForValue().set("group:websocket:content", answer);
}

// webSocket.close(3,"客户端主动断开链接");
//webSocket.close(1000,"客户端主动断开链接");

//webSocket.close(1000,"客户端主动断开链接");
}
if (this.stream && !StringUtils.isEmpty(curUserId)) {
Channel ch = ServerConfig.sessionMap.get(curUserId);
logger.info("当前ch:{}",ch.id().asLongText());
if (ch != null) {
List<String> ttsList = new ArrayList<>();
JSONObject jo = new JSONObject();
jo.put("action","chat");
jo.put("motion","idle");
jo.put("traceId",traceId);
//去除转义符
answerBuf = answerBuf.replaceAll("[\\r\\n]", "");
//去除引号
answerBuf = answerBuf.replaceAll("\"", "");
// 处理answer,如果包含"。",则将"。"之前的内容发送给前端
while(answerBuf.contains("。") || answerBuf.contains("?") || answerBuf.contains("!") ||
answerBuf.contains("?") || answerBuf.contains("!")) {
String[] temp = answerBuf.split("。|?|!|\\?|\\!");
ttsList.add(temp[0] + answerBuf.charAt(temp[0].length()));
answerBuf = answerBuf.substring(temp[0].length() + 1);
}
if (2 == responseData.getHeader().get("status").getAsInt() && CollectionUtils.isEmpty(ttsList)) {
jo.put("tts",answerBuf);
jo.put("status",2);
logger.info("发送到client:{},id:{},内容:{}",curUserId,ch.id().asLongText(),jo.toJSONString());
ch.writeAndFlush(new TextWebSocketFrame(jo.toJSONString()));
} else {
for (int i = 0;i <ttsList.size();i++) {
if (2 == responseData.getHeader().get("status").getAsInt() && i == ttsList.size() - 1) {
jo.put("status",2);
} else {
jo.put("status",1);
}
jo.put("tts",ttsList.get(i));
String str = jo.toJSONString();
logger.info("发送到client:{},id:{},内容:{}",curUserId,ch.id().asLongText(),jo.toJSONString());
ch.writeAndFlush(new TextWebSocketFrame(str));
}
}
}
}

} else {
// 添加缓存
INSTANCE.stringRedisTemplate.opsForValue().set("group:websocket:content", "-1");
System.out.println("返回结果错误:\n" + responseData.getHeader().get("code") + responseData.getHeader().get("message"));
LOCK.notifyAll();
} else {
// 添加缓存
INSTANCE.stringRedisTemplate.opsForValue().set("group:websocket:content", "-1");
// 判断流式则返回结束状态
if (stream == true) {
Channel ch = ServerConfig.sessionMap.get(curUserId);
if (ch != null) {
JSONObject jo = new JSONObject();
jo.put("action","chat");
jo.put("motion","idle");
jo.put("traceId",traceId);
jo.put("status",2);
jo.put("tts","抱歉,您的问题我无法解答。");
String str = jo.toJSONString();
logger.info("发送到client:{},id:{},内容:{}",curUserId,ch.id().asLongText(),jo.toJSONString());
ch.writeAndFlush(new TextWebSocketFrame(str));
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("返回结果错误:\n" + responseData.getHeader().get("code") + responseData.getHeader().get("message"));
LOCK.notifyAll();
}
} catch (Exception e) {
if (StringUtils.isNotEmpty(curUserId)) {
Channel ch = ServerConfig.sessionMap.get(curUserId);
JSONObject jo = new JSONObject();
jo.put("action","chat");
jo.put("motion","idle");
jo.put("traceId",traceId);
jo.put("status",2);
jo.put("tts","大模型出现异常,请稍后重试。");
String str = jo.toJSONString();
logger.info("发生异常client:{},内容:{}",curUserId,jo.toJSONString());
ch.writeAndFlush(new TextWebSocketFrame(str));
}
e.printStackTrace();
}
}



+ 31
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/ServerInitializer.java View File

@@ -0,0 +1,31 @@
package com.xueyi.nlt.netty.server;

import com.xueyi.nlt.netty.server.handler.ChatServerHandler;
import com.xueyi.nlt.netty.server.handler.HeartbeatHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

public class ServerInitializer extends ChannelInitializer<SocketChannel> {

@Override
protected void initChannel(SocketChannel ch) throws Exception{
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new ChunkedWriteHandler());
pipeline.addLast(new HttpObjectAggregator(1024*64));
pipeline.addLast(new WebSocketServerProtocolHandler("/chat"));
pipeline.addLast(new IdleStateHandler(60, 120, 180, TimeUnit.SECONDS));
pipeline.addLast(new HeartbeatHandler());
// 自定义handler,处理业务逻辑
pipeline.addLast(new ChatServerHandler());

}
}

+ 79
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/WebsocketServer.java View File

@@ -0,0 +1,79 @@
package com.xueyi.nlt.netty.server;

import com.xueyi.nlt.netty.client.codec.WsChannelInitializer;
import com.xueyi.nlt.netty.server.handler.ChatServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetSocketAddress;
import java.util.Date;

@Component
public class WebsocketServer {
private static final Logger log = LoggerFactory.getLogger(WebsocketServer.class);
private EventLoopGroup bossGroup;
private EventLoopGroup workGroup;

private void run() throws Exception {
log.info("启动netty服务端");

bossGroup = new NioEventLoopGroup();
workGroup = new NioEventLoopGroup();


try {
ServerBootstrap serverBootstrap = new ServerBootstrap();

serverBootstrap.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ServerInitializer());

// 设置监听端口
serverBootstrap.localAddress(new InetSocketAddress(9903));
// 启动服务器
ChannelFuture channelFuture = serverBootstrap.bind().sync();

log.info("Server started and listen on:{}",channelFuture.channel().localAddress());
// 对关闭通道进行监听
channelFuture.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}

/**
* 初始化服务器
*/
@PostConstruct()
public void init() {
new Thread(() -> {
try {
run();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}

@PreDestroy
public void destroy() throws InterruptedException {
if (bossGroup != null) {
bossGroup.shutdownGracefully().sync();
}
if (workGroup != null) {
workGroup.shutdownGracefully().sync();
}
}

}

+ 15
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/config/ServerConfig.java View File

@@ -0,0 +1,15 @@
package com.xueyi.nlt.netty.server.config;

import com.alibaba.fastjson2.JSONObject;
import com.xueyi.nlt.netty.client.WebSocketClient;
import io.netty.channel.Channel;

import java.util.concurrent.ConcurrentHashMap;

public class ServerConfig {

public static volatile ConcurrentHashMap<String, Channel> sessionMap = new ConcurrentHashMap<>();

public static volatile ConcurrentHashMap<String,Long> currentTraceMap = new ConcurrentHashMap<>();

}

+ 204
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/handler/ChatServerHandler.java View File

@@ -0,0 +1,204 @@
package com.xueyi.nlt.netty.server.handler;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xueyi.nlt.netty.server.config.ServerConfig;
import com.xueyi.nlt.nlt.template.FreeChatTemplate;
import com.xueyi.nlt.nlt.template.MovieChatTemplate;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.time.LocalDateTime;

@Component
public class ChatServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
// 添加log
private static final Logger log = LoggerFactory.getLogger(ChatServerHandler.class);

public static ChatServerHandler INSTANCE;

@Autowired
private FreeChatTemplate freeChatTemplate;

@Autowired
private MovieChatTemplate movieChatTemplate;

@PostConstruct
public void init() {
INSTANCE = this;
INSTANCE.freeChatTemplate = this.freeChatTemplate;
INSTANCE.movieChatTemplate = this.movieChatTemplate;
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception {
Channel channel = channelHandlerContext.channel();
// 判断textWebSocketFrame.text()是否为空,如果为空,则直接返回
if (StringUtils.isEmpty(textWebSocketFrame.text()) || StringUtils.isEmpty(textWebSocketFrame.text().trim()) ) {
channel.writeAndFlush(new TextWebSocketFrame("pong"));
return;
}
// 发送json字符串
String text = textWebSocketFrame.text();
JSONObject jsonObject = JSONObject.parseObject(text);
if (jsonObject.size() == 0) {
//心调检测
channel.writeAndFlush(new TextWebSocketFrame("pong"));
return;
}
// 获取到发送人的设备号
String devId = jsonObject.getString("devId");
// 获取到发送人的用户id
String msg = jsonObject.getString("msg");
synchronized (ServerConfig.class) {


if (!ServerConfig.sessionMap.containsKey(devId) ) {
// 说明是第一次登录上来连接,还没有开始聊天,将uid加到map中
register(devId, channel);
} else {
// 说明已经登录过了,判断当前channel与map中的channel是否一致,不一致则关闭之前的channel
update(devId, channel);
}
try {
sendMsg(devId, msg);
} catch (Exception e) {
JSONObject jo = new JSONObject();
jo.put("action","chat");
jo.put("motion","idle");
jo.put("traceId","");
jo.put("status",2);
jo.put("tts","大模型出现异常,请稍后重试。");
String str = jo.toJSONString();
log.info("发生异常client:{},内容:{}",devId,jo.toJSONString());
channel.writeAndFlush(new TextWebSocketFrame(str));
log.error("发送消息失败", e);
}
}

}

/**
* 第一次登录进来
*
* @param userId
* @param channel
*/
private void register(String userId, Channel channel) {
if (!ServerConfig.sessionMap.containsKey(userId)) { //没有指定的userId
ServerConfig.sessionMap.put(userId, channel);
// 将用户ID作为自定义属性加入到channel中,方便随时channel中获取用户ID
AttributeKey<String> key = AttributeKey.valueOf("userId");
channel.attr(key).setIfAbsent(userId);
}
}

/**
* 更新登录信息
*
* @param userId
* @param channel
*/
private void update(String userId, Channel channel) {
// 获取到之前的channel
Channel old_channel = ServerConfig.sessionMap.get(userId);
log.info("设备:{},之前的channel:{},新的channel:{}", userId, old_channel.id().asLongText(), channel.id().asLongText());
// 移除之前channel的attr属性
if (old_channel !=null && old_channel.hasAttr(AttributeKey.valueOf("userId"))) {
old_channel.attr(AttributeKey.valueOf("userId")).set(null);
}
// 更新sessionMap中的channel
ServerConfig.sessionMap.put(userId, channel);
// 将用户ID作为自定义属性加入到channel中,方便随时channel中获取用户ID
AttributeKey<String> key = AttributeKey.valueOf("userId");
channel.attr(key).setIfAbsent(userId);
}

/**
* 开发发送消息,进行聊天
*
* @param msg
* @param userId
*/
private void sendMsg(String userId, Object msg ) {
log.info("设备:{},收到消息:{}", userId,msg);
Channel channel1 = ServerConfig.sessionMap.get(userId);
if (channel1 != null) {
JSONObject result = INSTANCE.freeChatTemplate.handle(userId, msg.toString(),true);
// channel1.writeAndFlush(new TextWebSocketFrame("服务器时间" + LocalDateTime.now() + " " + "{\"action\":\"chat\",\"motion\":\"idle\",\"status\":1,\"tts\":\"是的,长津湖是一部2021年上映的中国电影,由陈凯歌、徐克和林超贤执导,吴京、易烊千玺等人主演。\"}"));
}
}

/**
* 一旦客户端连接上来,该方法被执行
*
* @param ctx
* @throws Exception
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
String remoteAddress = "";
// 获取客户端的IP地址
InetSocketAddress socketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
if (socketAddress != null) {
remoteAddress = socketAddress.getAddress().getHostAddress();
} else {
//有时候可能会出现获取客户端IP地址为空的情况,这可能是由于网络架构中存在多级代理(例如Nginx等)而导致的。这时候需要通过HTTP请求头中的X-Forwarded-For字段来获取客户端的IP地址。

}
log.info("handlerAdded 被调用:{},ip:{}" ,ctx.channel().id().asLongText(), remoteAddress);
}

/**
* 断开连接,需要移除用户
*
* @param ctx
* @throws Exception
*/
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
removeUserId(ctx);
}

/**
* 移除用户
*
* @param ctx
*/
private void removeUserId(ChannelHandlerContext ctx) {
Channel channel = ctx.channel();
AttributeKey<String> key = AttributeKey.valueOf("userId");
String userId = channel.attr(key).get();
if (userId == null) {
log.info("断开废弃连接,userId:{},channel:{}:", userId, channel.id().asLongText());
return;
}
if (ServerConfig.sessionMap.containsKey(userId)) {
ServerConfig.sessionMap.remove(userId);
log.info("用户下线,userId:{},channel:{}:", userId, channel.id().asLongText());
}

}

/**
* 处理移除,关闭通道
*
* @param ctx
* @param cause
* @throws Exception
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}

}

+ 32
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/netty/server/handler/HeartbeatHandler.java View File

@@ -0,0 +1,32 @@
package com.xueyi.nlt.netty.server.handler;

import com.xueyi.nlt.netty.server.config.ServerConfig;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

public class HeartbeatHandler extends ChannelInboundHandlerAdapter {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
//超时事件
if (evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) evt;
if (event.state() == IdleState.READER_IDLE){
//读空闲
System.out.println("读空闲");
// 关闭该通道
ctx.channel().close();
}else if (event.state() == IdleState.WRITER_IDLE){
//写空闲
System.out.println("写空闲");
}else if (event.state() == IdleState.ALL_IDLE){
//读写空闲
System.out.println("读写空闲");
}
}
super.userEventTriggered(ctx, evt);
}
}

+ 124
- 38
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/controller/DmIntentController.java View File

@@ -1,9 +1,6 @@
package com.xueyi.nlt.nlt.controller;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.MatchQuery;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@@ -12,6 +9,7 @@ import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.constant.digitalman.MessageConstants;
import com.xueyi.common.core.constant.digitalman.SkillConstants.SkillType;
import com.xueyi.common.core.context.SecurityContextHolder;
import com.xueyi.common.core.utils.DateUtil;
import com.xueyi.common.core.utils.core.IdUtil;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
@@ -23,7 +21,6 @@ import com.xueyi.common.security.annotation.Logical;
import com.xueyi.common.security.annotation.RequiresPermissions;
import com.xueyi.common.web.entity.controller.BaseController;
import com.xueyi.nlt.api.netty.domain.vo.DmWebSocketMessageVo;
import com.xueyi.nlt.api.nlt.domain.vo.*;
import com.xueyi.nlt.api.nlt.domain.vo.response.DmIntentResponse;
import com.xueyi.nlt.api.nlt.domain.vo.CoversationSessionVo;
import com.xueyi.nlt.api.nlt.domain.vo.DmIntentVo;
@@ -31,6 +28,7 @@ import com.xueyi.nlt.api.nlt.domain.vo.DmLandingLlmVo;
import com.xueyi.nlt.api.nlt.domain.vo.DmRecognitionVo;
import com.xueyi.nlt.api.nlt.domain.vo.KnowledgeVo;
import com.xueyi.nlt.api.nlt.domain.vo.TaskKnowledgeVo;
import com.xueyi.nlt.api.nlt.domain.vo.response.DmKnowledgeResponse;
import com.xueyi.nlt.api.nlt.feign.RemoteIntentService;
import com.xueyi.nlt.api.nlt.feign.RemoteLandingLlmService;
import com.xueyi.nlt.api.nlt.feign.RemoteQAService;
@@ -51,6 +49,8 @@ import com.xueyi.system.api.digitalmans.feign.RemoteDigitalmanService;
import com.xueyi.system.api.digitalmans.feign.RemoteManDeviceService;
import com.xueyi.system.api.digitalmans.feign.RemoteQuestionanswersService;
import com.xueyi.system.api.digitalmans.feign.RemoteSkillService;
import com.xueyi.system.api.interfaces.airport.domain.vo.PlaneMessageVo;
import com.xueyi.system.api.interfaces.airport.feign.RemotePlaneController;
import com.xueyi.system.api.model.Source;
import com.xueyi.system.api.organize.domain.dto.SysEnterpriseDto;
import com.xueyi.system.api.organize.feign.RemoteEnterpriseService;
@@ -59,6 +59,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@@ -69,16 +70,11 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.concurrent.CountDownLatch;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -120,7 +116,7 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt

@Autowired
private RemoteIntentService remoteIntentService;
@Autowired
private MeetingOrderTemplate meetingOrderTemplate;

@@ -161,6 +157,9 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt

@Autowired
private DmRegularMapper regularMapper;

@Autowired
private FlightMessageTemplate flightMessageTemplate;
/**
* 意图请求
列表
@@ -202,7 +201,9 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
@ResponseBody
public AjaxResult skillIntentApi(@RequestBody DmIntentVo intent) {
log.info("交互对象:{}", intent.toString());
redisTemplate.opsForValue().increment(("dashboard:server-chart:" + DateUtil.getDate()), 1);
redisTemplate.opsForValue().increment("dashboard:server", 1);
redisTemplate.opsForValue().increment(("dashboard:server-chart:" + DateUtil.getDate()), 1);
R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(intent.getDevId());
if (!manDeviceDtoR.isOk() || manDeviceDtoR.getData() == null) {
return AjaxResult.error("设备不存在或服务没有启动,请确认。");
@@ -230,6 +231,12 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
response.setSkillCode("33");
response.setH5(deliveryOrderTemplate.handle(intent.getDevId(),intent.getContent(), enterpriseId));
return AjaxResult.success(response);
case "flight":
response.setMsg("");
response.setSkillCode("34");
response.setH5(flightMessageTemplate.handle(intent.getDevId(),intent.getContent(), enterpriseId));
return AjaxResult.success(response);

}
}

@@ -296,7 +303,7 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
*/
@PostMapping("/api/searchQA")
@ResponseBody
public AjaxResult searchQA(@RequestBody DmIntentVo intent) {
public DmKnowledgeResponse searchQA(@RequestBody DmIntentVo intent) {
log.info("交互对象:{}",intent.toString());

R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(intent.getDevId());
@@ -306,7 +313,11 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
knowledgeVo.setTenantId(manDeviceDtoR.getData().getTId());
knowledgeVo.setQuestion(intent.getContent());
// return remoteQAService.query(manDeviceDtoR.getData().getManCode(),intent.getContent(),manDeviceDtoR.getData().getTId());
return remoteQAService.query(knowledgeVo);
R<DmKnowledgeResponse> dmKnowledgeResponseR = remoteQAService.query(knowledgeVo);
if (dmKnowledgeResponseR!= null && dmKnowledgeResponseR.getData() != null) {
return dmKnowledgeResponseR.getData();
}
return null;

}

@@ -317,15 +328,63 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
@ResponseBody
public AjaxResult searchQuestionAnswer(@RequestBody DmIntentVo intent) {
log.info("交互对象:{}",intent.toString());
redisTemplate.opsForValue().increment("dashboard:recognition", 1);
redisTemplate.opsForValue().increment("dashboard:server", 1);
R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(intent.getDevId());
if (manDeviceDtoR.isFail()) {
return AjaxResult.error("设备号未激活或服务异常");
}
Source source = SourceUtil.getSourceCache(manDeviceDtoR.getData().getStrategyId());
String enterpriseName = "";
R<SysEnterpriseDto> enterpriseDtoR = remoteEnterpriseService.getInfo(Long.valueOf(manDeviceDtoR.getData().getTId()));
if (enterpriseDtoR.isOk()) {
enterpriseName = enterpriseDtoR.getData().getName();
}
DmIntentResponse response = new DmIntentResponse();

//先调用意图
//根据技能调用知识库或大模型
CoversationSessionVo sessionObject = (CoversationSessionVo) redisTemplate2.opsForValue().get("group:device" + ":" + intent.getDevId() + ":" +"session");
if(!(sessionObject == null) && sessionObject.getCategory().equals("flight")) {
response.setMsg("");
response.setSkillCode("34");
response.setH5(flightMessageTemplate.handle(intent.getDevId(),intent.getContent()));
return AjaxResult.success(response);

}
response = doMatchRegular(intent);
if (StringUtils.isNotEmpty(response.getSkillCode())) {
if (SkillType.FLIGHT.getCode().equals(response.getSkillCode()) ) {
redisTemplate.opsForValue().increment("dashboard:flight", 1);
pushIntoDashboardRedis(enterpriseName, "查询航班信息", "skill");
response.setH5(flightMessageTemplate.handle(intent.getDevId(), intent.getContent()));
return AjaxResult.success(response);
}
}


// 调用知识库
// 调用知识库问答
response.setSkillCode("30");
DmKnowledgeResponse qaAjax = searchQA(intent);
String content = "";
if (qaAjax != null) {
log.info("知识库问答返回结果:{}",qaAjax.toString());
if (qaAjax.getTarget() == 1 && qaAjax.getAccurate() == 1) {
content = qaAjax.getResult().get(0).getKnowledgeLib();
pushIntoDashboardRedis(enterpriseName,content,"knowledge");
response.setH5(JSONObject.from(qaAjax));
return AjaxResult.success(response);
}
}

JSONObject joResult = new JSONObject();
joResult.put("msg","");
joResult.put("target",0);
DmLandingLlmVo vo = new DmLandingLlmVo();
vo.setCategory("bj_unicom");
vo.setCategory("airport");
vo.addDmLlm("user", intent.getContent());
JSONObject testJ = new JSONObject();
testJ.put("category","bj_unicom");
testJ.put("category","airport");
JSONArray ja1 = new JSONArray();
JSONObject jo = new JSONObject();
jo.put("role","user");
@@ -333,13 +392,31 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
ja1.add(jo);
testJ.put("messages",ja1);
JSONObject resultJson = remoteLandingLlmService.query(testJ);
JSONArray ja = resultJson.getJSONArray("data");

if (ja.size() > 0) {
joResult.put("msg",ja.getJSONObject(0).get("text"));
joResult.put("target",1);
log.info("北方大返回:{}",resultJson.toString());
if (resultJson.get("status").equals("success")) {
JSONArray ja = resultJson.getJSONArray("data");
if (ja.size() > 0) {
String text = ja.getJSONObject(0).getString("text");
response.setMsg(text);
// 判断text是否为纯数字
if (!text.matches("[0-9]+")) {
JSONObject joImage = new JSONObject();
joImage.put("msg",text);
// 非纯数字
if (ja.getJSONObject(0).containsKey("filename")) {
// TODO: 2023/9/27 合并知识到知识库
String libName = ja.getJSONObject(0).getString("filename").split("\\.")[0];
// 添加到知识数据库
}
if (ja.getJSONObject(0).containsKey("imageList") && ja.getJSONObject(0).getJSONArray("imageList").size() > 0) {
joImage.put("imageUrl",ja.getJSONObject(0).getJSONArray("imageList").getString(0));
}
response.setMsg("");
response.setH5(joImage);
}
}
}
return AjaxResult.success(joResult);
return AjaxResult.success(response);
}

/**
@@ -388,22 +465,22 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
// 调用知识库
// 调用知识库问答
response.setSkillCode("30");
AjaxResult qaAjax = searchQA(intent);
JSONObject qajson = qaAjax.toJson();
DmKnowledgeResponse qaAjax = searchQA(intent);
String content = "";
log.info("知识库问答返回结果:{}",qaAjax.toString());
if (qajson.containsKey("data") && qajson.getJSONObject("data").containsKey("result") && qajson.getJSONObject("data").size() > 0) {
content = qajson.getJSONObject("data").getJSONArray("result").getJSONObject(0).getString("knowledge_lib");
pushIntoDashboardRedis(enterpriseName,content,"knowledge");
response.setH5(JSONObject.from(qaAjax.get("data")));
return R.ok(response);
}
if (qajson.containsKey("data") && qajson.getJSONObject("data").getString("target").equals("0")) {
// 知识库没有答案,返回空
response.clear();
response.setMsg("");
if (qaAjax != null) {
log.info("知识库问答返回结果:{}",qaAjax.toString());
if (qaAjax.getTarget() == 1) {
content = qaAjax.getResult().get(0).getKnowledgeLib();
pushIntoDashboardRedis(enterpriseName,content,"knowledge");
response.setH5(JSONObject.from(qaAjax));
return R.ok(response);
}
else {
// 知识库没有答案,返回空
response.clear();
response.setMsg("");
}
}

}
}
else {
@@ -436,6 +513,9 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
redisTemplate.opsForValue().increment("dashboard:delivery", 1);
pushIntoDashboardRedis(enterpriseName, "寄快递", "skill");
}
}else if (SkillType.FLIGHT.getCode().equals(intent.getSkillCode()) ) {
redisTemplate.opsForValue().increment("dashboard:flight", 1);
pushIntoDashboardRedis(enterpriseName, "查询航班信息", "skill");
}
// 判断是否有权限
R<List<DmSkillDto>> skilllistInner = remoteskillService.skilllistInner(intent.getDevId(),"1",Long.parseLong(enterpriseId), source.getMaster(), SecurityConstants.INNER);
@@ -462,6 +542,9 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
// 做快递预约处理
response.setH5(deliveryOrderTemplate.handle(intent.getDevId(), intent.getContent(), Long.parseLong(SecurityContextHolder.getLocalMap().get("enterprise_id").toString())));
break;
case "34":
// 做查询航班信息处理
response.setH5(flightMessageTemplate.handle(intent.getDevId(), intent.getContent(), Long.parseLong(SecurityContextHolder.getLocalMap().get("enterprise_id").toString())));
default:
break;
}
@@ -730,18 +813,20 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
return matcher.find();
}

private DmIntentResponse doMatchRegular(DmIntentVo intent) {
private DmIntentResponse doMatchRegular(DmIntentVo intent){
DmIntentResponse response = new DmIntentResponse();

List <DmRegularPo> regularPos = regularMapper.selectList(null);


boolean flag = false;
for (DmRegularPo regularPo : regularPos) {
if (isMatchRegular(intent.getContent(), regularPo.getExpression())) {
response.setMsg(regularPo.getText());
response.setSkillCode(regularPo.getSkillCode());
response.setAction(regularPo.getAction());
response.setH5(regularPo.getJson());
flag = true;
break;
}
}
@@ -779,6 +864,7 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
return response;
}


interface Auth {
/** 系统 - 意图管理
管理 - 列表 */


+ 1
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/domain/LlmContext.java View File

@@ -13,6 +13,7 @@ import java.util.stream.Collectors;
@NoArgsConstructor
public class LlmContext implements Serializable {

private String devId;
private List<LlmContent> contentList;




+ 1
- 1
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/kafka/KafkaMessageConsumer.java View File

@@ -11,7 +11,7 @@ import java.io.IOException;
@Component
public class KafkaMessageConsumer {

@KafkaListener(groupId = "simpleGroup", topics = "es_info_log")
// @KafkaListener(groupId = "simpleGroup", topics = "es_info_log")
public void coumuser(@Payload String record, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) throws InterruptedException, IOException, IllegalAccessException {
System.out.println(record);
System.out.println(topic);


+ 1
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/service/ISysLlmService.java View File

@@ -8,4 +8,5 @@ import com.xueyi.nlt.nlt.domain.LlmResponse;
public interface ISysLlmService {

LlmResponse chat(LlmContext context, LlmParam param);
LlmResponse stream(LlmContext context, LlmParam param);
}

+ 8
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/service/impl/SparkServiceImpl.java View File

@@ -43,4 +43,12 @@ public class SparkServiceImpl implements ISysLlmService {
}

}

@Override
public LlmResponse stream(LlmContext context, LlmParam param) {
List<String> contentArr = context.getContentList().stream().map(LlmContent::getContent).collect(Collectors.toList());
webSocketClient.sendMsg(contentArr, true,context.getDevId());
LlmResponse response = new LlmResponse();
return response;
}
}

+ 166
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/template/FlightMessageTemplate.java View File

@@ -0,0 +1,166 @@
package com.xueyi.nlt.nlt.template;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xueyi.common.core.constant.digitalman.SkillConstants;
import com.xueyi.nlt.api.nlt.domain.vo.CoversationSessionVo;
import com.xueyi.system.api.interfaces.airport.domain.vo.PlaneMessageVo;
import com.xueyi.system.api.interfaces.airport.feign.RemotePlaneController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service("flight-message")
public class FlightMessageTemplate implements BaseTemplate{

private static final Logger log = LoggerFactory.getLogger(FlightMessageTemplate.class);

@Autowired
private RedisTemplate<Object,Object> objectRedisTemplate;

@Autowired
private RemotePlaneController remotePlaneController;


private void init(){
log.info("航信服务已启动。");
}
@Override
public JSONObject handle(String dev, String content) {
return handle(dev, content, 0L);
}

@Override
public JSONObject handle(String devId, String content, Long tenantId) {

CoversationSessionVo session = (CoversationSessionVo) objectRedisTemplate.opsForValue().get("group:device" + ":" + devId + ":" +"session");
boolean flag = true;
if (session == null) {
session = new CoversationSessionVo();
session.setCategory("flight");
JSONObject data = new JSONObject();
session.setFormat(new JSONObject());
session.getFormat().put("skillCode", SkillConstants.SkillType.FLIGHT.getCode());
session.getFormat().put("errorTime", 0);
flag = false;
}
JSONObject result;
content = content.replace("-", "").replace(" ", "").replace("$", "").toUpperCase();
Pattern pattern = Pattern.compile("([A-Z]{2}|\\d[A-Z]|[A-Z]\\d)\\d{4}");
Matcher matcher = pattern.matcher(content);
if(matcher.find()){
String fNum = matcher.group();
result = checkFlight(fNum, 0);
if(result.isEmpty()){
result = checkFlight(fNum, 1);
if(result.isEmpty()){
result = new JSONObject();
result.put("status", -1);
result.put("skillCode", "34");
session.getFormat().put("errorTime", session.getFormat().getInteger("errorTime") + 1);
}else{
session.getFormat().put("errorTime", 0);
}
}else{
session.getFormat().put("errorTime", 0);
}
}else{
if(flag){
result = new JSONObject();
result.put("status", -2);
result.put("skillCode", "34");
session.getFormat().put("errorTime", session.getFormat().getInteger("errorTime") + 1);
}else{
result = new JSONObject();
result.put("status", 0);
result.put("skillCode", "34");
}
}

if(session.getFormat().getInteger("errorTime") > 5){
objectRedisTemplate.delete("group:device" + ":" + devId + ":" +"session");
}else{
objectRedisTemplate.opsForValue().set("group:device" + ":" + devId + ":" +"session", session, 1, TimeUnit.MINUTES);
}
return result;
}

private JSONObject checkFlight(String fNum, Integer days) {
Long timestamp = System.currentTimeMillis();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String date = dateFormat.format(timestamp + days * 1000 * 60 * 60 * 24);
String singStr = date + fNum + timestamp;
String sign = DigestUtils.md5DigestAsHex(singStr.getBytes());
PlaneMessageVo planeMessageVo = new PlaneMessageVo();
planeMessageVo.setFNum(fNum);
planeMessageVo.setDate(date);
JSONObject result = new JSONObject();
JSONObject flightMessage = remotePlaneController.queryFlight(planeMessageVo, String.valueOf(timestamp), sign);
log.info(flightMessage.toString());
if (flightMessage.containsKey("reason") &&
flightMessage.getString("reason").equals("success")) {
JSONObject fullFlight = flightMessage.getJSONArray("result").getJSONObject(0);
SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dateNow = new Date(System.currentTimeMillis());
try{
if(dateNow.after(formatter.parse(fullFlight.getString("FlightDeptimePlanDate")))){
return new JSONObject();
}
} catch (ParseException e) {
log.error(e.toString());
return new JSONObject();
}

result.put("stopFlag", fullFlight.getInteger("StopFlag"));
result.put("flightNo", fullFlight.getString("FlightNo"));
result.put("flightCompany", fullFlight.getString("FlightCompany"));
JSONArray nowFlights = flightMessage.getJSONArray("result");
JSONArray flights = new JSONArray();
for (int i = 0; i < nowFlights.size(); i++) {
JSONObject nowFlight = nowFlights.getJSONObject(i);
if (nowFlight.getString("StopFlag").equals("0")) {
JSONObject newFlight = new JSONObject();
newFlight.put("Dep", nowFlight.getString("FlightDep"));
newFlight.put("Arr", nowFlight.getString("FlightArr"));
newFlight.put("DepTime", nowFlight.getString("FlightDeptimePlanDate"));
newFlight.put("ArrTime", nowFlight.getString("FlightArrtimePlanDate"));
flights.add(newFlight);
}
}
result.put("flights", flights);
List<String> transit = new ArrayList<>();
for (int i = 1; i < flights.size(); i++) {
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date begin = simpleDateFormat2.parse(flights.getJSONObject(i - 1).getString("ArrTime"));
Date end = simpleDateFormat2.parse(flights.getJSONObject(i).getString("DepTime"));
long minutes = (end.getTime() - begin.getTime()) / (1000 * 60);
if (minutes < 60) {
transit.add(String.format("%d分钟", (int) minutes));
} else {
transit.add(String.format("%dh%dm", minutes / 60, minutes % 60));
}
} catch (ParseException e) {
log.error(e.toString());
return new JSONObject();
}
}
result.put("transit", transit);
result.put("status", 1);
result.put("skillCode", "34");
}
return result;
}
}

+ 85
- 28
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/template/FreeChatTemplate.java View File

@@ -17,8 +17,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service("free-chat")
@@ -31,51 +34,105 @@ public class FreeChatTemplate implements BaseTemplate{
@Autowired
private RedisTemplate<String,String> redisTemplate;

private Map<String,String> correctWordsMap = new HashMap<>();

// 中航信领导来访临时对策
// bean初始化加载
@PostConstruct
public void init() {
//初始化纠错词库
correctWordsMap.put("中航讯","中航信");
}

@Override
public JSONObject handle(String devId, String content) {
Long operatorId = TerminalSecurityContextHolder.getOperatorId();
String redisKey = "group:nlp:" + SecurityContextHolder.getLocalMap().get("enterprise_id") + ":" + operatorId;
// 根据content内容调用模版并返回结果
// 通过redis获取数字人上下文信息
Long size = redisTemplate.opsForList().size(redisKey);
if (size > 8) {
redisTemplate.opsForList().leftPop(redisKey,2);
}
size = redisTemplate.opsForList().size(redisKey);
List<String> context = new ArrayList<>();
context.add("你是一位企业前台。你来自于缔智元公司。你的名字叫小智,你是一位数字员工。");
context.addAll(redisTemplate.opsForList().range(redisKey,size-6,size));

context.add(content);

//webSocketClient.sendMsg(context);
synchronized (WebSocketClient.LOCK) {
// 通过redis获取数字人上下文信息
Long size = redisTemplate.opsForList().size(redisKey);
if (size > 8) {
redisTemplate.opsForList().leftPop(redisKey,2);
}
size = redisTemplate.opsForList().size(redisKey);
List<String> context = new ArrayList<>();
context.add("你是缔智元公司的前台,你叫小智,你是一位数字人。");
context.addAll(redisTemplate.opsForList().range(redisKey,size-6,size));

LlmContext llmContext = LlmContext.parse(context,true);
LlmParam param = new LlmParam();
LlmResponse response = sysLlmService.chat(llmContext,param);
String result = response.getContent();
context.add(content);

// 处理数据
if (result.contains("我是科大讯飞")) {
result = "我是缔智元公司的数字人员工,我采用的是科大讯飞的星火大模型。";
}
//webSocketClient.sendMsg(context);

LlmContext llmContext = LlmContext.parse(context,true);
LlmParam param = new LlmParam();
LlmResponse response = sysLlmService.chat(llmContext,param);
String result = response.getContent();

if(!StringUtils.isEmpty(result)){
// 处理数据
if (result.contains("我是科大讯飞")) {
result = result.replaceAll("科大讯飞", "缔智元");
}
result = result.replaceAll("认知模型", "数字员工");
result = result.replaceAll("认知智能模型", "数字员工");
if (result.equals("-1")) {
result = "这个问题超出了我的能力,您可以提出更多关于公司相关问题。";
} else {
result = "这个问题超出了我无法回答,您可以提出更多关于电影相关问题。";
}

if(!StringUtils.isEmpty(result)){
redisTemplate.opsForList().rightPush(redisKey,content);
redisTemplate.opsForList().rightPush(redisKey,result);
}
JSONObject resultJson = new JSONObject();
resultJson.put("msg",result);
return resultJson;
}
JSONObject resultJson = new JSONObject();
resultJson.put("msg",result);
return resultJson;
}

public JSONObject handle(String dev, String content, boolean stream) {
Long operatorId = TerminalSecurityContextHolder.getOperatorId();
String redisKey = "group:nlp:" + SecurityContextHolder.getLocalMap().get("enterprise_id") + ":" + operatorId;
// 根据content内容调用模版并返回结果
synchronized (WebSocketClient.LOCK) {
// 通过redis获取数字人上下文信息
Long size = redisTemplate.opsForList().size(redisKey);
if (size > 8) {
redisTemplate.opsForList().leftPop(redisKey,2);
}
size = redisTemplate.opsForList().size(redisKey);
List<String> context = new ArrayList<>();
context.add("你是缔智元公司的前台,你叫小智,你是一位数字人,你们公司在北京,你的职能是负责做会议预定和访客预约。");
// 中航信领导来访临时对策
// 判断如果content包含correctWordsMap中的key,则替换为value
for (String key : correctWordsMap.keySet()) {
if (content.contains(key)) {
content = content.replaceAll(key, correctWordsMap.get(key));
}
}

//context.addAll(redisTemplate.opsForList().range(redisKey,size-2,size));
content = "请用简短的话回答下面的问题:" + content;
context.add(content);
//使用stream去除context列表中所有字符串中的引号
context = context.stream().map(s -> s.replaceAll("\"", "")).collect(java.util.stream.Collectors.toList());

//webSocketClient.sendMsg(context);

LlmContext llmContext = LlmContext.parse(context,true);
llmContext.setDevId(dev);
LlmParam param = new LlmParam();
LlmResponse response = sysLlmService.stream(llmContext,param);

JSONObject resultJson = new JSONObject();
resultJson.put("tts","让我想一想。");
resultJson.put("motion","idle");
resultJson.put("status","0");
resultJson.put("action","chat");
return resultJson;
}
}
@Override
public JSONObject handle(String dev, String content, Long tenantId) {
return null;
}
}
}

+ 34
- 14
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/template/MeetingOrderTemplate.java View File

@@ -85,7 +85,6 @@ public class MeetingOrderTemplate implements BaseTemplate {

private static final List<MeetingParamVo> MEETING_PARAMS = new ArrayList<>();

private static JSONObject MEETING_DURATION = new JSONObject();

private static List<String> MEETING_TOPIC = new ArrayList<>();

@@ -146,7 +145,6 @@ public class MeetingOrderTemplate implements BaseTemplate {
log.error("解析会议参数失败", e);
}
}
MEETING_DURATION = JSONObject.parseObject(nacosConfigManager.getConfigService().getConfig("meeting_duration_hour", "DEFAULT_GROUP", 5000));
String topics = nacosConfigManager.getConfigService().getConfig("meeting_topic", "DEFAULT_GROUP", 5000);
MEETING_TOPIC.addAll(List.of(topics.split(",")));
MEETING_CONFIRM = JSONObject.parseObject(nacosConfigManager.getConfigService().getConfig("meeting_confirm_cancel", "DEFAULT_GROUP", 5000));
@@ -188,7 +186,7 @@ public class MeetingOrderTemplate implements BaseTemplate {
// 更新session中的locationId与location
session.getFormat().put("location",roomsDto.getName());
session.getFormat().put("locationId",roomsDto.getId());
content = content.replace(roomsDto.getName(), "啊啊啊");
content = content.replace(roomsDto.getName(), "@@@");
break;
}
for(int i = 0;i<10;i++){
@@ -200,7 +198,7 @@ public class MeetingOrderTemplate implements BaseTemplate {
// 更新session中的locationId与location
session.getFormat().put("location",roomsDto.getName());
session.getFormat().put("locationId",roomsDto.getId());
content = content.replace(roomsDto.getName(), "啊啊啊");
content = content.replace(roomsDto.getName(), "@@@");
break;
}
}
@@ -211,14 +209,28 @@ public class MeetingOrderTemplate implements BaseTemplate {
session = dateSession;
}
//判断是否击中持续时间的正则
for(String key:MEETING_DURATION.keySet()){
if(content.contains(key)){
session.getFormat().put("duration", MEETING_DURATION.getIntValue(key));
content = content.replace(key, "啊啊啊");
break;
String[] chinesenumber2 = {"一","两","三","四","五","六","七","八","九","十"};
for(int i=0;i<10;i++){
content = content.replaceAll(chinesenumber2[i],number[i]);
}
Pattern pattern = Pattern.compile("(\\d)+(\\.)?(\\d)*(个)?(半)?小时");
Matcher matcher = pattern.matcher(content);
if(matcher.find()){
content = content.replace(matcher.group(), "@@@");
String matchedNumber =matcher.group().replace("个", "").replace("小时", "").replace("半", ".5");
Double tempNumber = Double.parseDouble(matchedNumber) * 60;
if(String.valueOf(tempNumber).endsWith(".0")){
session.getFormat().put("duration", Integer.parseInt(String.valueOf(Double.parseDouble(matchedNumber) * 60).replace(".0", "")));
}
}else{
if(content.contains("半小时") || content.contains("半个小时")){
session.getFormat().put("duration", 30);
content = content.replace("半小时", "@@@").replace("半个小时", "@@@");
}
}


//判断是否集中会议主题正则
for(String topic: MEETING_TOPIC){
if(content.contains(topic)){
session.getFormat().put("meetingIntent", topic);
@@ -227,14 +239,22 @@ public class MeetingOrderTemplate implements BaseTemplate {
}
//判断会议室是否冲突,如果冲突则回传有冲突
JSONObject checkObject = session.getFormat();
if(checkObject.containsKey("date")){
LocalDateTime date = LocalDateTime.parse(session.getFormat().getString("date") + " 00:00:00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime now = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
if(now.isAfter(date)){
session.getFormat().put("conflict", 1);
} else{
session.getFormat().remove("conflict");
}
}
if (checkObject.containsKey("date") && checkObject.containsKey("start_time") && checkObject.containsKey("location") && checkObject.containsKey("duration")) {
JSONObject ret= remoteMeetingService.queryExistOrder(checkObject.getLong("locationId"), checkObject.getString("date"), checkObject.getString("start_time"),checkObject.getInteger("duration"),tenantId,source.getMaster(), SecurityConstants.INNER);
if (StringUtils.isNotEmpty(ret.getString("err"))) {
// 会议室冲突,删除时间
session.getFormat().put("conflict",1);
}
else{
session.getFormat().put("conflict",0);
// 会议室冲突,返回冲突类型
session.getFormat().put("conflict", 2);
}else{
session.getFormat().put("conflict", 0);
}
}



+ 26
- 0
xueyi-modules/xueyi-system/pom.xml View File

@@ -131,12 +131,38 @@
<version>8.3.3</version>
</dependency>

<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>

<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>11.0</version>
</dependency>


<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.3</version>
</dependency>


<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>4.6.0</version>
</dependency>


</dependencies>

<build>
<finalName>${project.artifactId}</finalName>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>


+ 73
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/authority/controller/SysLoginController.java View File

@@ -1,6 +1,7 @@
package com.xueyi.system.authority.controller;

import com.xueyi.common.cache.utils.SourceUtil;
import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.context.SecurityContextHolder;
import com.xueyi.common.core.utils.core.CollUtil;
import com.xueyi.common.core.utils.core.ObjectUtil;
@@ -14,6 +15,10 @@ import com.xueyi.system.api.model.Source;
import com.xueyi.system.api.organize.domain.dto.SysEnterpriseDto;
import com.xueyi.system.api.organize.domain.dto.SysUserDto;
import com.xueyi.system.authority.service.ISysLoginService;
import com.xueyi.tenant.api.tenant.domain.po.TeTenantPo;
import com.xueyi.tenant.api.tenant.feign.RemoteTenantService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -33,6 +38,7 @@ import java.util.stream.Collectors;
@RestController
@RequestMapping("/login")
public class SysLoginController extends BasisController {
private final Logger log = LoggerFactory.getLogger(SysLoginController.class);

@Autowired
ISysLoginService loginService;
@@ -92,4 +98,71 @@ public class SysLoginController extends BasisController {
loginUser.setRouteURL(routeMap);
return R.ok(loginUser);
}


@Autowired
RemoteTenantService tenantService;

/**
* 获取登录信息 | 内部调用, 手机号登录
*/
@InnerAuth
@GetMapping("/inner/loginByPhone/{phone}")
public R<LoginUser> getLoginInfoByMobile(@PathVariable("phone") String phone) {
log.info("获取登录信息 | 内部调用, 手机号登录 | phone: {}", phone);
R<TeTenantPo> po = tenantService.tenant(phone, SecurityConstants.INNER);
log.info("获取登录信息 | 内部调用, 手机号登录 | po:{}, {}, {}", po.getMsg(),po.getCode(),po.isFail());
if (po.getData() == null)
return R.fail("指定手机号不存在记录");
SysEnterpriseDto enterprise = loginService.loginByEnterpriseName(po.getData().getName());
// 不存在直接返回空数据 | 与网络调用错误区分
if (ObjectUtil.isNull(enterprise))
return R.ok(null, "企业账号不存在");
SecurityContextHolder.setEnterpriseId(enterprise.getId().toString());
SecurityContextHolder.setIsLessor(enterprise.getIsLessor());
Source source = SourceUtil.getSourceCache(enterprise.getStrategyId());
// 不存在直接返回空数据 | 与网络调用错误区分
if (ObjectUtil.isNull(source))
return R.ok(null, "数据源不存在");
SecurityContextHolder.setSourceName(source.getMaster());

LoginUser loginUser = new LoginUser();
loginUser.setEnterprise(enterprise);
loginUser.setEnterpriseId(enterprise.getId());
loginUser.setEnterpriseName(enterprise.getName());
loginUser.setIsLessor(enterprise.getIsLessor());
loginUser.setSource(source);
loginUser.setSourceName(source.getMaster());
SysUserDto user = loginService.loginByStaff(phone);

if (ObjectUtil.isNull(user))
return R.ok(null, "用户账号不存在");
SecurityContextHolder.setUserType(user.getUserType());
// 角色权限标识
Set<String> roles = loginService.getRolePermission(user.getRoles(), user.getUserType());
// 角色Id集合
Set<Long> roleIds = CollUtil.isNotEmpty(user.getRoles())
? user.getRoles().stream().map(SysRoleDto::getId).collect(Collectors.toSet())
: new HashSet<>();

// 菜单权限标识
Set<String> permissions = loginService.getMenuPermission(roleIds, user.getUserType());

// 权限范围
DataScope dataScope = loginService.getDataScope(user.getRoles(), user);
dataScope.setRoles(roles);
dataScope.setRoleIds(roleIds);
dataScope.setPermissions(permissions);

// 路由路径集合
Map<String, String> routeMap = loginService.getMenuRouteMap(roleIds, user.getUserType());

loginUser.setUser(user);
loginUser.setUserId(user.getId());
loginUser.setUserName(user.getUserName());
loginUser.setUserType(user.getUserType());
loginUser.setScope(dataScope);
loginUser.setRouteURL(routeMap);
return R.ok(loginUser);
}
}

+ 2
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/authority/service/ISysLoginService.java View File

@@ -68,4 +68,6 @@ public interface ISysLoginService {
* @return 路由路径集合
*/
Map<String, String> getMenuRouteMap(Set<Long> roleIds, String userType);

SysUserDto loginByStaff(String phone);
}

+ 32
- 1
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/authority/service/impl/SysLoginServiceImpl.java View File

@@ -1,17 +1,28 @@
package com.xueyi.system.authority.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xueyi.common.core.constant.basic.SqlConstants;
import com.xueyi.common.core.constant.system.AuthorityConstants;
import com.xueyi.common.core.utils.core.StrUtil;
import com.xueyi.common.security.utils.SecurityUtils;
import com.xueyi.common.web.entity.domain.SqlField;
import com.xueyi.system.api.authority.domain.dto.SysRoleDto;
import com.xueyi.system.api.model.DataScope;
import com.xueyi.system.api.organize.domain.dto.SysDeptDto;
import com.xueyi.system.api.organize.domain.dto.SysEnterpriseDto;
import com.xueyi.system.api.organize.domain.dto.SysPostDto;
import com.xueyi.system.api.organize.domain.dto.SysUserDto;
import com.xueyi.system.api.organize.domain.model.SysUserConverter;
import com.xueyi.system.api.staff.domain.po.DmStaffPo;
import com.xueyi.system.authority.service.ISysLoginService;
import com.xueyi.system.authority.service.ISysMenuService;
import com.xueyi.system.organize.service.*;
import com.xueyi.system.organize.mapper.SysUserMapper;
import com.xueyi.system.organize.service.ISysDeptService;
import com.xueyi.system.organize.service.ISysEnterpriseService;
import com.xueyi.system.organize.service.ISysOrganizeService;
import com.xueyi.system.organize.service.ISysPostService;
import com.xueyi.system.organize.service.ISysUserService;
import com.xueyi.system.staff.mapper.DmStaffMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@@ -44,6 +55,9 @@ public class SysLoginServiceImpl implements ISysLoginService {
@Autowired
ISysMenuService menuService;

@Autowired
DmStaffMapper dmStaffMapper;

@Autowired
private ISysOrganizeService organizeService;

@@ -220,4 +234,21 @@ public class SysLoginServiceImpl implements ISysLoginService {
? menuService.getRouteMap()
: menuService.getRouteMap(roleIds);
}

@Autowired
SysUserMapper userMapper;

@Autowired
SysUserConverter sysUserConverter;

@Override
public SysUserDto loginByStaff(String phone) {
DmStaffPo po = dmStaffMapper.selectOne(Wrappers.<DmStaffPo>query().lambda().eq(DmStaffPo::getPhone, phone).last(SqlConstants.LIMIT_ONE));
if (po == null) {
return null;
}
SqlField field = new SqlField(SqlConstants.OperateType.EQ, "tenant_id", po.getTenantId());
SysUserDto dto = sysUserConverter.mapperDto(userMapper.selectByField(field)) ;
return dto;
}
}

+ 4
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/common/service/IDmHolidayService.java View File

@@ -4,7 +4,11 @@ import com.xueyi.common.web.entity.service.IBaseService;
import com.xueyi.system.common.domain.dto.DmHolidayDto;
import com.xueyi.system.common.domain.query.DmHolidayQuery;

import java.util.Date;

public interface IDmHolidayService extends IBaseService<DmHolidayQuery, DmHolidayDto> {

DmHolidayDto getTodayHoliday();

DmHolidayDto isHoliday(Date date);
}

+ 8
- 1
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/common/service/impl/IDmHolidayServiceImpl.java View File

@@ -1,5 +1,6 @@
package com.xueyi.system.common.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.xueyi.common.web.entity.service.impl.BaseServiceImpl;
import com.xueyi.system.common.domain.dto.DmHolidayDto;
import com.xueyi.system.common.domain.query.DmHolidayQuery;
@@ -8,14 +9,20 @@ import com.xueyi.system.common.service.IDmHolidayService;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Date;

@Service
public class IDmHolidayServiceImpl extends BaseServiceImpl<DmHolidayQuery, DmHolidayDto, IDmHolidayManager> implements IDmHolidayService {

@Override
public DmHolidayDto getTodayHoliday() {
return isHoliday(new Date());
}

@Override
public DmHolidayDto isHoliday(Date date) {
DmHolidayQuery query = new DmHolidayQuery();
query.setDate(LocalDate.now());
query.setDate(LocalDateTimeUtil.of(date).toLocalDate());
DmHolidayDto dto = baseManager.selectTodayHoliday(query);
if (dto != null) {
return dto;


+ 10
- 2
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/device/controller/DmDeviceTenantMergeController.java View File

@@ -6,6 +6,7 @@ import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.common.core.web.validate.V_A;
import com.xueyi.common.core.web.validate.V_E;
import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.common.datasource.annotation.Master;
import com.xueyi.common.log.annotation.Log;
import com.xueyi.common.log.enums.BusinessType;
@@ -14,7 +15,6 @@ import com.xueyi.common.web.annotation.TenantIgnore;
import com.xueyi.common.web.entity.controller.BaseController;
import com.xueyi.system.api.device.domain.dto.DmDeviceTenantMergeDto;
import com.xueyi.system.api.device.domain.po.DmDeviceTenantMergePo;
import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo;
import com.xueyi.system.api.digitalmans.domain.dto.DmManDeviceDto;
import com.xueyi.system.api.digitalmans.domain.po.DmManDevicePo;
import com.xueyi.system.api.model.Source;
@@ -29,7 +29,15 @@ import com.xueyi.system.organize.service.ISysEnterpriseService;
import com.xueyi.tenant.api.source.domain.po.TeSourcePo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.Serializable;
import java.util.List;


+ 31
- 1
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/controller/DmDigitalmanController.java View File

@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xueyi.common.cache.utils.DictUtil;
import com.xueyi.common.cache.utils.SourceUtil;
import com.xueyi.common.core.constant.basic.BaseConstants;
import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.constant.basic.SqlConstants;
@@ -12,6 +13,7 @@ import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.common.core.web.validate.V_A;
import com.xueyi.common.core.web.validate.V_E;
import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.common.log.annotation.Log;
import com.xueyi.common.log.enums.BusinessType;
import com.xueyi.common.security.annotation.InnerAuth;
@@ -20,7 +22,6 @@ import com.xueyi.common.web.entity.controller.BaseController;
import com.xueyi.common.web.utils.DateUtils;
import com.xueyi.file.api.feign.RemoteFileService;
import com.xueyi.message.api.transfer.feign.RemoteTransferService;
import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo;
import com.xueyi.system.api.device.feign.RemoteDeviceTenantMergeService;
import com.xueyi.system.api.dict.domain.dto.SysDictDataDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmDigitalmanWorktimeDto;
@@ -29,8 +30,10 @@ import com.xueyi.system.api.digitalmans.domain.dto.DmSyncDigitalmanDto;
import com.xueyi.system.api.digitalmans.domain.po.DmDigitalmanExtPo;
import com.xueyi.system.api.digitalmans.domain.po.DmManDevicePo;
import com.xueyi.system.api.digitalmans.feign.RemoteDigitalmanService;
import com.xueyi.system.api.model.Source;
import com.xueyi.system.api.sms.domain.vo.DingdingReqEntity;
import com.xueyi.system.api.sms.feign.RemoteDingdingService;
import com.xueyi.system.api.staff.feign.RemoteStaffService;
import com.xueyi.system.device.service.impl.DmDeviceTenantMergeServiceImpl;
import com.xueyi.system.digitalmans.domain.dto.DmDigitalmanDto;
import com.xueyi.system.digitalmans.domain.dto.DmDigitalmanExtDto;
@@ -50,6 +53,8 @@ import com.xueyi.system.emcs.domain.dto.RedisBaseDto;
import com.xueyi.system.emcs.mapper.DmDeviceLogFileMapper;
import com.xueyi.system.emcs.mapper.DmExceptionLogMapper;
import com.xueyi.system.emcs.service.BaseRedisListDataCache;
import com.xueyi.tenant.api.tenant.domain.dto.TeTenantDto;
import com.xueyi.tenant.api.tenant.feign.RemoteTenantService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -461,4 +466,29 @@ public class DmDigitalmanController extends BaseController<DmDigitalmanQuery, Dm
log.info("删除文件返回结果:{}", r.getData());
return R.ok();
}

@Autowired
private RemoteTenantService tenantService;


@Autowired
private RemoteStaffService staffService;

@GetMapping("/api/delRecognizedRecords")
public AjaxResult delRecognizedRecords (@RequestParam(value = "day") Integer day){

R<List<TeTenantDto>> listR = tenantService.tenantList();
if (listR.isFail()) {
System.out.println("租户列表获取失败");
return null;
}
List<TeTenantDto> res = listR.getData();
TeTenantDto teTenantDto = res.get(0);
if (teTenantDto != null) {
Source source = SourceUtil.getSourceCache(teTenantDto.getStrategyId());
staffService.delRecognizedRecordsImg(day,teTenantDto.getId(), source.getMaster(), SecurityConstants.INNER);
}

return AjaxResult.success();
}
}

+ 0
- 9
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/controller/DmManDeviceController.java View File

@@ -38,7 +38,6 @@ import com.xueyi.system.emcs.domain.dto.DmExceptionLogDto;
import com.xueyi.system.emcs.domain.query.DmExceptionLogQuery;
import com.xueyi.system.emcs.service.IDmExceptionLogService;
import com.xueyi.system.organize.service.ISysEnterpriseService;
import com.xueyi.system.pass.mapper.DmRecognizedRecordsMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -376,14 +375,6 @@ public class DmManDeviceController extends BaseController<DmManDeviceQuery, DmMa
return AjaxResult.success(baseService.restartDevice(type,devId));
}


@Autowired
private DmRecognizedRecordsMapper mapper;
@GetMapping("/delRecognizedRecords")
public AjaxResult delRecognizedRecords (@RequestParam(value = "day") Integer day){
mapper.del(day);
return AjaxResult.success();
}
/**
* 获取数字人设备管理选择框列表
*/


+ 11
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/controller/DmQuestionsController.java View File

@@ -1,15 +1,19 @@
package com.xueyi.system.digitalmans.controller;

import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.common.core.web.validate.V_A;
import com.xueyi.common.core.web.validate.V_E;
import com.xueyi.common.log.annotation.Log;
import com.xueyi.common.log.enums.BusinessType;
import com.xueyi.common.security.annotation.InnerAuth;
import com.xueyi.common.security.annotation.Logical;
import com.xueyi.common.security.annotation.RequiresPermissions;
import com.xueyi.common.security.utils.SecurityUtils;
import com.xueyi.common.web.entity.controller.BaseController;
import com.xueyi.nlt.api.nlt.domain.vo.TaskKnowledgeVo;
import com.xueyi.system.api.digitalmans.domain.vo.DmBatchQuestionsVo;
import com.xueyi.system.api.digitalmans.domain.vo.DmTipVo;
import com.xueyi.system.digitalmans.domain.dto.DmQuestionsDto;
import com.xueyi.system.digitalmans.domain.query.DmQuestionsQuery;
import com.xueyi.system.digitalmans.service.IDmQuestionsService;
@@ -39,6 +43,13 @@ public class DmQuestionsController extends BaseController<DmQuestionsQuery, DmQu
return "企业知识库问题" ;
}

@InnerAuth
@GetMapping("/inner/tipList")
@Log(title = "数字人知识库问题管理", businessType = BusinessType.OTHER)
@ResponseBody
public R<List<DmTipVo>> tipList() {
return R.ok(baseService.tipList());
}
/**
* 查询企业知识库问题列表
*/


+ 6
- 2
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/controller/api/DmMenuApiController.java View File

@@ -3,14 +3,18 @@ package com.xueyi.system.digitalmans.controller.api;
import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo;
import com.xueyi.common.core.web.vo.DeviceTenantSourceMergeVo;
import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto;
import com.xueyi.system.api.digitalmans.feign.RemoteModelService;
import com.xueyi.system.resource.controller.api.BaseApiController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;



+ 15
- 15
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/manager/impl/DmModelManager.java View File

@@ -1,24 +1,27 @@
package com.xueyi.system.digitalmans.manager.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xueyi.common.core.constant.basic.OperateConstants;
import com.xueyi.common.web.entity.domain.SlaveRelation;
import com.xueyi.common.web.entity.manager.impl.BaseManagerImpl;
import com.xueyi.system.api.digitalmans.domain.dto.DmH5MenuDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmModelDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto;
import com.xueyi.system.api.digitalmans.domain.po.*;
import com.xueyi.system.digitalmans.controller.DmQAndAController;
import com.xueyi.system.api.digitalmans.domain.po.DmDigitalmanPo;
import com.xueyi.system.api.digitalmans.domain.po.DmH5MenuPo;
import com.xueyi.system.api.digitalmans.domain.po.DmModelIconPo;
import com.xueyi.system.api.digitalmans.domain.po.DmModelPo;
import com.xueyi.system.api.digitalmans.domain.po.DmScreenIconPo;
import com.xueyi.system.api.resource.domain.po.DmResourcesPo;
import com.xueyi.system.digitalmans.domain.dto.DmModelUploadDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmModelDto;
import com.xueyi.system.api.digitalmans.domain.merge.DmModelIconMerge;
import com.xueyi.system.digitalmans.domain.model.DmModelConverter;
import com.xueyi.system.digitalmans.domain.model.DmScreenIconConverter;
import com.xueyi.system.digitalmans.domain.po.DmManIconPo;
import com.xueyi.system.digitalmans.domain.query.DmModelQuery;
import com.xueyi.system.digitalmans.domain.model.DmModelConverter;
import com.xueyi.system.digitalmans.mapper.*;
import com.xueyi.common.web.entity.manager.impl.BaseManagerImpl;
import com.xueyi.system.digitalmans.manager.IDmModelManager;
import com.xueyi.system.api.resource.domain.po.DmResourcesPo;
import com.xueyi.system.digitalmans.mapper.merge.DmModelIconMergeMapper;
import com.xueyi.system.digitalmans.mapper.DmDigitalmanMapper;
import com.xueyi.system.digitalmans.mapper.DmH5MenuMapper;
import com.xueyi.system.digitalmans.mapper.DmManIconMapper;
import com.xueyi.system.digitalmans.mapper.DmModelIconMapper;
import com.xueyi.system.digitalmans.mapper.DmModelMapper;
import com.xueyi.system.digitalmans.mapper.DmScreenIconMapper;
import com.xueyi.system.resource.domain.po.DmBackgroundPo;
import com.xueyi.system.resource.domain.po.DmScreenOffPo;
import com.xueyi.system.resource.mapper.DmBackgroundMapper;
@@ -35,8 +38,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.xueyi.system.api.digitalmans.domain.merge.MergeGroup.Model_DmModelIcon_GROUP;


/**
* 模型管理 数据封装层处理
@@ -74,7 +75,6 @@ public class DmModelManager extends BaseManagerImpl<DmModelQuery, DmModelDto, Dm
@Autowired
DmH5MenuMapper h5MenuMapper;


@Autowired
DmScreenIconConverter screenIconConverter;



+ 4
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/service/IDmQuestionsService.java View File

@@ -1,13 +1,17 @@
package com.xueyi.system.digitalmans.service;

import com.xueyi.system.api.digitalmans.domain.vo.DmTipVo;
import com.xueyi.system.digitalmans.domain.query.DmQuestionsQuery;
import com.xueyi.system.digitalmans.domain.dto.DmQuestionsDto;
import com.xueyi.common.web.entity.service.IBaseService;

import java.util.List;

/**
* 企业知识库问题管理 服务层
*
* @author yinruoxi
*/
public interface IDmQuestionsService extends IBaseService<DmQuestionsQuery, DmQuestionsDto> {
List<DmTipVo> tipList();
}

+ 32
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/digitalmans/service/impl/DmQuestionsServiceImpl.java View File

@@ -1,9 +1,13 @@
package com.xueyi.system.digitalmans.service.impl;

import com.xueyi.system.api.digitalmans.domain.vo.DmTipVo;
import com.xueyi.system.api.organize.domain.dto.SysUserDto;
import com.xueyi.system.api.organize.domain.query.SysUserQuery;
import com.xueyi.system.digitalmans.domain.dto.DmQAndADto;
import com.xueyi.system.digitalmans.domain.dto.DmQuestionsDto;
import com.xueyi.system.digitalmans.domain.query.DmQAndAQuery;
import com.xueyi.system.digitalmans.domain.query.DmQuestionsQuery;
import com.xueyi.system.digitalmans.manager.IDmQAndAManager;
import com.xueyi.system.digitalmans.service.IDmQuestionsService;
import com.xueyi.system.digitalmans.manager.IDmQuestionsManager;
import com.xueyi.common.web.entity.service.impl.BaseServiceImpl;
@@ -11,6 +15,8 @@ import com.xueyi.system.organize.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
@@ -23,6 +29,9 @@ public class DmQuestionsServiceImpl extends BaseServiceImpl<DmQuestionsQuery, Dm

@Autowired
private ISysUserService iSysUserService;

@Autowired
private IDmQAndAManager iDmQAndAManager;
/**
* 查询企业知识库问题对象列表 | 数据权限
*
@@ -46,4 +55,27 @@ public class DmQuestionsServiceImpl extends BaseServiceImpl<DmQuestionsQuery, Dm
return questionsDtos;
}

@Override
public List<DmTipVo> tipList() {
// 获取所有知识库所有列表
List<DmQuestionsDto> knowledgeList = baseManager.selectList(new DmQuestionsQuery());
// 遍历知识库,获取对应QA结果,存入DmTipVo列表中
List<DmTipVo> dmTipVos = new ArrayList<>();
knowledgeList.forEach(knowledge -> {
DmQAndAQuery query = new DmQAndAQuery();
query.setKnowledgeId(knowledge.getId());
List<DmQAndADto> qAndADtos = iDmQAndAManager.selectList(query);
qAndADtos.forEach(qAndADto -> {
DmTipVo dmTipVo = new DmTipVo();
dmTipVo.setName(qAndADto.getName());
dmTipVo.setId(qAndADto.getId());
dmTipVo.setType(0);
dmTipVos.add(dmTipVo);
});
});
// 将dmTipVos列表打乱数组排序
Collections.shuffle(dmTipVos);

return dmTipVos;
}
}

+ 42
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/interfaces/airport/bean/FlightsQueryReq.java View File

@@ -0,0 +1,42 @@
package com.xueyi.system.interfaces.airport.bean;

import com.xueyi.common.web.entity.domain.BaseReq;
import lombok.Data;

import javax.validation.constraints.NotNull;

/**
* @author yk
* @description
* @date 2023-12-06 11:45
*/
@Data
public class FlightsQueryReq extends BaseReq {

@NotNull(message = "Valid校验:出发城市startCity不能为空!")
private String startCity;

@NotNull(message = "Valid校验:抵达城市endCity不能为空!")
private String endCity;

@NotNull(message = "Valid校验:时间startDate不能为空!")
private String date;




@Override
public String toString() {
return "PlaneQueryReq{" +
"START_CITY='" + startCity + '\'' +
", END_CITY='" + endCity + '\'' +
", START_DATE='" + date + '\'' +
'}';
}

public String toQueryString() {
return "START_CITY=" + startCity +
"&END_CITY=" + endCity +
"&START_DATE=" + date;
}
}

+ 33
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/interfaces/airport/bean/PlaneQueryReq.java View File

@@ -0,0 +1,33 @@
package com.xueyi.system.interfaces.airport.bean;

import com.xueyi.common.web.entity.domain.BaseReq;
import lombok.Data;

import javax.validation.constraints.NotNull;

/**
* @author yk
* @description
* @date 2023-12-06 11:45
*/
@Data
public class PlaneQueryReq extends BaseReq {

@NotNull(message = "Valid校验:航班号fNum不能为空!")
private String fNum;

@NotNull(message = "Valid校验:时间date不能为空!")
private String date;

@Override
public String toString() {
return "PlaneQueryReq{" +
"fNum='" + fNum + '\'' +
", date='" + date + '\'' +
'}';
}

public String toQueryString() {
return "fnum=" + this.fNum + "&date=" + this.date;
}
}

+ 127
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/interfaces/airport/controller/PlaneController.java View File

@@ -0,0 +1,127 @@
package com.xueyi.system.interfaces.airport.controller;

import com.alibaba.fastjson2.JSONObject;
import com.xueyi.common.redis.utils.RedisUtil;
import com.xueyi.common.web.controller.BaseApiController;
import com.xueyi.common.web.response.MyResponse;
import com.xueyi.system.interfaces.airport.bean.FlightsQueryReq;
import com.xueyi.system.interfaces.airport.bean.PlaneQueryReq;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.IOException;

/**
* @author yk
* @description
* @date 2023-12-04 14:57
*/
@RestController
@RequestMapping("/plane/api")
public class PlaneController extends BaseApiController {
private final Logger logger = LoggerFactory.getLogger(PlaneController.class);

@Value("${notification.airport.flight.juhe.key}")
private String key;
@Value("${notification.airport.flight.juhe.url}")
private String juHeUrl;
@Value("${notification.airport.flight.icredit.app-code}")
private String icreditCode;
@Value("${notification.airport.flight.icredit.flights-url}")
private String icreditUrl;

@RequestMapping("/query-flight")
public JSONObject query (@Valid @RequestBody PlaneQueryReq req, HttpServletRequest httpServletRequest) {
String sign = httpServletRequest.getHeader("sign");
String ts = httpServletRequest.getHeader("ts");
MyResponse resp = super.checkSign(req, sign, ts);
if (resp.getStatus() != 200) {
return resp.toJSON();
}

logger.info("查询航班信息:{}", req);
String dateStr = req.getDate().replaceAll("-","");
String redisKey = "dgman:airport:flight:"+req.getFNum()+":" + dateStr;
if (RedisUtil.existed(redisKey)){
return JSONObject.parseObject(RedisUtil.getVal(redisKey).toString());
}

OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
logger.info("请求参数:{}", "key="+key+"&"+req.toQueryString());
okhttp3.RequestBody body = okhttp3.RequestBody.Companion.create("key="+key+"&"+req.toQueryString(), mediaType);
Request request = new Request.Builder()
.url(juHeUrl)
.method("POST", body)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
String result = response.body().string();
logger.info("查询航班信息结果:{}", result);
RedisUtil.setVal(redisKey,result,60*60*24);

return JSONObject.parseObject(result);
}

} catch (IOException e) {
throw new RuntimeException(e);
}
return new JSONObject();
}

@RequestMapping("/flight-list")
public JSONObject flightList (@Valid @RequestBody FlightsQueryReq req, HttpServletRequest httpServletRequest) {
String sign = httpServletRequest.getHeader("sign");
String ts = httpServletRequest.getHeader("ts");
MyResponse resp = super.checkSign(req, sign, ts);
if (resp.getStatus() != 200) {
return resp.toJSON();
}

logger.info("查询航班列表信息:{}", req);
String dateStr = req.getDate().replaceAll("-","");
String redisKey = "dgman:airport:flight:"+req.getEndCity()+":" + dateStr;
if (RedisUtil.existed(redisKey)){
return JSONObject.parseObject(RedisUtil.getVal(redisKey).toString());
}

req.setDate(req.getDate().replaceAll("-",""));

OkHttpClient client = new OkHttpClient().newBuilder()
.build();
Request request = new Request.Builder()
.url(icreditUrl+"?"+req.toQueryString())
.get()
.addHeader("Authorization", "APPCODE "+icreditCode)
.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
.build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
String result = response.body().string();
logger.info("查询航班列表结果:{}", result);
RedisUtil.setVal(redisKey,result,60*60*24);
return JSONObject.parseObject(result);
}

} catch (IOException e) {
throw new RuntimeException(e);
}
return new JSONObject();
}


}

+ 31
- 0
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/interfaces/airport/controller/VideoTalkController.java View File

@@ -0,0 +1,31 @@
package com.xueyi.system.interfaces.airport.controller;

import com.xueyi.system.interfaces.airport.lib.VideoTalkZegoServerAssistant;
import com.xueyi.system.interfaces.airport.lib.VideoTalkZegoServerAssistant.TokenInfo;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @author yk
* @description
* @date 2023-12-04 14:57
*/
@RestController
@RequestMapping("/videoTalk/api")
public class VideoTalkController {

@RequestMapping("/genToken/{userId}")
public TokenInfo genToken (@PathVariable("userId") String userId) {
long appId = 1648563584L; // 由即构提供
String secretKey = "1568a55020c0585e4b6c257fc13c8adc"; // 由即构提供
int effectiveTimeInSeconds = 300; // 有效时间,单位:秒

String payload = "{\"room_id\":\"demo\"}"; // 填入自定义的payload值,如room_id。 非必输,不传则payload赋值null。
VideoTalkZegoServerAssistant.VERBOSE = true; // 正式运行时,最好置为 false
TokenInfo token = VideoTalkZegoServerAssistant.generateToken04(appId, userId, secretKey, effectiveTimeInSeconds, payload);
return token;
}


}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save