feat(): 修改动态多数据源,完成故障报警和故障码功能

baize
baize 2024-06-24 17:13:10 +08:00
parent 42ede316cb
commit f33be9fbcc
78 changed files with 2187 additions and 308 deletions

View File

@ -20,4 +20,7 @@ public class ServiceNameConstants {
* serviceid
*/
public static final String FILE_SERVICE = "muyu-file";
// public static final String SYSTEM_BUSINESS = "muyu-business";
public static final String DATASOURCE_SERVICE = "muyu-net-working";
}

View File

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.muyu</groupId>
<artifactId>muyu-common</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>muyu-common-saas</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<description>
SaaS多数据源模块
</description>
<dependencies>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>muyu-common-core</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.20</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>muyu-common-security</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,87 +0,0 @@
package com.muyu.saas.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.muyu.common.core.utils.SpringUtils;
import com.muyu.saas.domain.model.DataSourceInfo;
import com.muyu.saas.domain.model.EnterPriseInfo;
import com.muyu.saas.factory.DruidDataSourceFactory;
import com.muyu.saas.role.DynamicDataSource;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* ManyDataSource
*
* @author DeKangLiu
* Date 2024/6/3 20:01
*/
@Component
@Log4j2
@AllArgsConstructor
public class ManyDataSource {
@PostConstruct
public void init(){
new Thread(()->{
try {
Thread.sleep(10000);
} catch (InterruptedException ignored) {}
DruidDataSourceFactory druidDataSourceFactory= SpringUtils.getBean(DruidDataSourceFactory.class);
DynamicDataSource dynamicDataSource= SpringUtils.getBean(DynamicDataSource.class);
EnterPriseInfo enterPriseInfo = EnterPriseInfo.builder()
.entCode("liu_45")
.ip("192.168.116.129")
.port(3351)
.build();
DataSourceInfo dataSourceInfo = DataSourceInfo.hostAndPortBuild(enterPriseInfo.getEntCode(), enterPriseInfo.getIp(), enterPriseInfo.getPort());
DruidDataSource druidDataSource = druidDataSourceFactory.create(dataSourceInfo);
dynamicDataSource.put(dataSourceInfo.getKey(), druidDataSource);
}).start();
}
private List<EnterPriseInfo> dataSourceInfoList(){
List<EnterPriseInfo> list = new ArrayList<>();
list.add(
EnterPriseInfo.builder()
.entCode("liu_44")
.ip("192.168.116.129")
.port(3350)
.build()
);
return list;
}
@Bean
@Primary
public DynamicDataSource dynamicDataSource(DruidDataSourceFactory druidDataSourceFactory) {
//企业列表 企业CODE 端口 ip
Map<Object, Object> dataSourceMap = new HashMap<>();
dataSourceInfoList()
.stream()
.map(enterPriseInfo -> DataSourceInfo.hostAndPortBuild(enterPriseInfo.getEntCode(), enterPriseInfo.getIp(),enterPriseInfo.getPort()))
.forEach(dataSourceInfo -> {
dataSourceMap.put(dataSourceInfo.getKey(), druidDataSourceFactory.create(dataSourceInfo));
});
//设置动态数据源
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
dynamicDataSource.setTargetDataSources(dataSourceMap);
//将数据源信息备份在defineTargetDataSources中
dynamicDataSource.setDefineTargetDataSources(dataSourceMap);
return dynamicDataSource;
}
}

View File

@ -1,25 +0,0 @@
package com.muyu.saas.domain.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* EnterPriseInfo
*
* @author DeKangLiu
* Date 2024/6/4 08:53
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EnterPriseInfo {
private String entCode;
private String ip;
private Integer port;
}

View File

@ -1,26 +0,0 @@
package com.muyu.saas.exception;
import com.muyu.common.core.exception.ServiceException;
/**
* SaaS SaaSException
*
* @author DeKangLiu
* Date 2024/6/4 18:45
*/
public class SaaSException extends ServiceException {
public SaaSException(String message, Integer code) {
super(message, code);
}
public SaaSException(String message) {
super(message);
}
public SaaSException() {
super();
}
}

View File

@ -1,54 +0,0 @@
package com.muyu.saas.interceptor;
import com.muyu.common.core.utils.ServletUtils;
import com.muyu.common.core.utils.SpringUtils;
import com.muyu.saas.contents.SaaSConstant;
import com.muyu.saas.exception.SaaSException;
import com.muyu.saas.holder.DynamicDataSourceHolder;
import com.muyu.saas.role.DynamicDataSource;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* SaaS SaaSInterceptor
*
* @author DeKangLiu
* Date 2024/6/4 14:39
*/
public class SaaSInterceptor implements AsyncHandlerInterceptor {
/**
*
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)){
return true;
}
String SaasKey = ServletUtils.getHeader(request, SaaSConstant.SAAS_KEY);
if (SaasKey==null){
throw new SaaSException("SaaS非法访问");
} else {
DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
if (!dynamicDataSource.hashKye(SaasKey)){
throw new SaaSException("SaaS非法访问");
}
}
DynamicDataSourceHolder.setDynamicDataSourceKey(SaasKey);
return true;
}
/**
*
*/
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
DynamicDataSourceHolder.removeDynamicDataSourceKey();
}
}

View File

@ -1,31 +0,0 @@
package com.muyu.saas.interceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
*
*
* @author muyu
*/
public class WebMvcSaaSConfig implements WebMvcConfigurer {
/**
*
*/
public static final String[] excludeUrls = {"/login", "/logout", "/refresh"};
@Override
public void addInterceptors (InterceptorRegistry registry) {
registry.addInterceptor(getHeaderInterceptor())
.addPathPatterns("/**")
.excludePathPatterns(excludeUrls)
.order(-10);
}
/**
*
*/
public SaaSInterceptor getHeaderInterceptor () {
return new SaaSInterceptor();
}
}

View File

@ -1,4 +0,0 @@
com.muyu.saas.interceptor.WebMvcSaaSConfig
com.muyu.saas.factory.DruidDataSourceFactory
com.muyu.saas.datasource.ManyDataSource
com.muyu.saas.domain.model.EnterPriseInfo

View File

@ -1,9 +1,9 @@
package com.muyu.system.remote;
package com.muyu.common.system.remote;
import com.muyu.common.core.constant.ServiceNameConstants;
import com.muyu.common.core.domain.Result;
import com.muyu.common.system.domain.SysDept;
import com.muyu.system.remote.factory.RemoteSysDeptFactory;
import com.muyu.common.system.remote.factory.RemoteSysDeptFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;

View File

@ -1,10 +1,9 @@
package com.muyu.system.remote;
package com.muyu.common.system.remote;
import com.muyu.common.core.constant.ServiceNameConstants;
import com.muyu.common.core.domain.Result;
import com.muyu.common.security.annotation.RequiresPermissions;
import com.muyu.common.system.domain.SysUser;
import com.muyu.system.remote.factory.RemoteSysUserFactory;
import com.muyu.common.system.remote.factory.RemoteSysUserFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
@ -28,7 +27,6 @@ public interface RemoteSysUserService {
* @param user
* @return Result
*/
@RequiresPermissions("system:user:add")
@PostMapping
Result add(@Validated @RequestBody SysUser user);
}

View File

@ -1,8 +1,8 @@
package com.muyu.system.remote.factory;
package com.muyu.common.system.remote.factory;
import com.muyu.common.core.domain.Result;
import com.muyu.common.system.domain.SysDept;
import com.muyu.system.remote.RemoteSysDeptService;
import com.muyu.common.system.remote.RemoteSysDeptService;
import lombok.extern.log4j.Log4j2;
import org.springframework.cloud.openfeign.FallbackFactory;

View File

@ -1,8 +1,8 @@
package com.muyu.system.remote.factory;
package com.muyu.common.system.remote.factory;
import com.muyu.common.core.domain.Result;
import com.muyu.common.system.domain.SysUser;
import com.muyu.system.remote.RemoteSysUserService;
import com.muyu.common.system.remote.RemoteSysUserService;
import org.springframework.cloud.openfeign.FallbackFactory;
/**

View File

@ -1,3 +1,5 @@
com.muyu.common.system.remote.factory.RemoteUserFallbackFactory
com.muyu.common.system.remote.factory.RemoteLogFallbackFactory
com.muyu.common.system.remote.factory.RemoteFileFallbackFactory
com.muyu.common.system.remote.factory.RemoteSysDeptFactory
com.muyu.common.system.remote.factory.RemoteSysUserFactory

View File

@ -18,7 +18,6 @@
<module>muyu-common-datascope</module>
<module>muyu-common-datasource</module>
<module>muyu-common-system</module>
<module>muyu-common-saas</module>
</modules>
<artifactId>muyu-common</artifactId>

View File

@ -0,0 +1,52 @@
package com.muyu.customer.business.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.muyu.common.core.annotation.Excel;
import com.muyu.common.core.web.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* DataSource
*
* @author DeKangLiu
* Date 2024/6/22 22:56
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName("datasource")
public class DataSource extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(value = "id",type = IdType.AUTO)
@ApiModelProperty(name = "主键", value = "主键")
private Long id;
/** 数据源key */
@Excel(name = "数据源key")
@ApiModelProperty(name = "数据源key", value = "数据源key")
private String enterpriseCode;
/** 数据源端口 */
@Excel(name = "数据源端口")
@ApiModelProperty(name = "数据源端口", value = "数据源端口")
private Integer port;
/** 数据源ip */
@Excel(name = "数据源ip")
@ApiModelProperty(name = "数据源ip", value = "数据源ip")
private String ip;
}

View File

@ -0,0 +1,94 @@
package com.muyu.customer.business.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.muyu.customer.business.domain.req.FaultCodeEditReq;
import com.muyu.customer.business.domain.req.FaultCodeQueryReq;
import com.muyu.customer.business.domain.req.FaultCodeSaveReq;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.experimental.SuperBuilder;
import io.swagger.annotations.*;
import com.muyu.common.core.annotation.Excel;
import com.muyu.common.core.web.domain.BaseEntity;
/**
* fault_code
*
* @author chx
* @date 2024-06-20
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@TableName("fault_code")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "FaultCode", description = "车辆故障码")
public class FaultCode extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(value = "id",type = IdType.AUTO)
@ApiModelProperty(name = "主键", value = "主键")
private Long id;
/** 故障码 */
@Excel(name = "故障码")
@ApiModelProperty(name = "故障码", value = "故障码")
private String faultCode;
/** 故障标签 */
@Excel(name = "故障标签")
@ApiModelProperty(name = "故障标签", value = "故障标签")
private String faultLabel;
/** 故障位 */
@Excel(name = "故障位")
@ApiModelProperty(name = "故障位", value = "故障位")
private Long faultBit;
/** 故障值 */
@Excel(name = "故障值")
@ApiModelProperty(name = "故障值", value = "故障值")
private Long faultValue;
/**
*
*/
public static FaultCode queryBuild( FaultCodeQueryReq faultCodeQueryReq){
return FaultCode.builder()
.faultCode(faultCodeQueryReq.getFaultCode())
.build();
}
/**
*
*/
public static FaultCode saveBuild(FaultCodeSaveReq faultCodeSaveReq){
return FaultCode.builder()
.faultCode(faultCodeSaveReq.getFaultCode())
.faultLabel(faultCodeSaveReq.getFaultLabel())
.faultBit(faultCodeSaveReq.getFaultBit())
.faultValue(faultCodeSaveReq.getFaultValue())
.build();
}
/**
*
*/
public static FaultCode editBuild(Long id, FaultCodeEditReq faultCodeEditReq){
return FaultCode.builder()
.id(id)
.faultCode(faultCodeEditReq.getFaultCode())
.faultLabel(faultCodeEditReq.getFaultLabel())
.faultBit(faultCodeEditReq.getFaultBit())
.faultValue(faultCodeEditReq.getFaultValue())
.build();
}
}

View File

@ -0,0 +1,113 @@
package com.muyu.customer.business.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.muyu.customer.business.domain.req.FaultRecordEditReq;
import com.muyu.customer.business.domain.req.FaultRecordQueryReq;
import com.muyu.customer.business.domain.req.FaultRecordSaveReq;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.experimental.SuperBuilder;
import io.swagger.annotations.*;
import com.muyu.common.core.annotation.Excel;
import com.muyu.common.core.web.domain.BaseEntity;
/**
* fault_record
*
* @author chx
* @date 2024-06-20
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@TableName("fault_record")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "FaultRecord", description = "故障记录")
public class FaultRecord extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(value = "id",type = IdType.AUTO)
@ApiModelProperty(name = "主键", value = "主键")
private Long id;
/** 故障码 */
@Excel(name = "故障码")
@ApiModelProperty(name = "故障码", value = "故障码")
private String faultCode;
/** 车辆vin */
@Excel(name = "车辆vin")
@ApiModelProperty(name = "车辆vin", value = "车辆vin")
private String vin;
/** 故障开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "故障开始时间", width = 30, dateFormat = "yyyy-MM-dd")
@ApiModelProperty(name = "故障开始时间", value = "故障开始时间")
private Date startTime;
/** 故障结束时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "故障结束时间", width = 30, dateFormat = "yyyy-MM-dd")
@ApiModelProperty(name = "故障结束时间", value = "故障结束时间")
private Date endTime;
/** 故障级别 */
@Excel(name = "故障级别")
@ApiModelProperty(name = "故障级别", value = "故障级别")
private String faultLevel;
/** 故障是否处理 */
@Excel(name = "故障是否处理")
@ApiModelProperty(name = "故障是否处理", value = "故障是否处理")
private String faultHandle;
/**
*
*/
public static FaultRecord queryBuild( FaultRecordQueryReq faultRecordQueryReq){
return FaultRecord.builder()
.faultCode(faultRecordQueryReq.getFaultCode())
.vin(faultRecordQueryReq.getVin())
.build();
}
/**
*
*/
public static FaultRecord saveBuild(FaultRecordSaveReq faultRecordSaveReq){
return FaultRecord.builder()
.faultCode(faultRecordSaveReq.getFaultCode())
.vin(faultRecordSaveReq.getVin())
.startTime(faultRecordSaveReq.getStartTime())
.endTime(faultRecordSaveReq.getEndTime())
.faultLevel(faultRecordSaveReq.getFaultLevel())
.faultHandle(faultRecordSaveReq.getFaultHandle())
.build();
}
/**
*
*/
public static FaultRecord editBuild(Long id, FaultRecordEditReq faultRecordEditReq){
return FaultRecord.builder()
.id(id)
.faultCode(faultRecordEditReq.getFaultCode())
.vin(faultRecordEditReq.getVin())
.startTime(faultRecordEditReq.getStartTime())
.endTime(faultRecordEditReq.getEndTime())
.faultLevel(faultRecordEditReq.getFaultLevel())
.faultHandle(faultRecordEditReq.getFaultHandle())
.build();
}
}

View File

@ -0,0 +1,42 @@
package com.muyu.customer.business.domain.req;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.experimental.SuperBuilder;
import io.swagger.annotations.*;
import com.muyu.common.core.web.domain.BaseEntity;
/**
* fault_code
*
* @author chx
* @date 2024-06-20
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "FaultCodeEditReq", description = "车辆故障码")
public class FaultCodeEditReq extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 故障码 */
@ApiModelProperty(name = "故障码", value = "故障码")
private String faultCode;
/** 故障标签 */
@ApiModelProperty(name = "故障标签", value = "故障标签")
private String faultLabel;
/** 故障位 */
@ApiModelProperty(name = "故障位", value = "故障位")
private Long faultBit;
/** 故障值 */
@ApiModelProperty(name = "故障值", value = "故障值")
private Long faultValue;
}

View File

@ -0,0 +1,30 @@
package com.muyu.customer.business.domain.req;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.experimental.SuperBuilder;
import io.swagger.annotations.*;
import com.muyu.common.core.web.domain.BaseEntity;
/**
* fault_code
*
* @author chx
* @date 2024-06-20
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "FaultCodeQueryReq", description = "车辆故障码")
public class FaultCodeQueryReq extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 故障码 */
@ApiModelProperty(name = "故障码", value = "故障码")
private String faultCode;
}

View File

@ -0,0 +1,51 @@
package com.muyu.customer.business.domain.req;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.experimental.SuperBuilder;
import io.swagger.annotations.*;
import com.muyu.common.core.web.domain.BaseEntity;
/**
* fault_code
*
* @author chx
* @date 2024-06-20
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "FaultCodeSaveReq", description = "车辆故障码")
public class FaultCodeSaveReq extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 主键 */
@ApiModelProperty(name = "主键", value = "主键")
private Long id;
/** 故障码 */
@ApiModelProperty(name = "故障码", value = "故障码")
private String faultCode;
/** 故障标签 */
@ApiModelProperty(name = "故障标签", value = "故障标签")
private String faultLabel;
/** 故障位 */
@ApiModelProperty(name = "故障位", value = "故障位")
private Long faultBit;
/** 故障值 */
@ApiModelProperty(name = "故障值", value = "故障值")
private Long faultValue;
}

View File

@ -0,0 +1,54 @@
package com.muyu.customer.business.domain.req;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.experimental.SuperBuilder;
import io.swagger.annotations.*;
import com.muyu.common.core.web.domain.BaseEntity;
/**
* fault_record
*
* @author chx
* @date 2024-06-20
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "FaultRecordEditReq", description = "故障记录")
public class FaultRecordEditReq extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 故障码 */
@ApiModelProperty(name = "故障码", value = "故障码")
private String faultCode;
/** 车辆vin */
@ApiModelProperty(name = "车辆vin", value = "车辆vin")
private String vin;
/** 故障开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(name = "故障开始时间", value = "故障开始时间")
private Date startTime;
/** 故障结束时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(name = "故障结束时间", value = "故障结束时间")
private Date endTime;
/** 故障级别 */
@ApiModelProperty(name = "故障级别", value = "故障级别")
private String faultLevel;
/** 故障是否处理 */
@ApiModelProperty(name = "故障是否处理", value = "故障是否处理")
private String faultHandle;
}

View File

@ -0,0 +1,36 @@
package com.muyu.customer.business.domain.req;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.experimental.SuperBuilder;
import io.swagger.annotations.*;
import com.muyu.common.core.web.domain.BaseEntity;
/**
* fault_record
*
* @author chx
* @date 2024-06-20
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "FaultRecordQueryReq", description = "故障记录")
public class FaultRecordQueryReq extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 故障码 */
@ApiModelProperty(name = "故障码", value = "故障码")
private String faultCode;
/** 车辆vin */
@ApiModelProperty(name = "车辆vin", value = "车辆vin")
private String vin;
}

View File

@ -0,0 +1,65 @@
package com.muyu.customer.business.domain.req;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.experimental.SuperBuilder;
import io.swagger.annotations.*;
import com.muyu.common.core.web.domain.BaseEntity;
/**
* fault_record
*
* @author chx
* @date 2024-06-20
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "FaultRecordSaveReq", description = "故障记录")
public class FaultRecordSaveReq extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 主键 */
@ApiModelProperty(name = "主键", value = "主键")
private Long id;
/** 故障码 */
@ApiModelProperty(name = "故障码", value = "故障码")
private String faultCode;
/** 车辆vin */
@ApiModelProperty(name = "车辆vin", value = "车辆vin")
private String vin;
/** 故障开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(name = "故障开始时间", value = "故障开始时间")
private Date startTime;
/** 故障结束时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(name = "故障结束时间", value = "故障结束时间")
private Date endTime;
/** 故障级别 */
@ApiModelProperty(name = "故障级别", value = "故障级别")
private String faultLevel;
/** 故障是否处理 */
@ApiModelProperty(name = "故障是否处理", value = "故障是否处理")
private String faultHandle;
}

View File

@ -16,5 +16,17 @@
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>muyu-common-core</artifactId>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>muyu-net-working-common</artifactId>
<version>3.6.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,40 @@
//package com.muyu.customer.business.domain;
//
//import com.muyu.common.core.annotation.Excel;
//import com.muyu.common.core.web.domain.BaseEntity;
//import lombok.AllArgsConstructor;
//import lombok.Data;
//import lombok.EqualsAndHashCode;
//import lombok.NoArgsConstructor;
//import lombok.experimental.SuperBuilder;
//
///**
// * 多数据源对象 EnterpriseInfo
// *
// * @author DeKangLiu
// * Date 2024/6/22 20:37
// */
//@Data
//@SuperBuilder
//@NoArgsConstructor
//@AllArgsConstructor
//@EqualsAndHashCode(callSuper = true)
////@TableName("entinfo")
//public class EnterPriseInfo extends BaseEntity {
// private static final long serialVersionUID = 1L;
//
// /** 数据源key */
// @Excel(name = "数据源key")
// private String entCode;
//
// /** 数据源ip */
// @Excel(name = "数据源ip")
// private String ip;
//
// /** 数据源端口 */
// @Excel(name = "数据源端口")
// private Integer port;
//
// /** 数据源ID */
// private Long id;
//}

View File

@ -0,0 +1,24 @@
//package com.muyu.customer.business.remote;
//
//import com.muyu.common.core.constant.ServiceNameConstants;
//import com.muyu.customer.business.remote.factory.RemoteBusinessFallbackFactory;
//import org.springframework.cloud.openfeign.FeignClient;
//import org.springframework.web.bind.annotation.GetMapping;
//import com.muyu.net.working.domain.DataSource;
//import java.util.List;
//
///**
// * 用户服务 RemoteBusinessService
// *
// * @author DeKangLiu
// * Date 2024/6/22 20:39
// */
//@FeignClient(
// contextId = "remoteBusinessService",
// value = ServiceNameConstants.SYSTEM_BUSINESS,
// fallbackFactory = RemoteBusinessFallbackFactory.class
//)
//public interface RemoteBusinessService {
// @GetMapping("/datasource/listAll")
// public List<DataSource> listAll();
//}

View File

@ -0,0 +1,35 @@
//package com.muyu.customer.business.remote.factory;
//
//import com.muyu.customer.business.remote.RemoteBusinessService;
//import com.muyu.net.working.domain.DataSource;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.cloud.openfeign.FallbackFactory;
//import org.springframework.stereotype.Component;
//
//import java.util.List;
//
///**
// * 熔断器 RemoteBusinessFallbackFactory
// *
// * @author DeKangLiu
// * Date 2024/6/22 20:41
// */
//@Component
//public class RemoteBusinessFallbackFactory implements FallbackFactory<RemoteBusinessService> {
// private static final Logger log = LoggerFactory.getLogger(RemoteBusinessFallbackFactory.class);
//
// @Override
// public RemoteBusinessService create (Throwable throwable) {
// log.error("用户服务调用失败:{}", throwable.getMessage());
// return new RemoteBusinessService() {
// /**
// * 获取所有企业信息
// */
// @Override
// public List<DataSource> listAll() {
// return null;
// }
// };
// }
//}

View File

@ -72,6 +72,11 @@
<groupId>com.muyu</groupId>
<artifactId>muyu-common-datascope</artifactId>
</dependency>
<!-- rabbitmq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- MuYu Common Log -->
<dependency>
@ -84,10 +89,28 @@
<groupId>com.muyu</groupId>
<artifactId>muyu-common-swagger</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.muyu</groupId>-->
<!-- <artifactId>muyu-customer-business-remote</artifactId>-->
<!-- <version>3.6.3</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>muyu-common-saas</artifactId>
<artifactId>muyu-net-working-common</artifactId>
<version>3.6.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>muyu-net-working-remote</artifactId>
<version>3.6.3</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -18,8 +18,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableCustomConfig
@EnableCustomSwagger2
@EnableMyFeignClients
@SpringBootApplication
//@EnableScheduling
@SpringBootApplication(exclude = {DynamicDataSourceAutoConfiguration.class, DataSourceAutoConfiguration.class })
public class MuYuCustomerBusinessApplication {
public static void main (String[] args) {
SpringApplication.run(MuYuCustomerBusinessApplication.class, args);

View File

@ -0,0 +1,48 @@
package com.muyu.customer.business.config;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
*
*/
@Component
public class ConfirmCallbackConfig implements RabbitTemplate.ConfirmCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* @PostContructspringspring
* @PostConstruct bean
* @PreDestory bean
*/
@PostConstruct
public void init() {
rabbitTemplate.setConfirmCallback(this);
}
/**
*
*
* @param correlationData
* @param ack
* @param cause
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack) {
// 消息投递到 broker 的状态true表示成功
System.out.println("消息发送成功!");
} else {
// 发送异常
System.out.println("发送异常原因 = " + cause);
// TODO 可以将消息 内容 以及 失败的原因 记录到 日志表中
}
}
}

View File

@ -0,0 +1,53 @@
package com.muyu.customer.business.config;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* RabbitAdminRabbitMQJavaRabbitMQRabbitMQ
*/
@Configuration
public class RabbitAdminConfig {
@Value("${spring.rabbitmq.host}")
private String host;
@Value("${spring.rabbitmq.username}")
private String username;
@Value("${spring.rabbitmq.password}")
private String password;
@Value("${spring.rabbitmq.virtualhost}")
private String virtualhost;
/**
* RabbitMQ
* @return
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(host);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualhost);
// 配置发送确认回调时次配置必须配置否则即使在RabbitTemplate配置了ConfirmCallback也不会生效
connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
connectionFactory.setPublisherReturns(true);
return connectionFactory;
}
/**
* RabbitAdmin
* @param connectionFactory
* @return
*/
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
}
}

View File

@ -0,0 +1,15 @@
package com.muyu.customer.business.config;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitmqConfig {
// 消息转换配置
@Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}

View File

@ -0,0 +1,34 @@
package com.muyu.customer.business.config;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* returnedMessage
*/
@Component
public class ReturnCallbackConfig implements RabbitTemplate.ReturnsCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct // @PostContruct是spring框架的注解在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法也可以理解为在spring容器初始化的时候执
public void init() {
rabbitTemplate.setReturnsCallback(this);
}
/**
*
* @param returnedMessage the returned message and metadata.
*/
@Override
public void returnedMessage(ReturnedMessage returnedMessage) {
System.out.println("消息" + returnedMessage.getMessage().toString() + "被交换机" + returnedMessage.getExchange() + "回退!"
+ "退回原因为:" + returnedMessage.getReplyText());
// 回退了所有的信息,可做补偿机制 记录到 数据库
}
}

View File

@ -0,0 +1,114 @@
package com.muyu.customer.business.consumer;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.customer.business.domain.FaultRecord;
import com.muyu.customer.business.saas.holder.DynamicDataSourceHolder;
import com.muyu.customer.business.service.FaultRecordService;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* rabbitMQ Task
*
* @author DeKangLiu
* Date 2024/6/20 22:33
*/
@Component
@Log4j2
public class RabbitConsumer {
@Autowired
private FaultRecordService faultRecordService;
@Autowired
private StringRedisTemplate redisTemplate;
@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "error"),
exchange = @Exchange(name = "carnet_fault_event", type = ExchangeTypes.DIRECT))})
public void consumptionStartMessage(Message message, Channel channel) {
try {
// DynamicDataSourceHolder.setDynamicDataSourceKey("liu_"+42);
log.info("接收到消息:{}", new String(message.getBody()));
String body= new String(message.getBody());
String[] split = body.split("_");
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = dateFormat.parse(split[3]);
String s = redisTemplate.opsForValue().get(split[0]+"1");
System.out.println(s);
//选择数据源,切换数据源,
DynamicDataSourceHolder.setDynamicDataSourceKey("liu_"+s);
FaultRecord build = FaultRecord.builder()
.vin(split[0])
.faultCode(split[1])
.faultLevel(split[2])
.startTime(date)
.build();
log.info("123{}",build);
faultRecordService.save(build);
// 移除数据源,
DynamicDataSourceHolder.removeDynamicDataSourceKey();
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
log.info("消费成功!数据源为:{}",message);
} catch (Exception e) {
log.info("消费失败,{}",e.getMessage());
try {
//回退消息
channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
log.info("回退成功");
}catch (IOException ex){
log.info("回退失败:{}",ex.getMessage());
}
throw new RuntimeException(e);
}
}
@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "success"),
exchange = @Exchange(name = "carnet_fault_event", type = ExchangeTypes.DIRECT))})
public void successMessage(Message message, Channel channel) {
try {
log.info("恢复正常消息:{}", new String(message.getBody()));
String body= new String(message.getBody());
String[] split = body.split("_");
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = dateFormat.parse(split[3]);
String s = redisTemplate.opsForValue().get(split[0]+"1");
System.out.println(s);
//选择数据源,切换数据源,
DynamicDataSourceHolder.setDynamicDataSourceKey("liu_"+s);
FaultRecord build = FaultRecord.builder()
.vin(split[0])
.faultCode(split[1])
.faultLevel(split[2])
.startTime(date)
.build();
FaultRecord faultRecordOne = faultRecordService.selectFault(build);
log.info("查询到的故障为:{}",faultRecordOne);
faultRecordOne.setEndTime(faultRecord.getEndTime());
// 进行修改故障表
faultRecordService.updateByFaultRecord(faultRecordOne);
// 移除数据源,
DynamicDataSourceHolder.removeDynamicDataSourceKey();
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e) {
try {
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,111 @@
package com.muyu.customer.business.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.muyu.customer.business.domain.FaultCode;
import com.muyu.customer.business.domain.req.FaultCodeEditReq;
import com.muyu.customer.business.domain.req.FaultCodeQueryReq;
import com.muyu.customer.business.domain.req.FaultCodeSaveReq;
import com.muyu.customer.business.service.FaultCodeService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.utils.poi.ExcelUtil;
import com.muyu.common.core.web.controller.BaseController;
import com.muyu.common.log.annotation.Log;
import com.muyu.common.log.enums.BusinessType;
import com.muyu.common.security.annotation.RequiresPermissions;
import com.muyu.common.core.web.page.TableDataInfo;
/**
* Controller
*
* @author chx
* @date 2024-06-20
*/
@Api(tags = "车辆故障码")
@RestController
@RequestMapping("/faultCode")
public class FaultCodeController extends BaseController {
@Autowired
private FaultCodeService faultCodeService;
/**
*
*/
@ApiOperation("获取车辆故障码列表")
@RequiresPermissions("customerBusiness:faultCode:list")
@GetMapping("/list")
public Result<TableDataInfo<FaultCode>> list(FaultCodeQueryReq faultCodeQueryReq) {
startPage();
List<FaultCode> list = faultCodeService.list(FaultCode.queryBuild(faultCodeQueryReq));
return getDataTable(list);
}
/**
*
*/
@ApiOperation("导出车辆故障码列表")
@RequiresPermissions("customerBusiness:faultCode:export")
@Log(title = "车辆故障码", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, FaultCode faultCode) {
List<FaultCode> list = faultCodeService.list(faultCode);
ExcelUtil<FaultCode> util = new ExcelUtil<FaultCode>(FaultCode.class);
util.exportExcel(response, list, "车辆故障码数据");
}
/**
*
*/
@ApiOperation("获取车辆故障码详细信息")
@RequiresPermissions("customerBusiness:faultCode:query")
@GetMapping(value = "/{id}")
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class)
public Result<FaultCode> getInfo(@PathVariable("id") Long id) {
return Result.success(faultCodeService.getById(id));
}
/**
*
*/
@RequiresPermissions("customerBusiness:faultCode:add")
@Log(title = "车辆故障码", businessType = BusinessType.INSERT)
@PostMapping
@ApiOperation("新增车辆故障码")
public Result<String> add(@RequestBody FaultCodeSaveReq faultCodeSaveReq) {
return toAjax(faultCodeService.save(FaultCode.saveBuild(faultCodeSaveReq)));
}
/**
*
*/
@RequiresPermissions("customerBusiness:faultCode:edit")
@Log(title = "车辆故障码", businessType = BusinessType.UPDATE)
@PutMapping("/{id}")
@ApiOperation("修改车辆故障码")
public Result<String> edit(@PathVariable Long id, @RequestBody FaultCodeEditReq faultCodeEditReq) {
return toAjax(faultCodeService.updateById(FaultCode.editBuild(id,faultCodeEditReq)));
}
/**
*
*/
@RequiresPermissions("customerBusiness:faultCode:remove")
@Log(title = "车辆故障码", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@ApiOperation("删除车辆故障码")
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = String.class, example = "1,2,3,4")
public Result<String> remove(@PathVariable List<Long> ids) {
return toAjax(faultCodeService.removeBatchByIds(ids));
}
}

View File

@ -0,0 +1,111 @@
package com.muyu.customer.business.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.muyu.customer.business.domain.FaultRecord;
import com.muyu.customer.business.domain.req.FaultRecordEditReq;
import com.muyu.customer.business.domain.req.FaultRecordQueryReq;
import com.muyu.customer.business.domain.req.FaultRecordSaveReq;
import com.muyu.customer.business.service.FaultRecordService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.utils.poi.ExcelUtil;
import com.muyu.common.core.web.controller.BaseController;
import com.muyu.common.log.annotation.Log;
import com.muyu.common.log.enums.BusinessType;
import com.muyu.common.security.annotation.RequiresPermissions;
import com.muyu.common.core.web.page.TableDataInfo;
/**
* Controller
*
* @author chx
* @date 2024-06-20
*/
@Api(tags = "故障记录")
@RestController
@RequestMapping("/faultRecord")
public class FaultRecordController extends BaseController {
@Autowired
private FaultRecordService faultRecordService;
/**
*
*/
@ApiOperation("获取故障记录列表")
@RequiresPermissions("customerBusiness:faultRecord:list")
@GetMapping("/list")
public Result<TableDataInfo<FaultRecord>> list(FaultRecordQueryReq faultRecordQueryReq) {
startPage();
List<FaultRecord> list = faultRecordService.list(FaultRecord.queryBuild(faultRecordQueryReq));
return getDataTable(list);
}
/**
*
*/
@ApiOperation("导出故障记录列表")
@RequiresPermissions("customerBusiness:faultRecord:export")
@Log(title = "故障记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, FaultRecord faultRecord) {
List<FaultRecord> list = faultRecordService.list(faultRecord);
ExcelUtil<FaultRecord> util = new ExcelUtil<FaultRecord>(FaultRecord.class);
util.exportExcel(response, list, "故障记录数据");
}
/**
*
*/
@ApiOperation("获取故障记录详细信息")
@RequiresPermissions("customerBusiness:faultRecord:query")
@GetMapping(value = "/{id}")
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class)
public Result<FaultRecord> getInfo(@PathVariable("id") Long id) {
return Result.success(faultRecordService.getById(id));
}
/**
*
*/
@RequiresPermissions("customerBusiness:faultRecord:add")
@Log(title = "故障记录", businessType = BusinessType.INSERT)
@PostMapping
@ApiOperation("新增故障记录")
public Result<String> add(@RequestBody FaultRecordSaveReq faultRecordSaveReq) {
return toAjax(faultRecordService.save(FaultRecord.saveBuild(faultRecordSaveReq)));
}
/**
*
*/
@RequiresPermissions("customerBusiness:faultRecord:edit")
@Log(title = "故障记录", businessType = BusinessType.UPDATE)
@PutMapping("/{id}")
@ApiOperation("修改故障记录")
public Result<String> edit(@PathVariable Long id, @RequestBody FaultRecordEditReq faultRecordEditReq) {
return toAjax(faultRecordService.updateById(FaultRecord.editBuild(id,faultRecordEditReq)));
}
/**
*
*/
@RequiresPermissions("customerBusiness:faultRecord:remove")
@Log(title = "故障记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@ApiOperation("删除故障记录")
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = String.class, example = "1,2,3,4")
public Result<String> remove(@PathVariable List<Long> ids) {
return toAjax(faultRecordService.removeBatchByIds(ids));
}
}

View File

@ -1,6 +1,9 @@
package com.muyu.customer.business.controller;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -10,6 +13,7 @@ import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.customer.business.mapper.VehicleMapper;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.utils.poi.ExcelUtil;
@ -38,6 +42,8 @@ public class VehicleController extends BaseController {
private VehicleService vehicleService;
@Autowired
private HttpServletRequest request;
@Autowired
private StringRedisTemplate redisTemplate;
/**
*
@ -47,7 +53,22 @@ public class VehicleController extends BaseController {
@GetMapping("/list")
public Result<TableDataInfo<Vehicle>> list(VehicleQueryReq vehicleQueryReq) {
startPage();
List<Vehicle> list = vehicleService.list(Vehicle.queryBuild(vehicleQueryReq));
ExecutorService executor = Executors.newFixedThreadPool(list.size());
list.forEach(vehicle -> {
executor.submit(new Runnable() {
@Override
public void run() {
redisTemplate
.opsForValue()
.set(vehicle.getVin()+"1",
String.valueOf(SecurityUtils.getLoginUser().getSysUser().getEnterpriseId()),
24,
TimeUnit.HOURS);
}
});
});
return getDataTable(list);
}
@ -84,6 +105,7 @@ public class VehicleController extends BaseController {
@PostMapping
@ApiOperation("新增车辆录入")
public Result<String> add(@RequestBody VehicleSaveReq vehicleSaveReq) {
return toAjax(vehicleService.save(Vehicle.saveBuild(vehicleSaveReq)));
}

View File

@ -0,0 +1,39 @@
package com.muyu.customer.business.controller;
import com.alibaba.fastjson2.JSON;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.web.controller.BaseController;
import com.muyu.customer.business.domain.Vehicle;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* VehicleInfoController
*
* @author DeKangLiu
* Date 2024/6/22 20:31
*/
@Log4j2
@RestController
@RequestMapping("/vehicleInfo")
public class VehicleInfoController extends BaseController {
@Autowired
private RedisTemplate<String,String> redisTemplate;
@GetMapping("/list/{vin}")
public Result vehicleInfoAllList(@PathVariable String vin){
if (redisTemplate.hasKey(vin)){
String lastElement = redisTemplate.opsForList().index(vin, -1);
Vehicle vehicleInfo = JSON.parseObject(lastElement, Vehicle.class);
return Result.success(vehicleInfo);
}
return null;
}
}

View File

@ -0,0 +1,15 @@
package com.muyu.customer.business.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.muyu.customer.business.domain.FaultCode;
/**
* Mapper
*
* @author chx
* @date 2024-06-20
*/
public interface FaultCodeMapper extends BaseMapper<FaultCode> {
}

View File

@ -0,0 +1,18 @@
package com.muyu.customer.business.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.muyu.customer.business.domain.FaultRecord;
/**
* Mapper
*
* @author chx
* @date 2024-06-20
*/
public interface FaultRecordMapper extends BaseMapper<FaultRecord> {
void addRecord(FaultRecord build);
FaultRecord selectFault(FaultRecord build);
}

View File

@ -0,0 +1,120 @@
package com.muyu.customer.business.saas.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSON;
import com.muyu.common.core.utils.SpringUtils;
import com.muyu.common.redis.service.RedisService;
import com.muyu.customer.business.saas.factory.DruidDataSourceFactory;
import com.muyu.customer.business.saas.domain.model.DataSourceInfo;
import com.muyu.customer.business.saas.role.DynamicDataSource;
import com.muyu.net.working.remote.RemoteDatasourceService;
import com.rabbitmq.client.Channel;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import com.muyu.net.working.domain.DataSource;
import java.io.IOException;
import java.util.*;
/**
* ManyDataSource
*
* @author DeKangLiu
* Date 2024/6/3 20:01
*/
@Component
@Log4j2
@AutoConfigureBefore(RedisService.class)
public class ManyDataSource {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private RemoteDatasourceService remoteDatasourceService;
@Autowired
private RabbitTemplate rabbitTemplate;
@RabbitListener(queuesToDeclare = {@Queue(name = "liu-vehicle-exchange")})
public void smsConfig(String msg, Message message, Channel channel){
//获取消息的ID
String messageId = message.getMessageProperties().getMessageId();
try {
//添加消息id到redis set集合中 添加成功返回1 表示未消费 添加失败返回0 表示已消费
Long count = redisTemplate.opsForSet().add("messageId", messageId);
//添加成功 正常消费信息
if (count == 1) {
log.info("开始消费");
druidData(msg);
//确认消费
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
log.info("消费成功");
}
} catch (Exception e) {
log.info("消费失败,尝试重连");
try {
//回退消息,尝试重连
druidData(msg);
channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
log.info("消费失败");
} catch (IOException ex) {
//回退失败
log.info("消费异常");
}
}
}
private void druidData(String msg) {
DataSource entInfo= JSON.parseObject(msg, DataSource.class);
log.info("消息为:{}",entInfo);
DruidDataSourceFactory druidDataSourceFactory = SpringUtils.getBean(DruidDataSourceFactory.class);
DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
DataSourceInfo dataSourceInfo = DataSourceInfo.hostAndPortBuild(entInfo.getEnterpriseCode(), entInfo.getIp(), entInfo.getPort());
DruidDataSource druidDataSource = druidDataSourceFactory.create(dataSourceInfo);
dynamicDataSource.put(dataSourceInfo.getKey(), druidDataSource);
}
@Lazy
private List<DataSource> dataSourceInfoList(){
List<DataSource> databaseNameList = new ArrayList<>(){{
add(DataSource.builder()
.enterpriseCode("liu_44")
.ip("192.168.116.129")
.port(3350)
.build());
}};
List<DataSource> list = remoteDatasourceService.listAll();
System.out.println(list);
databaseNameList.addAll(list);
return databaseNameList;
}
@Bean
@Primary
public DynamicDataSource dynamicDataSource(DruidDataSourceFactory druidDataSourceFactory) {
//查企业
Map<Object, Object> dataSourceMap = new HashMap<>();
dataSourceInfoList()
.stream()
.map(entInfo-> DataSourceInfo.hostAndPortBuild(entInfo.getEnterpriseCode(),entInfo.getIp(),entInfo.getPort()))
.forEach(dataSourceInfo -> {
dataSourceMap.put(dataSourceInfo.getKey(), druidDataSourceFactory.create(dataSourceInfo));
});
//设置动态数据源
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
dynamicDataSource.setTargetDataSources(dataSourceMap);
//将数据源信息备份在defineTargetDataSources中
dynamicDataSource.setDefineTargetDataSources(dataSourceMap);
return dynamicDataSource;
}
}

View File

@ -0,0 +1,52 @@
package com.muyu.customer.business.saas.domain.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.muyu.common.core.annotation.Excel;
import com.muyu.common.core.web.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* DataSource
*
* @author DeKangLiu
* Date 2024/6/22 22:56
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName("datasource")
public class DataSource extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(value = "id",type = IdType.AUTO)
@ApiModelProperty(name = "主键", value = "主键")
private Long id;
/** 数据源key */
@Excel(name = "数据源key")
@ApiModelProperty(name = "数据源key", value = "数据源key")
private String enterpriseCode;
/** 数据源端口 */
@Excel(name = "数据源端口")
@ApiModelProperty(name = "数据源端口", value = "数据源端口")
private Integer port;
/** 数据源ip */
@Excel(name = "数据源ip")
@ApiModelProperty(name = "数据源ip", value = "数据源ip")
private String ip;
}

View File

@ -1,8 +1,8 @@
package com.muyu.saas.domain.model;
package com.muyu.customer.business.saas.domain.model;
import com.muyu.common.core.utils.StringUtils;
import com.muyu.saas.contents.DatasourceContent;
import com.muyu.customer.business.saas.contents.DatasourceContent;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -44,7 +44,7 @@ public class DataSourceInfo {
public static DataSourceInfo hostAndPortBuild(String key,String host, Integer port){
return DataSourceInfo.builder()
.key(key)
.url(StringUtils.format(DatasourceContent.DATASOURCE_URL, host, port,port))
.url(StringUtils.format(DatasourceContent.DATASOURCE_URL, host,port))
.password(DatasourceContent.PASSWORD)
.userName(DatasourceContent.USER_NAME)
.build();

View File

@ -1,7 +1,7 @@
package com.muyu.saas.factory;
package com.muyu.customer.business.saas.factory;
import com.alibaba.druid.pool.DruidDataSource;
import com.muyu.saas.domain.model.DataSourceInfo;
import com.muyu.customer.business.saas.domain.model.DataSourceInfo;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

View File

@ -1,4 +1,4 @@
package com.muyu.saas.holder;
package com.muyu.customer.business.saas.holder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

View File

@ -0,0 +1,51 @@
package com.muyu.customer.business.saas.role;
import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.common.system.domain.SysUser;
import com.muyu.common.system.remote.RemoteUserService;
import com.muyu.customer.business.saas.holder.DynamicDataSourceHolder;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
*
*
* @author DeKangLiu
* Date 2024/6/3 20:12
*/
@Aspect
@Component
public class DataSourceAsp {
@Lazy
@Autowired
private RemoteUserService remoteUserService;
@Pointcut("execution(public * com.muyu.customer.business.controller.*Controller.*(..))")
public void pointcut () {
}
/**
*
*/
@Before("pointcut()")
public void beforeMethod() {
Integer enterpriseId = SecurityUtils.getLoginUser().getSysUser().getEnterpriseId();
DynamicDataSourceHolder.setDynamicDataSourceKey("liu_"+enterpriseId);
}
/**
*
*
*
*/
@After("pointcut()")
public void afterMethod() {
DynamicDataSourceHolder.removeDynamicDataSourceKey();
}
}

View File

@ -1,7 +1,7 @@
package com.muyu.saas.role;
package com.muyu.customer.business.saas.role;
import com.alibaba.druid.pool.DruidDataSource;
import com.muyu.saas.holder.DynamicDataSourceHolder;
import com.muyu.customer.business.saas.holder.DynamicDataSourceHolder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@ -0,0 +1,22 @@
package com.muyu.customer.business.service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
import com.muyu.customer.business.domain.FaultCode;
/**
* Service
*
* @author chx
* @date 2024-06-20
*/
public interface FaultCodeService extends IService<FaultCode> {
/**
*
*
* @param faultCode
* @return
*/
public List<FaultCode> list(FaultCode faultCode);
}

View File

@ -0,0 +1,25 @@
package com.muyu.customer.business.service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
import com.muyu.customer.business.domain.FaultRecord;
/**
* Service
*
* @author chx
* @date 2024-06-20
*/
public interface FaultRecordService extends IService<FaultRecord> {
/**
*
*
* @param faultRecord
* @return
*/
public List<FaultRecord> list(FaultRecord faultRecord);
void addRecord(FaultRecord build);
FaultRecord selectFault(FaultRecord build);
}

View File

@ -3,6 +3,7 @@ package com.muyu.customer.business.service;
import java.util.List;
import com.muyu.customer.business.domain.Vehicle;
import com.baomidou.mybatisplus.extension.service.IService;
import com.muyu.customer.business.domain.req.VehicleQueryReq;
/**
* Service

View File

@ -0,0 +1,43 @@
package com.muyu.customer.business.service.impl;
import java.util.List;
import com.muyu.common.core.utils.ObjUtils;
import com.muyu.customer.business.domain.FaultCode;
import com.muyu.customer.business.mapper.FaultCodeMapper;
import com.muyu.customer.business.service.FaultCodeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
/**
* Service
*
* @author chx
* @date 2024-06-20
*/
@Slf4j
@Service
public class FaultCodeServiceImpl extends ServiceImpl<FaultCodeMapper, FaultCode> implements FaultCodeService {
/**
*
*
* @param faultCode
* @return
*/
@Override
public List<FaultCode> list(FaultCode faultCode) {
LambdaQueryWrapper<FaultCode> queryWrapper = new LambdaQueryWrapper<>();
if (ObjUtils.notNull(faultCode.getFaultCode())){
queryWrapper.eq(FaultCode::getFaultCode, faultCode.getFaultCode());
}
return list(queryWrapper);
}
}

View File

@ -0,0 +1,61 @@
package com.muyu.customer.business.service.impl;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.muyu.common.core.utils.ObjUtils;
import com.muyu.customer.business.domain.FaultRecord;
import com.muyu.customer.business.mapper.FaultRecordMapper;
import com.muyu.customer.business.service.FaultRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
/**
* Service
*
* @author chx
* @date 2024-06-20
*/
@Slf4j
@Service
public class FaultRecordServiceImpl extends ServiceImpl<FaultRecordMapper, FaultRecord> implements FaultRecordService {
@Autowired
private FaultRecordMapper faultRecordMapper;
/**
*
*
* @param faultRecord
* @return
*/
@Override
public List<FaultRecord> list(FaultRecord faultRecord) {
LambdaQueryWrapper<FaultRecord> queryWrapper = new LambdaQueryWrapper<>();
if (ObjUtils.notNull(faultRecord.getFaultCode())){
queryWrapper.eq(FaultRecord::getFaultCode, faultRecord.getFaultCode());
}
if (ObjUtils.notNull(faultRecord.getVin())){
queryWrapper.eq(FaultRecord::getVin, faultRecord.getVin());
}
return list(queryWrapper);
}
@Override
public void addRecord(FaultRecord build) {
faultRecordMapper.addRecord(build);
}
@Override
public FaultRecord selectFault(FaultRecord build) {
return faultRecordMapper.selectFault(build);
}
}

View File

@ -2,12 +2,14 @@ package com.muyu.customer.business.service.impl;
import java.util.List;
import com.alibaba.fastjson2.JSONObject;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.utils.ObjUtils;
import com.muyu.customer.business.domain.Vehicle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.muyu.customer.business.mapper.FenceMapper;
import com.muyu.customer.business.domain.Fence;
@ -15,7 +17,6 @@ import com.muyu.customer.business.service.FenceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.web.client.RestTemplate;
/**
* Service
*
@ -57,11 +58,20 @@ public class FenceServiceImpl extends ServiceImpl<FenceMapper, Fence> implement
return list(queryWrapper);
}
@Autowired
private StringRedisTemplate redisTemplate;
@Override
public Result getConn(Vehicle vehicle) {
Object forObject = restTemplate.getForObject("http://192.168.43.154:88/test/getList?vin="+vehicle.getVin(), Object.class);
return Result.success(forObject);
// Object forObject = restTemplate.getForObject("http://192.168.43.154:88/test/getList?vin="+vehicle.getVin(), Object.class);
String value = "";
if (Boolean.TRUE.equals(redisTemplate.hasKey(vehicle.getVin()))) {
value = redisTemplate.opsForValue().get(vehicle.getVin());
System.out.println(value);
}
JSONObject jsonObject = JSONObject.parseObject(value);
System.out.println(jsonObject);
System.out.println(value);
return Result.success(jsonObject);
}
}

View File

@ -93,9 +93,6 @@ public class VehicleServiceImpl extends ServiceImpl<VehicleMapper, Vehicle> imp
}
return list(queryWrapper);
}
}

View File

@ -4,9 +4,26 @@ server:
# Spring
spring:
main:
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
allow-circular-references: true
application:
# 应用名称
name: muyu-customer-business
rabbitmq:
host: 121.43.127.44
port: 5672
username: guest
password: guest
virtualHost: /
listener:
simple:
prefetch: 1 #每次消费一条消息 消费完成取下一条消费
acknowledge-mode: manual # 手动确认消息
retry:
enabled: true # 开启重试
publisher-confirm-type: correlated #确认消息已发送到交换机(Exchange)
publisher-returns: true #确认消息已发送到队列(Queue)
profiles:
# 环境配置
active: dev

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.muyu.customer.business.mapper.FaultCodeMapper">
<resultMap type="com.muyu.customer.business.domain.FaultCode" id="FaultCodeResult">
<result property="id" column="id" />
<result property="faultCode" column="fault_code" />
<result property="faultLabel" column="fault_label" />
<result property="faultBit" column="fault_bit" />
<result property="faultValue" column="fault_value" />
</resultMap>
<sql id="selectFaultCodeVo">
select id, fault_code, fault_label, fault_bit, fault_value from fault_code
</sql>
</mapper>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.muyu.customer.business.mapper.FaultRecordMapper">
<resultMap type="com.muyu.customer.business.domain.FaultRecord" id="FaultRecordResult">
<result property="id" column="id" />
<result property="faultCode" column="fault_code" />
<result property="vin" column="vin" />
<result property="startTime" column="start_time" />
<result property="endTime" column="end_time" />
<result property="faultLevel" column="fault_level" />
<result property="faultHandle" column="fault_handle" />
</resultMap>
<sql id="selectFaultRecordVo">
select id, fault_code, vin, start_time, end_time, fault_level, fault_handle from fault_record
</sql>
<insert id="addRecord">
INSERT INTO fault_record
(`fault_code`, `vin`, `start_time`, `end_time`, `fault_level`, `fault_handle`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES
values(#{faultCode},#{vin},#{startTime},null,#{faultLevel},#{faultHandle},null,null,null,null,null)
</insert>
<select id="selectFault" resultType="com.muyu.customer.business.domain.FaultRecord">
SELECT id,fault_code,vin,start_time,end_time,fault_level,fault_handle
FROM fault_record
WHERE fault_code =#{faultCode} AND vin = #{vin} AND end_time is NULL
</select>
</mapper>

View File

@ -0,0 +1,54 @@
package com.muyu.net.working.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.muyu.common.core.annotation.Excel;
import com.muyu.common.core.web.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.io.Serializable;
/**
* DataSource
*
* @author DeKangLiu
* Date 2024/6/22 22:56
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName("datasource")
public class DataSource extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(value = "id",type = IdType.AUTO)
@ApiModelProperty(name = "主键", value = "主键")
private Long id;
/** 数据源key */
@Excel(name = "数据源key")
@ApiModelProperty(name = "数据源key", value = "数据源key")
private String enterpriseCode;
/** 数据源端口 */
@Excel(name = "数据源端口")
@ApiModelProperty(name = "数据源端口", value = "数据源端口")
private Integer port;
/** 数据源ip */
@Excel(name = "数据源ip")
@ApiModelProperty(name = "数据源ip", value = "数据源ip")
private String ip;
}

View File

@ -17,6 +17,20 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>muyu-common-core</artifactId>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>muyu-net-working-common</artifactId>
<version>3.6.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,27 @@
package com.muyu.net.working.remote;
import com.muyu.common.core.constant.ServiceNameConstants;
import com.muyu.net.working.remote.factory.RemoteDatasourceFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import com.muyu.net.working.domain.DataSource;
import java.util.List;
/**
* RemoteBusinessService
*
* @author DeKangLiu
* Date 2024/6/22 20:39
*/
@FeignClient(
contextId = "remoteDatasourceService",
value = ServiceNameConstants.DATASOURCE_SERVICE,
fallbackFactory = RemoteDatasourceFallbackFactory.class,
path = "/datasource"
)
public interface RemoteDatasourceService {
@GetMapping("/listAll")
public List<DataSource> listAll();
}

View File

@ -0,0 +1,39 @@
package com.muyu.net.working.remote.factory;
import com.muyu.common.core.domain.Result;
import com.muyu.net.working.domain.DataSource;
import com.muyu.net.working.remote.RemoteDatasourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import javax.xml.crypto.Data;
import java.util.List;
/**
* RemoteBusinessFallbackFactory
*
* @author DeKangLiu
* Date 2024/6/22 20:41
*/
@Component
public class RemoteDatasourceFallbackFactory implements FallbackFactory<RemoteDatasourceService> {
private static final Logger log = LoggerFactory.getLogger(RemoteDatasourceFallbackFactory.class);
@Override
public RemoteDatasourceService create (Throwable throwable) {
log.error("用户服务调用失败:{}", throwable.getMessage());
return new RemoteDatasourceService() {
/**
*
* @return
*/
@Override
public List<DataSource> listAll() {
return null;
}
};
}
}

View File

@ -0,0 +1 @@
com.muyu.net.working.remote.factory.RemoteDatasourceFallbackFactory

View File

@ -93,6 +93,11 @@
<groupId>com.muyu</groupId>
<artifactId>muyu-common-swagger</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,48 @@
package com.muyu.net.working.config;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
*
*/
@Component
public class ConfirmCallbackConfig implements RabbitTemplate.ConfirmCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* @PostContructspringspring
* @PostConstruct bean
* @PreDestory bean
*/
@PostConstruct
public void init() {
rabbitTemplate.setConfirmCallback(this);
}
/**
*
*
* @param correlationData
* @param ack
* @param cause
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack) {
// 消息投递到 broker 的状态true表示成功
System.out.println("消息发送成功!");
} else {
// 发送异常
System.out.println("发送异常原因 = " + cause);
// TODO 可以将消息 内容 以及 失败的原因 记录到 日志表中
}
}
}

View File

@ -0,0 +1,53 @@
package com.muyu.net.working.config;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* RabbitAdminRabbitMQJavaRabbitMQRabbitMQ
*/
@Configuration
public class RabbitAdminConfig {
@Value("${spring.rabbitmq.host}")
private String host;
@Value("${spring.rabbitmq.username}")
private String username;
@Value("${spring.rabbitmq.password}")
private String password;
@Value("${spring.rabbitmq.virtualhost}")
private String virtualhost;
/**
* RabbitMQ
* @return
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(host);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualhost);
// 配置发送确认回调时次配置必须配置否则即使在RabbitTemplate配置了ConfirmCallback也不会生效
connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
connectionFactory.setPublisherReturns(true);
return connectionFactory;
}
/**
* RabbitAdmin
* @param connectionFactory
* @return
*/
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
}
}

View File

@ -0,0 +1,16 @@
package com.muyu.net.working.config;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitmqConfig {
// 消息转换配置
@Bean
public MessageConverter jsonMessageConverter() {
// 使用json序列化方式进行消息转换
return new Jackson2JsonMessageConverter();
}
}

View File

@ -0,0 +1,34 @@
package com.muyu.net.working.config;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* returnedMessage
*/
@Component
public class ReturnCallbackConfig implements RabbitTemplate.ReturnsCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct // @PostContruct是spring框架的注解在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法也可以理解为在spring容器初始化的时候执
public void init() {
rabbitTemplate.setReturnsCallback(this);
}
/**
*
* @param returnedMessage the returned message and metadata.
*/
@Override
public void returnedMessage(ReturnedMessage returnedMessage) {
System.out.println("消息" + returnedMessage.getMessage().toString() + "被交换机" + returnedMessage.getExchange() + "回退!"
+ "退回原因为:" + returnedMessage.getReplyText());
// 回退了所有的信息,可做补偿机制 记录到 数据库
}
}

View File

@ -0,0 +1,53 @@
package com.muyu.net.working.controller;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.web.controller.BaseController;
import com.muyu.common.core.web.page.TableDataInfo;
import com.muyu.common.log.annotation.Log;
import com.muyu.common.log.enums.BusinessType;
import com.muyu.common.security.annotation.RequiresPermissions;
import com.muyu.net.working.domain.DataSource;
import com.muyu.net.working.domain.Enterprise;
import com.muyu.net.working.service.DataSourceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* DataSourceController
*
* @author DeKangLiu
* Date 2024/6/22 23:07
*/
@Api(tags = "多数据源")
@Log4j2
@RestController
@RequestMapping("/datasource")
public class DataSourceController extends BaseController {
@Autowired
private DataSourceService dataSourceService;
@ApiOperation("获取多数据源列表")
@GetMapping("/list")
public Result<TableDataInfo<DataSource>> list(DataSource dataSource) {
startPage();
List<DataSource> list = dataSourceService.list(dataSource);
return getDataTable(list);
}
@GetMapping("/listAll")
public List<DataSource> listAll() {
List<DataSource> list = dataSourceService.list();
return list;
}
@PostMapping
@ApiOperation("新增多数据源")
public Result<String> add(@RequestBody DataSource dataSource) {
return toAjax(dataSourceService.save(dataSource));
}
}

View File

@ -8,11 +8,9 @@ import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.common.system.domain.LoginUser;
import com.muyu.common.system.domain.SysDept;
import com.muyu.common.system.domain.SysUser;
import com.muyu.system.remote.RemoteSysDeptService;
import com.muyu.system.remote.RemoteSysUserService;
import com.muyu.system.remote.factory.RemoteSysDeptFactory;
import com.muyu.common.system.remote.RemoteSysDeptService;
import com.muyu.common.system.remote.RemoteSysUserService;
import io.swagger.annotations.*;
import io.swagger.models.auth.In;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

View File

@ -0,0 +1,18 @@
package com.muyu.net.working.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.muyu.net.working.domain.DataSource;
import com.muyu.net.working.domain.Enterprise;
import java.util.List;
/**
* DataSourcrMapper
*
* @author DeKangLiu
* Date 2024/6/22 23:13
*/
public interface DataSourceMapper extends BaseMapper<DataSource> {
List<DataSource> list(DataSource dataSource);
}

View File

@ -0,0 +1,17 @@
package com.muyu.net.working.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.muyu.net.working.domain.DataSource;
import java.util.List;
/**
* DataSourceService
*
* @author DeKangLiu
* Date 2024/6/22 23:09
*/
public interface DataSourceService extends IService<DataSource> {
List<DataSource> list(DataSource dataSource);
}

View File

@ -0,0 +1,30 @@
package com.muyu.net.working.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.muyu.net.working.domain.DataSource;
import com.muyu.net.working.mapper.DataSourceMapper;
import com.muyu.net.working.service.DataSourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* DataSourceServiceImpl
*
* @author DeKangLiu
* Date 2024/6/22 23:12
*/
@Service
@Slf4j
public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSource> implements DataSourceService {
@Autowired
private DataSourceMapper dataSourceMapper;
@Override
public List<DataSource> list(DataSource dataSource) {
return dataSourceMapper.list(dataSource);
}
}

View File

@ -8,12 +8,16 @@ import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.alibaba.fastjson.JSON;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.utils.ObjUtils;
import com.muyu.net.working.domain.DataSource;
import com.muyu.net.working.domain.req.EnterpriseSaveReq;
import com.muyu.net.working.service.DataSourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.muyu.net.working.mapper.EnterpriseMapper;
@ -34,6 +38,10 @@ public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterpr
@Autowired
private EnterpriseMapper enterpriseMapper;
@Autowired
private DataSourceService dataSourceService;
@Autowired
private RabbitTemplate rabbitTemplate;
/**
*
*
@ -128,11 +136,12 @@ public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterpr
enterpriseMapper.addEnterprise(enterpriseSaveReq);
}
public static void postTest(Enterprise enterprise) throws Exception {
public void postTest(Enterprise enterprise) throws Exception {
// 1.请求URL
String postUrl = "http://192.168.116.129:10006/webhook/%E6%96%B0%E5%BB%BA%E4%BC%81%E4%B8%9A%E7%AE%A1%E7%90%86";
// 2.请求参数JSON格式
enterprise.getId();
// enterprise.getId();
Map<String, String> parammap = new HashMap<>();
parammap.put("enterpriseId", "liu-"+enterprise.getId());
parammap.put("mysqlPort", String.valueOf(3306+enterprise.getId()));
@ -161,6 +170,17 @@ public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterpr
new InputStreamReader(httpConn.getInputStream()));
String resultData = br.readLine();
System.out.println("从服务端返回结果: " + resultData);
DataSource build = DataSource.builder()
.enterpriseCode("liu_" + enterprise.getId())
.ip("192.168.116.129")
.port(3306 +enterprise.getId()).build();
dataSourceService.save(build);
rabbitTemplate.convertAndSend("liu-vehicle-exchange",build,message ->{
message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
//设置消息延迟时间为5秒
message.getMessageProperties().setDelay(5000);
return message;
} );
// 7.关闭HttpURLConnection连接
httpConn.disconnect();
}

View File

@ -4,6 +4,20 @@ server:
# Spring
spring:
rabbitmq:
host: 121.43.127.44
port: 5672
username: guest
password: guest
virtualHost: /
listener:
simple:
prefetch: 1 #每次消费一条消息 消费完成取下一条消费
acknowledge-mode: manual # 手动确认消息
retry:
enabled: true # 开启重试
publisher-confirm-type: correlated #确认消息已发送到交换机(Exchange)
publisher-returns: true #确认消息已发送到队列(Queue)
application:
# 应用名称
name: muyu-net-working

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.muyu.net.working.mapper.DataSourceMapper">
<select id="list" resultType="com.muyu.net.working.domain.DataSource">
select * from datasource
</select>
</mapper>

View File

@ -1,2 +0,0 @@
com.muyu.system.remote.factory.RemoteSysUserFactory
com.muyu.system.remote.factory.RemoteSysDeptFactory