Compare commits

..

1 Commits
master ... v1.0

Author SHA1 Message Date
DongZeLiang 5ba1cd9a4a fix():车辆报文上报基于模板 2024-12-11 15:27:40 +08:00
114 changed files with 2593 additions and 4967 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

72
pom.xml
View File

@ -6,43 +6,33 @@
<groupId>com.muyu</groupId>
<artifactId>VehicleSimulation</artifactId>
<version>1.0.7</version>
<version>1.0.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatisplus.version>3.5.7</mybatisplus.version>
<forest.version>1.5.36</forest.version>
<jjwt.version>0.12.5</jjwt.version>
<mybatisplus.version>3.5.1</mybatisplus.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<version>2.7.15</version>
</parent>
<dependencies>
<!-- SpringBootWeb开发框架 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot测试框架 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- SpringBoot校验框架 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- mqtt3 -->
<dependency>
<groupId>org.eclipse.paho</groupId>
@ -50,7 +40,7 @@
<version>1.2.5</version>
</dependency>
<!-- lombok插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
@ -59,17 +49,25 @@
<!-- mybatis-plus 所需依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!-- mysql数据库驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<!-- 使用h2内存数据库 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- json处理框架 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
@ -79,8 +77,14 @@
<!-- http调用框架 -->
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot3-starter</artifactId>
<version>${forest.version}</version>
<artifactId>forest-spring-boot-starter</artifactId>
<version>1.5.33</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<!--常用工具类 -->
@ -88,28 +92,6 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
</dependencies>
<build>
<finalName>vehicle-simulation-${version}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -3,8 +3,6 @@ package com.muyu;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author DongZeLiang
@ -12,9 +10,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
* @description
* @date 2023/11/9
*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@SpringBootApplication
@MapperScan(value = "com.muyu.**.mapper")
@EnableTransactionManagement
public class VehicleSimulationApplication {
public static void main(String[] args) {

View File

@ -1,52 +0,0 @@
package com.muyu.cache;
import com.github.benmanes.caffeine.cache.Expiry;
import org.checkerframework.checker.index.qual.NonNegative;
import java.util.concurrent.TimeUnit;
/**
* @Author: DongZeLiang
* @date: 2024/9/12
* @Description:
* @Version: 1.0
*/
public class CacheExpiry<K, V extends ExpiryTime> implements Expiry<K, ExpiryTime> {
/**
* @param key
* @param value
* @param currentTime
*
* @return
*/
@Override
public long expireAfterCreate (K key, ExpiryTime value, long currentTime) {
return TimeUnit.SECONDS.toNanos(value.getExpiryTime());
}
/**
* @param key
* @param value
* @param currentTime
* @param currentDuration
*
* @return
*/
@Override
public long expireAfterUpdate (K key, ExpiryTime value, long currentTime, @NonNegative long currentDuration) {
return TimeUnit.SECONDS.toNanos(value.getRefreshTime());
}
/**
* @param key
* @param value
* @param currentTime
* @param currentDuration
*
* @return
*/
@Override
public long expireAfterRead (K key, ExpiryTime value, long currentTime, @NonNegative long currentDuration) {
return TimeUnit.SECONDS.toNanos(value.getRefreshTime());
}
}

View File

@ -1,31 +0,0 @@
package com.muyu.cache;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
*/
@Configuration
public class CaffeineConfig {
@Bean("loginUserCache")
public Cache<String, ? extends ExpiryTime> loginUserCache(){
CacheExpiry<String, ExpiryTime> cacheExpiry = new CacheExpiry<>();
return Caffeine.newBuilder()
.expireAfter(cacheExpiry)
.initialCapacity(128)
.build();
}
@Bean("messageTemplateCache")
public Cache<Long, ? extends ExpiryTime> messageTemplateCache(){
CacheExpiry<Long, ExpiryTime> cacheExpiry = new CacheExpiry<>();
return Caffeine.newBuilder()
.expireAfter(cacheExpiry)
.initialCapacity(128)
.build();
}
}

View File

@ -1,32 +0,0 @@
package com.muyu.cache;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* @Author: DongZeLiang
* @date: 2024/9/12
* @Description:
* @Version: 1.0
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class ExpiryTime {
/**
* 30
*/
@Builder.Default
private long expiryTime = 30*60;
/**
* 15
*/
@Builder.Default
private long refreshTime = 15*60;
}

View File

@ -1,51 +0,0 @@
package com.muyu.cache.model;
import com.muyu.cache.ExpiryTime;
import com.muyu.web.domain.MessageTemplate;
import com.muyu.web.domain.MessageTemplateValue;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
import java.util.function.Function;
/**
* @Author: DongZeLiang
* @date: 2024/9/25
* @Description:
* @Version: 1.0
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class MessageTemplateCacheModel extends ExpiryTime {
/**
*
*/
private Long key;
/**
*
*/
private String messageName;
/**
*
*/
private List<MessageTemplateValue> messageTemplateValueList;
public static MessageTemplateCacheModel messageTemplateBuild(
MessageTemplate messageTemplate, Function<Long,List<MessageTemplateValue>> function) {
return MessageTemplateCacheModel.builder()
.key(messageTemplate.getId())
.messageName(messageTemplate.getMessageName())
.messageTemplateValueList(function.apply(messageTemplate.getId()))
.build();
}
}

View File

@ -1,40 +0,0 @@
package com.muyu.config;
import com.muyu.utils.AesUtil;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.log4j.Log4j2;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.sql.Connection;
/**
*
* @Author: DongZeLiang
* @date: 2024/9/11
* @Description:
* @Version: 1.0
*/
@Log4j2
@Configuration
public class DataSourceConfig {
/**
* Bean
* @param dataSourceProperties
* @return hikari
*/
@Bean
public HikariDataSource initDataSource(DataSourceProperties dataSourceProperties) throws Exception {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setJdbcUrl(AesUtil.decrypt(dataSourceProperties.getUrl()));
hikariDataSource.setUsername(AesUtil.decrypt(dataSourceProperties.getUsername()));
hikariDataSource.setPassword(AesUtil.decrypt(dataSourceProperties.getPassword()));
hikariDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
Connection connection = hikariDataSource.getConnection();
log.info("数据源[{}]初始化成功", dataSourceProperties.getName());
hikariDataSource.evictConnection(connection);
return hikariDataSource;
}
}

View File

@ -1,53 +0,0 @@
package com.muyu.config;
import com.muyu.system.exception.BasicException;
import com.muyu.web.common.Result;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
*
* @author DongZeLiang
* @version 1.0
* @description
* @date 2023/11/15
*/
@Log4j2
@RestControllerAdvice
public class ExceptionAdvice {
/**
*
* @param exception
* @return
*/
@ExceptionHandler(value = RuntimeException.class)
public Result<String> runtimeExceptionHandler(HttpServletRequest request, RuntimeException exception){
log.error("请求发生异常:[{}] ----- [{}]",request.getRequestURI(), exception.getMessage(), exception);
return Result.error(exception.getMessage());
}
/**
*
* @param exception
* @return
*/
@ExceptionHandler(value = BasicException.class)
public Result<String> runtimeExceptionHandler(HttpServletRequest request, BasicException exception){
log.error("请求发生异常:[{}] ----- [{}]",request.getRequestURI(), exception.getMessage(), exception);
return Result.error(exception.getCode(), exception.getMessage());
}
/**
*
* @param exception
* @return
*/
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Result<String> runtimeExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException exception){
log.error("请求发生异常:[{}] ----- [{}]",request.getRequestURI(), exception.getMessage(), exception);
return Result.error(exception.getAllErrors().get(0).getDefaultMessage());
}
}

View File

@ -1,58 +0,0 @@
package com.muyu.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.muyu.system.handle.SystemHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Date;
import java.util.Set;
import java.util.stream.Collectors;
/**
*
*
*/
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
public MyMetaObjectHandler () {
log.info("元数据填充初始化成功");
}
@Override
public void insertFill(MetaObject metaObject) {
String[] setterNames = metaObject.getSetterNames();
Set<String> setterNamesSet = Arrays.stream(setterNames).collect(Collectors.toSet());
if (setterNamesSet.contains("tenantId")){
if (metaObject.getValue("tenantId") == null){
this.setFieldValByName("tenantId", SystemHandler.getTenantId(),metaObject);
}
}
if (setterNamesSet.contains("createTime")){
if (metaObject.getValue("createTime") == null) {
this.setFieldValByName("createTime", new Date(), metaObject);
}
}
if (setterNamesSet.contains("updateTime")){
if (metaObject.getValue("updateTime") == null) {
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
}
@Override
public void updateFill(MetaObject metaObject) {
String[] setterNames = metaObject.getSetterNames();
Set<String> setterNamesSet = Arrays.stream(setterNames).collect(Collectors.toSet());
if (setterNamesSet.contains("updateTime")){
if (metaObject.getValue("updateTime") == null) {
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
}
}

View File

@ -1,35 +0,0 @@
package com.muyu.config;
import com.muyu.config.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
/**
*
* */
@Configuration
public class SystemWebConfigurer implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
/** 拦截器配置 */
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 白名单
List<String> patterns = new ArrayList<String>();
patterns.add("/system/auth/reg");
patterns.add("/system/auth/login");
patterns.add("/system/auth/logout");
patterns.add("/");
patterns.add("/static/**");
// 通过注册工具添加拦截器
registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns(patterns);
}
}

View File

@ -1,82 +0,0 @@
package com.muyu.config.interceptor;
import com.github.benmanes.caffeine.cache.Cache;
import com.muyu.system.constants.TokenConstants;
import com.muyu.system.context.SystemUserContext;
import com.muyu.system.domain.LoginUserInfo;
import com.muyu.system.exception.BasicException;
import com.muyu.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
*
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Resource( name = "loginUserCache")
private Cache<String, LoginUserInfo> loginUserInfoCache;
/**
*
*
* @param request
* @param response
* @param handler
* @return trueControllerfalseController
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
// 判断当前请求是否需要被拦截
String token = request.getHeader(TokenConstants.AUTHENTICATION);
if (StringUtils.isEmpty(token)){
throw new BasicException(501,"未授权请求,请重新授权");
}
Claims claims = JwtUtils.parseToken(token);
String userKey = JwtUtils.getUserKey(claims);
LoginUserInfo loginUserInfo = loginUserInfoCache.getIfPresent(userKey);
if (loginUserInfo == null){
throw new BasicException(502,"用户授权过期,请重新登录");
}
SystemUserContext.set(loginUserInfo);
return true;
}
/**
*
*
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, ModelAndView modelAndView) throws Exception {
}
/**
*
*
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, Exception ex) throws Exception {
SystemUserContext.remove();
}
}

View File

@ -1,130 +0,0 @@
package com.muyu.config.runner;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.benmanes.caffeine.cache.Cache;
import com.muyu.cache.model.MessageTemplateCacheModel;
import com.muyu.config.tenant.CustomTenantHandler;
import com.muyu.vehicle.VehicleInstance;
import com.muyu.vehicle.core.LocalContainer;
import com.muyu.web.common.pool.FixedThreadPool;
import com.muyu.web.common.pool.ScheduledThreadPool;
import com.muyu.web.domain.VehicleInfo;
import com.muyu.web.service.MessageTemplateService;
import com.muyu.web.service.MessageTemplateValueService;
import com.muyu.web.service.VehicleInfoService;
import com.muyu.web.service.VehicleInstanceService;
import jakarta.annotation.PreDestroy;
import jakarta.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
import java.util.List;
/**
*
* @author DongZeLiang
* @version 1.0
* @description
* @date 2023/11/9
*/
@Log4j2
@Configuration
public class VehicleConfigRunner implements ApplicationRunner {
@Autowired
private VehicleInfoService vehicleInfoService;
@Autowired
private VehicleInstanceService vehicleInstanceService;
@Autowired
private CustomTenantHandler customTenantHandler;
/**
*
*/
@Resource(name = "messageTemplateCache")
private Cache<Long, MessageTemplateCacheModel> messageTemplateCache;
/**
*
*/
@Autowired
private MessageTemplateService messageTemplateService;
/**
*
*/
@Autowired
private MessageTemplateValueService messageTemplateValueService;
public void initMessageTemplate() {
long startTime = System.currentTimeMillis();
log.info("开始初始化加载报文模板---------------");
messageTemplateService
.list()
.stream()
.map(messageTemplate -> MessageTemplateCacheModel.messageTemplateBuild(messageTemplate, messageTemplateValueService::valueListByMsgId))
.filter(model -> {
log.info(
"过滤校验报文模板[{}-{}] 报文值个数-[{}个] -- {}",
model.getKey(), model.getMessageName(), model.getMessageTemplateValueList().size(),
model.getMessageTemplateValueList().isEmpty() ? "不合格,已过滤" : "合格"
);
return !model.getMessageTemplateValueList().isEmpty();
})
.forEach(model -> messageTemplateCache.put(model.getKey(), model));
log.info("结束初始化加载报文模板耗时:[{}MS]---------------", System.currentTimeMillis() - startTime);
}
/**
*
*/
public void vehiclePageInit (){
long startTime = System.currentTimeMillis();
int page = 0, pageSize = 10;
log.info("初始开始,批量从数据库当中加载数据到内存当中,每次[{}]条", pageSize);
while (true){
Page<VehicleInfo> vehiclePage = vehicleInfoService.page(new Page<>(page++, pageSize));
List<VehicleInfo> vehicleInfoList = vehiclePage.getRecords();
vehicleInfoList.forEach(vehicleInstanceService::init);
log.debug("第[{}]页,[{}]条", page, vehicleInfoList.size());
if (vehicleInfoList.size() < pageSize){
break;
}
}
log.info("数据加载完成,耗时:{} MS", System.currentTimeMillis() - startTime);
}
@Override
public void run (ApplicationArguments args) {
customTenantHandler.ignore();
this.initMessageTemplate();
this.vehiclePageInit();
customTenantHandler.remove();
// 提交给线程池 一分钟 执行一次
// ThreadPool.submit(new Thread(vehicleService::syncDb), 30);
}
/**
*
*/
@PreDestroy
public void destroy(){
log.info("数据库同步");
vehicleInfoService.syncDb();
log.info("下线所有车辆");
List<VehicleInstance> onlineVehicleInstanceList = LocalContainer.getTenantOnlineVehicleInstance();
onlineVehicleInstanceList.forEach(VehicleInstance::closeClient);
log.info("关闭线程池");
ScheduledThreadPool.shutdown();
FixedThreadPool.shutDown();
}
}

View File

@ -1,48 +0,0 @@
package com.muyu.config.tenant;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.muyu.system.handle.SystemHandler;
import com.muyu.web.utils.Convert;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.Set;
@Component
public class CustomTenantHandler implements TenantLineHandler {
private static final ThreadLocal<Boolean> ignoreTableThreadLocal = new ThreadLocal<>();
public void ignore(){
ignoreTableThreadLocal.set(true);
}
public void remove(){
ignoreTableThreadLocal.remove();
}
private static final Set<String> ignoreTableSet = new HashSet<String>(){{
add("user_info");
}};
@Override
public Expression getTenantId() {
// 假设有一个租户上下文,能够从中获取当前用户的租户
String tenantId = SystemHandler.getTenantId();
// 返回租户ID的表达式LongValue 是 JSQLParser 中表示 bigint 类型的 class
return new StringValue(tenantId);
}
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public boolean ignoreTable(String tableName) {
// 根据需要返回是否忽略该表
return Convert.toBool(ignoreTableThreadLocal.get(), Boolean.FALSE) || ignoreTableSet.contains(tableName);
}
}

View File

@ -1,48 +0,0 @@
package com.muyu.system.constants;
/**
*
*
* @author muyu
*/
public class SecurityConstants {
/**
* ID
*/
public static final String DETAILS_USER_ID = "user_id";
/**
*
*/
public static final String DETAILS_USERNAME = "username";
/**
*
*/
public static final String AUTHORIZATION_HEADER = "authorization";
/**
*
*/
public static final String FROM_SOURCE = "from-source";
/**
*
*/
public static final String INNER = "inner";
/**
*
*/
public static final String USER_KEY = "user_key";
/**
*
*/
public static final String LOGIN_USER = "login_user";
/**
*
*/
public static final String ROLE_PERMISSION = "role_permission";
}

View File

@ -1,24 +0,0 @@
package com.muyu.system.constants;
/**
* TokenKey
*
* @author muyu
*/
public class TokenConstants {
/**
*
*/
public static final String AUTHENTICATION = "Authorization";
/**
*
*/
public static final String PREFIX = "Bearer ";
/**
*
*/
public final static String SECRET = "abcdefghijklmnsalieopadfaqawefwerstuvwxyz";
}

View File

@ -1,29 +0,0 @@
package com.muyu.system.context;
import com.muyu.system.domain.LoginUserInfo;
/**
* @Description:
* @author: MuYu
* @date: 2024/9/10-5:52
*/
public class SystemUserContext {
/**
* 线
*/
private static final ThreadLocal<LoginUserInfo> basicContextLocal = new ThreadLocal<>();
public static LoginUserInfo get() {
return basicContextLocal.get();
}
public static void set(LoginUserInfo value) {
basicContextLocal.set(value);
}
public static void remove() {
basicContextLocal.remove();
}
}

View File

@ -1,49 +0,0 @@
package com.muyu.system.domain;
import com.muyu.cache.ExpiryTime;
import com.muyu.system.properties.ServerConfigProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* @Description:
* @author: MuYu
* @date: 2024/9/11-10:15
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class LoginUserInfo extends ExpiryTime {
/**
* ID
*/
private Long id;
/**
* token
*/
private String userKey;
/**
*
*/
private String userName;
/**
* ID
*/
private String tenantId;
/**
*
*/
private ServerConfigProperties serverConfig;
}

View File

@ -1,44 +0,0 @@
package com.muyu.system.enums;
import java.util.Arrays;
/**
* @Author: DongZeLiang
* @date: 2024/9/20
* @Description:
* @Version: 1.0
*/
public enum MessageTemplateValueType {
FIXED("fixed", "固定"),
INTERVAL("interval", "区间"),
EL("el","表达式");
/**
*
*/
private final String code;
/**
*
*/
private final String label;
MessageTemplateValueType (String code, String label) {
this.code = code;
this.label = label;
}
public String code () {
return code;
}
public String label () {
return label;
}
public static MessageTemplateValueType get(String code){
return Arrays.stream(MessageTemplateValueType.values())
.filter(valueType -> valueType.code.equals(code))
.findFirst().orElse(null);
}
}

View File

@ -1,35 +0,0 @@
package com.muyu.system.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @Author: DongZeLiang
* @date: 2024/9/13
* @Description:
* @Version: 1.0
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class BasicException extends RuntimeException{
private final int code;
private final String msg;
/**
* Returns the detail message string of this throwable.
*
* @return the detail message string of this {@code Throwable} instance
* (which may be {@code null}).
*/
@Override
public String getMessage () {
return this.msg;
}
}

View File

@ -1,69 +0,0 @@
package com.muyu.system.handle;
import com.muyu.system.context.SystemUserContext;
import com.muyu.system.domain.LoginUserInfo;
import com.muyu.system.properties.ServerConfigProperties;
/**
* @Description:
* @author: MuYu
* @date: 2024/9/11-10:23
*/
public class SystemHandler {
/**
*
* @return
*/
public static LoginUserInfo getUserInfo(){
return SystemUserContext.get();
}
/**
* key
* @return Key
*/
public static String getUserKey(){
return getUserInfo().getUserKey();
}
/**
* ID
* @return ID
*/
public static Long getUserId(){
return getUserInfo().getId();
}
/**
*
* @return
*/
public static ServerConfigProperties getServerConfig(){
return SystemUserContext.get().getServerConfig();
}
/**
*
*/
public static void setServerConfig(ServerConfigProperties serverConfig){
SystemUserContext.get().setServerConfig(serverConfig);
}
/**
*
* @return
*/
public static String getLoadReqUrl(){
return getServerConfig().getLoadReqUrl();
}
/**
* ID
* @return ID
*/
public static String getTenantId () {
return getUserInfo().getTenantId();
}
}

View File

@ -1,100 +0,0 @@
package com.muyu.system.properties;
import com.muyu.web.domain.ServerConfig;
import com.muyu.web.domain.model.ServerConfigModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: DongZeLiang
* @date: 2024/6/10
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ServerConfigProperties {
/**
*
*/
private String host;
/**
*
*/
private String port;
/**
*
*/
private String uri;
/**
*
*/
private String loadReqUrl;
/**
* MQTT
*/
private String mqttAddr;
/**
* MQTT
*/
private String mqttTopic;
/**
* MQTT
*/
private Integer mqttQos;
/**
*
* @param serverConfigModel
* @return
*/
public static ServerConfigProperties modelToProperties(ServerConfigModel serverConfigModel) {
return ServerConfigProperties.builder()
.host(serverConfigModel.getHost())
.port(serverConfigModel.getPort())
.uri(serverConfigModel.getUri())
.mqttAddr(serverConfigModel.getDefaultMqttAddr())
.mqttTopic(serverConfigModel.getDefaultMqttTopic())
.mqttQos(serverConfigModel.getDefaultMqttQos())
.loadReqUrl(
String.format(
"http://%s:%s%s",
serverConfigModel.getHost(),
serverConfigModel.getPort(),
serverConfigModel.getUri().startsWith("/") ? serverConfigModel.getUri() : "/" + serverConfigModel.getUri()
)
)
.build();
}
/**
*
* @param serverConfig
* @return
*/
public static ServerConfigProperties configToProperties(ServerConfig serverConfig ) {
return ServerConfigProperties.builder()
.host(serverConfig.getHost())
.port(serverConfig.getPort())
.uri(serverConfig.getUri())
.mqttAddr(serverConfig.getDefaultMqttAddr())
.mqttTopic(serverConfig.getDefaultMqttTopic())
.mqttQos(serverConfig.getDefaultMqttQos())
.loadReqUrl(
String.format(
"http://%s:%s%s",
serverConfig.getHost(),
serverConfig.getPort(),
serverConfig.getUri().startsWith("/") ? serverConfig.getUri() : "/" + serverConfig.getUri()
)
)
.build();
}
}

View File

@ -1,39 +0,0 @@
package com.muyu.utils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class AesUtil {
private static final String key = "oLXZmx1h1nAo2G832yEceA==";
private static final String ALGORITHM = "AES";
private static final int KEY_SIZE = 128;
public static String generateKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
keyGenerator.init(KEY_SIZE);
SecretKey secretKey = keyGenerator.generateKey();
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
}
public static String encrypt(String data) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(key), ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String encryptedData) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(key), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
}

View File

@ -1,134 +0,0 @@
package com.muyu.utils;
/**
*
*
* @author muyu
*/
public class Constants {
/**
* UTF-8
*/
public static final String UTF8 = "UTF-8";
/**
* GBK
*/
public static final String GBK = "GBK";
/**
* www
*/
public static final String WWW = "www.";
/**
* RMI
*/
public static final String LOOKUP_RMI = "rmi:";
/**
* LDAP
*/
public static final String LOOKUP_LDAP = "ldap:";
/**
* LDAPS
*/
public static final String LOOKUP_LDAPS = "ldaps:";
/**
* http
*/
public static final String HTTP = "http://";
/**
* https
*/
public static final String HTTPS = "https://";
/**
*
*/
public static final Integer SUCCESS = 200;
/**
*
*/
public static final Integer FAIL = 500;
/**
*
*/
public static final String LOGIN_SUCCESS_STATUS = "0";
/**
*
*/
public static final String LOGIN_FAIL_STATUS = "1";
/**
*
*/
public static final String LOGIN_SUCCESS = "Success";
/**
*
*/
public static final String LOGOUT = "Logout";
/**
*
*/
public static final String REGISTER = "Register";
/**
*
*/
public static final String LOGIN_FAIL = "Error";
/**
*
*/
public static final String PAGE_NUM = "pageNum";
/**
*
*/
public static final String PAGE_SIZE = "pageSize";
/**
*
*/
public static final String ORDER_BY_COLUMN = "orderByColumn";
/**
* "desc" "asc".
*/
public static final String IS_ASC = "isAsc";
/**
*
*/
public static final long CAPTCHA_EXPIRATION = 2;
/**
*
*/
public static final String RESOURCE_PREFIX = "/profile";
/**
* json
*/
public static final String[] JSON_WHITELIST_STR = {"org.springframework", "com.muyu"};
/**
* 访
*/
public static final String[] JOB_WHITELIST_STR = {"com.muyu"};
/**
*
*/
public static final String[] JOB_ERROR_STR = {"java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.muyu.common.core.utils.file"};
}

View File

@ -1,45 +0,0 @@
package com.muyu.utils;
/**
* ID
*
* @author muyu
*/
public class IdUtils {
/**
* UUID
*
* @return UUID
*/
public static String randomUUID () {
return UUID.randomUUID().toString();
}
/**
* UUID线
*
* @return UUID线
*/
public static String simpleUUID () {
return UUID.randomUUID().toString(true);
}
/**
* UUID使ThreadLocalRandomUUID
*
* @return UUID
*/
public static String fastUUID () {
return UUID.fastUUID().toString();
}
/**
* UUID线使ThreadLocalRandomUUID
*
* @return UUID线
*/
public static String fastSimpleUUID () {
return UUID.fastUUID().toString(true);
}
}

View File

@ -1,165 +0,0 @@
package com.muyu.utils;
import com.muyu.system.constants.SecurityConstants;
import com.muyu.system.constants.TokenConstants;
import com.muyu.web.utils.Convert;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecureDigestAlgorithm;
import javax.crypto.SecretKey;
import java.util.Date;
import java.util.Map;
/**
* Jwt
*
* @author muyu
*/
public class JwtUtils {
/**
*
*/
private final static SecureDigestAlgorithm<SecretKey, SecretKey> ALGORITHM = Jwts.SIG.HS256;
/**
* / 使secret使
* secret, jwt
* 256(32)
*/
private final static String secret = TokenConstants.SECRET;
/**
*
*/
public static final SecretKey KEY = Keys.hmacShaKeyFor(secret.getBytes());
/**
* jwt
*/
private final static String JWT_ISS = "MUYU";
/**
* jwt
*/
private final static String SUBJECT = "Peripherals";
/**
*
*
* @param claims
*
* @return
*/
public static String createToken (Map<String, Object> claims) {
return Jwts.builder()
// 设置头部信息header
.header().add("typ", "JWT").add("alg", "HS256").and()
// 设置自定义负载信息payload
.claims(claims)
// 签发时间
.issuedAt(new Date())
// 主题
.subject(SUBJECT)
// 签发者
.issuer(JWT_ISS)
// 签名
.signWith(KEY, ALGORITHM)
.compact();
}
/**
*
*
* @param token
*
* @return
*/
public static Claims parseToken (String token) {
return Jwts.parser()
.verifyWith(KEY)
.build()
.parseSignedClaims(token)
.getPayload();
}
/**
*
*
* @param token
*
* @return ID
*/
public static String getUserKey (String token) {
Claims claims = parseToken(token);
return getValue(claims, SecurityConstants.USER_KEY);
}
/**
*
*
* @param claims
*
* @return ID
*/
public static String getUserKey (Claims claims) {
return getValue(claims, SecurityConstants.USER_KEY);
}
/**
* ID
*
* @param token
*
* @return ID
*/
public static String getUserId (String token) {
Claims claims = parseToken(token);
return getValue(claims, SecurityConstants.DETAILS_USER_ID);
}
/**
* ID
*
* @param claims
*
* @return ID
*/
public static String getUserId (Claims claims) {
return getValue(claims, SecurityConstants.DETAILS_USER_ID);
}
/**
*
*
* @param token
*
* @return
*/
public static String getUserName (String token) {
Claims claims = parseToken(token);
return getValue(claims, SecurityConstants.DETAILS_USERNAME);
}
/**
*
*
* @param claims
*
* @return
*/
public static String getUserName (Claims claims) {
return getValue(claims, SecurityConstants.DETAILS_USERNAME);
}
/**
*
*
* @param claims
* @param key
*
* @return
*/
public static String getValue (Claims claims, String key) {
return Convert.toStr(claims.get(key), "");
}
}

View File

@ -1,503 +0,0 @@
package com.muyu.utils;
import com.muyu.utils.text.StrFormatter;
import org.springframework.util.AntPathMatcher;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
*
*
* @author muyu
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils {
/**
*
*/
private static final String NULLSTR = "";
/**
* 线
*/
private static final char SEPARATOR = '_';
/**
*
*
* @param value defaultValue value
*
* @return value
*/
public static <T> T nvl (T value, T defaultValue) {
return value != null ? value : defaultValue;
}
/**
* * Collection ListSetQueue
*
* @param coll Collection
*
* @return true false
*/
public static boolean isEmpty (Collection<?> coll) {
return isNull(coll) || coll.isEmpty();
}
/**
* * CollectionListSetQueue
*
* @param coll Collection
*
* @return true false
*/
public static boolean isNotEmpty (Collection<?> coll) {
return !isEmpty(coll);
}
/**
* *
*
* @param objects
* * @return true false
*/
public static boolean isEmpty (Object[] objects) {
return isNull(objects) || (objects.length == 0);
}
/**
* *
*
* @param objects
*
* @return true false
*/
public static boolean isNotEmpty (Object[] objects) {
return !isEmpty(objects);
}
/**
* * Map
*
* @param map Map
*
* @return true false
*/
public static boolean isEmpty (Map<?, ?> map) {
return isNull(map) || map.isEmpty();
}
/**
* * Map
*
* @param map Map
*
* @return true false
*/
public static boolean isNotEmpty (Map<?, ?> map) {
return !isEmpty(map);
}
/**
* *
*
* @param str String
*
* @return true false
*/
public static boolean isEmpty (String str) {
return isNull(str) || NULLSTR.equals(str.trim());
}
/**
* *
*
* @param str String
*
* @return true false
*/
public static boolean isNotEmpty (String str) {
return !isEmpty(str);
}
/**
* *
*
* @param object Object
*
* @return true false
*/
public static boolean isNull (Object object) {
return object == null;
}
/**
* *
*
* @param object Object
*
* @return true false
*/
public static boolean isNotNull (Object object) {
return !isNull(object);
}
/**
* * Java
*
* @param object
*
* @return true false
*/
public static boolean isArray (Object object) {
return isNotNull(object) && object.getClass().isArray();
}
/**
*
*/
public static String trim (String str) {
return (str == null ? "" : str.trim());
}
/**
*
*
* @param str
* @param start
*
* @return
*/
public static String substring (final String str, int start) {
if (str == null) {
return NULLSTR;
}
if (start < 0) {
start = str.length() + start;
}
if (start < 0) {
start = 0;
}
if (start > str.length()) {
return NULLSTR;
}
return str.substring(start);
}
/**
*
*
* @param str
* @param start
* @param end
*
* @return
*/
public static String substring (final String str, int start, int end) {
if (str == null) {
return NULLSTR;
}
if (end < 0) {
end = str.length() + end;
}
if (start < 0) {
start = str.length() + start;
}
if (end > str.length()) {
end = str.length();
}
if (start > end) {
return NULLSTR;
}
if (start < 0) {
start = 0;
}
if (end < 0) {
end = 0;
}
return str.substring(start, end);
}
/**
*
*
* @param str value
*
* @return
*/
public static boolean hasText (String str) {
return (str != null && !str.isEmpty() && containsText(str));
}
private static boolean containsText (CharSequence str) {
int strLen = str.length();
for (int i = 0 ; i < strLen ; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return true;
}
}
return false;
}
/**
* , {} <br>
* {} <br>
* {} 使 \\ { {} \ 使 \\\\ <br>
* <br>
* 使format("this is {} for {}", "a", "b") -> this is a for b<br>
* {} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* \ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param template {}
* @param params
*
* @return
*/
public static String format (String template, Object... params) {
if (isEmpty(params) || isEmpty(template)) {
return template;
}
return StrFormatter.format(template, params);
}
/**
* http(s)://开头
*
* @param link
*
* @return
*/
public static boolean ishttp (String link) {
return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
}
/**
* collectionarray arrayvalue
*
* @param collection
* @param array
*
* @return boolean
*/
public static boolean containsAny (Collection<String> collection, String... array) {
if (isEmpty(collection) || isEmpty(array)) {
return false;
} else {
for (String str : array) {
if (collection.contains(str)) {
return true;
}
}
return false;
}
}
/**
* 线
*/
public static String toUnderScoreCase (String str) {
if (str == null) {
return null;
}
StringBuilder sb = new StringBuilder();
// 前置字符是否大写
boolean preCharIsUpperCase = true;
// 当前字符是否大写
boolean curreCharIsUpperCase = true;
// 下一字符是否大写
boolean nexteCharIsUpperCase = true;
for (int i = 0 ; i < str.length() ; i++) {
char c = str.charAt(i);
if (i > 0) {
preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
} else {
preCharIsUpperCase = false;
}
curreCharIsUpperCase = Character.isUpperCase(c);
if (i < (str.length() - 1)) {
nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
}
if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {
sb.append(SEPARATOR);
} else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) {
sb.append(SEPARATOR);
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
*
*
* @param str
* @param strs
*
* @return true
*/
public static boolean inStringIgnoreCase (String str, String... strs) {
if (str != null && strs != null) {
for (String s : strs) {
if (str.equalsIgnoreCase(trim(s))) {
return true;
}
}
}
return false;
}
/**
* 线线 HELLO_WORLD->HelloWorld
*
* @param name 线
*
* @return
*/
public static String convertToCamelCase (String name) {
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || name.isEmpty()) {
// 没必要转换
return "";
} else if (!name.contains("_")) {
// 不含下划线,仅将首字母大写
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
// 用下划线将原始字符串分割
String[] camels = name.split("_");
for (String camel : camels) {
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if (camel.isEmpty()) {
continue;
}
// 首字母大写
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
return result.toString();
}
/**
*
* user_name->userName
*/
public static String toCamelCase (String s) {
if (s == null) {
return null;
}
if (s.indexOf(SEPARATOR) == -1) {
return s;
}
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for (int i = 0 ; i < s.length() ; i++) {
char c = s.charAt(i);
if (c == SEPARATOR) {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
*
*
* @param str
* @param strs
*
* @return
*/
public static boolean matches (String str, List<String> strs) {
if (isEmpty(str) || isEmpty(strs)) {
return false;
}
for (String pattern : strs) {
if (isMatch(pattern, str)) {
return true;
}
}
return false;
}
/**
* url:
* ? ;
* * ;
* ** ;
*
* @param pattern
* @param url url
*
* @return
*/
public static boolean isMatch (String pattern, String url) {
AntPathMatcher matcher = new AntPathMatcher();
return matcher.match(pattern, url);
}
@SuppressWarnings("unchecked")
public static <T> T cast (Object obj) {
return (T) obj;
}
/**
* 0使size size
*
* @param num
* @param size
*
* @return
*/
public static final String padl (final Number num, final int size) {
return padl(num.toString(), size, '0');
}
/**
* ssizesize
*
* @param s
* @param size
* @param c
*
* @return
*/
public static final String padl (final String s, final int size, final char c) {
final StringBuilder sb = new StringBuilder(size);
if (s != null) {
final int len = s.length();
if (s.length() <= size) {
for (int i = size - len ; i > 0 ; i--) {
sb.append(c);
}
sb.append(s);
} else {
return s.substring(len - size, len);
}
} else {
for (int i = size ; i > 0 ; i--) {
sb.append(c);
}
}
return sb.toString();
}
}

View File

@ -1,468 +0,0 @@
package com.muyu.utils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.io.Serial;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
/**
* universally unique identifierUUID
*
* @author muyu
*/
public final class UUID implements java.io.Serializable, Comparable<UUID> {
@Serial
private static final long serialVersionUID = -1185015143654744140L;
/**
* UUID64
*/
private final long mostSigBits;
/**
* UUID64
*/
private final long leastSigBits;
/**
*
*
* @param data
*/
private UUID (@NotNull byte[] data) {
long msb = 0;
long lsb = 0;
assert data.length == 16 : "data must be 16 bytes in length";
for (int i = 0 ; i < 8 ; i++) {
msb = (msb << 8) | (data[i] & 0xff);
}
for (int i = 8 ; i < 16 ; i++) {
lsb = (lsb << 8) | (data[i] & 0xff);
}
this.mostSigBits = msb;
this.leastSigBits = lsb;
}
/**
* 使 UUID
*
* @param mostSigBits {@code UUID} 64
* @param leastSigBits {@code UUID} 64
*/
public UUID (long mostSigBits, long leastSigBits) {
this.mostSigBits = mostSigBits;
this.leastSigBits = leastSigBits;
}
/**
* 4UUID
*
* @return {@code UUID}
*/
@NotNull
@Contract(" -> new")
public static UUID fastUUID () {
return randomUUID(false);
}
/**
* 4UUID 使 UUID
*
* @return {@code UUID}
*/
@NotNull
@Contract(" -> new")
public static UUID randomUUID () {
return randomUUID(true);
}
/**
* 4UUID 使 UUID
*
* @param isSecure 使{@link SecureRandom}
*
* @return {@code UUID}
*/
@NotNull
@Contract("_ -> new")
public static UUID randomUUID (boolean isSecure) {
final Random ng = isSecure ? Holder.numberGenerator : getRandom();
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= (byte) 0x80; /* set to IETF variant */
return new UUID(randomBytes);
}
/**
* 3UUID
*
* @param name UUID
*
* @return {@code UUID}
*/
@NotNull
@Contract("_ -> new")
public static UUID nameUUIDFromBytes (byte[] name) {
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException nae) {
throw new InternalError("MD5 not supported");
}
byte[] md5Bytes = md.digest(name);
md5Bytes[6] &= 0x0f; /* clear version */
md5Bytes[6] |= 0x30; /* set to version 3 */
md5Bytes[8] &= 0x3f; /* clear variant */
md5Bytes[8] |= (byte) 0x80; /* set to IETF variant */
return new UUID(md5Bytes);
}
/**
* {@link #toString()} {@code UUID}
*
* @param name {@code UUID}
*
* @return {@code UUID}
*
* @throws IllegalArgumentException name {@link #toString}
*/
@NotNull
@Contract("_ -> new")
public static UUID fromString (String name) {
String[] components = name.split("-");
if (components.length != 5) {
throw new IllegalArgumentException("Invalid UUID string: " + name);
}
for (int i = 0 ; i < 5 ; i++) {
components[i] = "0x" + components[i];
}
long mostSigBits = Long.decode(components[0]);
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[1]);
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[2]);
long leastSigBits = Long.decode(components[3]);
leastSigBits <<= 48;
leastSigBits |= Long.decode(components[4]);
return new UUID(mostSigBits, leastSigBits);
}
/**
* hex
*
* @param val
* @param digits
*
* @return
*/
@NotNull
private static String digits (long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
/**
* {@link SecureRandom} (RNG)
*
* @return {@link SecureRandom}
*/
@NotNull
public static SecureRandom getSecureRandom () {
try {
return SecureRandom.getInstance("SHA1PRNG");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* <br>
* ThreadLocalRandomJDK 7线
*
* @return {@link ThreadLocalRandom}
*/
public static ThreadLocalRandom getRandom () {
return ThreadLocalRandom.current();
}
/**
* UUID 128 64
*
* @return UUID 128 64
*/
public long getLeastSignificantBits () {
return leastSigBits;
}
/**
* UUID 128 64
*
* @return UUID 128 64
*/
public long getMostSignificantBits () {
return mostSigBits;
}
/**
* {@code UUID} . {@code UUID}
* <p>
* :
* <ul>
* <li>1 UUID
* <li>2 DCE UUID
* <li>3 UUID
* <li>4 UUID
* </ul>
*
* @return {@code UUID}
*/
public int version () {
// Version is bits masked by 0x000000000000F000 in MS long
return (int) ((mostSigBits >> 12) & 0x0f);
}
/**
* {@code UUID} {@code UUID}
* <p>
*
* <ul>
* <li>0 NCS
* <li>2 <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF&nbsp;RFC&nbsp;4122</a>(Leach-Salz),
* <li>6
* <li>7 使
* </ul>
*
* @return {@code UUID}
*/
public int variant () {
// This field is composed of a varying number of bits.
// 0 - - Reserved for NCS backward compatibility
// 1 0 - The IETF aka Leach-Salz variant (used by this class)
// 1 1 0 Reserved, Microsoft backward compatibility
// 1 1 1 Reserved for future definition.
return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63));
}
/**
* UUID
*
* <p>
* 60 {@code UUID} time_lowtime_mid time_hi <br>
* 100 UTC 1582 10 15
*
* <p>
* UUID version 1<br>
* {@code UUID} UUID UnsupportedOperationException
*
* @throws UnsupportedOperationException {@code UUID} version 1 UUID
*/
public long timestamp () throws UnsupportedOperationException {
checkTimeBase();
return (mostSigBits & 0x0FFFL) << 48//
| ((mostSigBits >> 16) & 0x0FFFFL) << 32//
| mostSigBits >>> 32;
}
/**
* UUID
*
* <p>
* 14 UUID clock_seq clock_seq UUID
* <p>
* {@code clockSequence} UUID version 1 UUID UUID
* UnsupportedOperationException
*
* @return {@code UUID}
*
* @throws UnsupportedOperationException UUID version 1
*/
public int clockSequence () throws UnsupportedOperationException {
checkTimeBase();
return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48);
}
/**
* UUID
*
* <p>
* 48 UUID node IEEE 802 UUID
* <p>
* UUID version 1<br>
* UUID UUID UnsupportedOperationException
*
* @return {@code UUID}
*
* @throws UnsupportedOperationException UUID version 1
*/
public long node () throws UnsupportedOperationException {
checkTimeBase();
return leastSigBits & 0x0000FFFFFFFFFFFFL;
}
/**
* {@code UUID}
*
* <p>
* UUID BNF
*
* <pre>
* {@code
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
* time_low = 4*<hexOctet>
* time_mid = 2*<hexOctet>
* time_high_and_version = 2*<hexOctet>
* variant_and_sequence = 2*<hexOctet>
* node = 6*<hexOctet>
* hexOctet = <hexDigit><hexDigit>
* hexDigit = [0-9a-fA-F]
* }
* </pre>
*
* </blockquote>
*
* @return {@code UUID}
*
* @see #toString(boolean)
*/
@NotNull
@Override
public String toString () {
return toString(false);
}
/**
* {@code UUID}
*
* <p>
* UUID BNF
*
* <pre>
* {@code
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
* time_low = 4*<hexOctet>
* time_mid = 2*<hexOctet>
* time_high_and_version = 2*<hexOctet>
* variant_and_sequence = 2*<hexOctet>
* node = 6*<hexOctet>
* hexOctet = <hexDigit><hexDigit>
* hexDigit = [0-9a-fA-F]
* }
* </pre>
*
* </blockquote>
*
* @param isSimple '-'UUID
*
* @return {@code UUID}
*/
@NotNull
public String toString (boolean isSimple) {
final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36);
// time_low
builder.append(digits(mostSigBits >> 32, 8));
if (!isSimple) {
builder.append('-');
}
// time_mid
builder.append(digits(mostSigBits >> 16, 4));
if (!isSimple) {
builder.append('-');
}
// time_high_and_version
builder.append(digits(mostSigBits, 4));
if (!isSimple) {
builder.append('-');
}
// variant_and_sequence
builder.append(digits(leastSigBits >> 48, 4));
if (!isSimple) {
builder.append('-');
}
// node
builder.append(digits(leastSigBits, 12));
return builder.toString();
}
// Comparison Operations
/**
* UUID
*
* @return UUID
*/
@Override
public int hashCode () {
long hilo = mostSigBits ^ leastSigBits;
return ((int) (hilo >> 32)) ^ (int) hilo;
}
// -------------------------------------------------------------------------------------------------------------------
// Private method start
/**
*
* <p>
* {@code null} UUID UUID varriant {@code true}
*
* @param obj
*
* @return {@code true} {@code false}
*/
@Override
public boolean equals (Object obj) {
if ((null == obj) || (obj.getClass() != UUID.class)) {
return false;
}
UUID id = (UUID) obj;
return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits);
}
/**
* UUID UUID
*
* <p>
* UUID UUID UUID UUID UUID
*
* @param val UUID UUID
*
* @return UUID val -10 1
*/
@Override
public int compareTo (UUID val) {
// The ordering is intentionally set up so that the UUIDs
// can simply be numerically compared as two numbers
//
//
return (this.mostSigBits < val.mostSigBits ? -1 : //
(this.mostSigBits > val.mostSigBits ? 1 : //
(Long.compare(this.leastSigBits, val.leastSigBits))));
}
/**
* time-basedUUID
*/
private void checkTimeBase () {
if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID");
}
}
/**
* SecureRandom
*/
private static class Holder {
static final SecureRandom numberGenerator = getSecureRandom();
}
}

View File

@ -1,95 +0,0 @@
package com.muyu.utils.text;
import com.muyu.utils.StringUtils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
*
*
* @author muyu
*/
public class CharsetKit {
/**
* ISO-8859-1
*/
public static final String ISO_8859_1 = "ISO-8859-1";
/**
* UTF-8
*/
public static final String UTF_8 = "UTF-8";
/**
* GBK
*/
public static final String GBK = "GBK";
/**
* ISO-8859-1
*/
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
/**
* UTF-8
*/
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
/**
* GBK
*/
public static final Charset CHARSET_GBK = Charset.forName(GBK);
/**
* Charset
*
* @param charset
*
* @return Charset
*/
public static Charset charset (String charset) {
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
}
/**
*
*
* @param source
* @param srcCharset ISO-8859-1
* @param destCharset UTF-8
*
* @return
*/
public static String convert (String source, String srcCharset, String destCharset) {
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
}
/**
*
*
* @param source
* @param srcCharset ISO-8859-1
* @param destCharset UTF-8
*
* @return
*/
public static String convert (String source, Charset srcCharset, Charset destCharset) {
if (null == srcCharset) {
srcCharset = StandardCharsets.ISO_8859_1;
}
if (null == destCharset) {
destCharset = StandardCharsets.UTF_8;
}
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) {
return source;
}
return new String(source.getBytes(srcCharset), destCharset);
}
/**
* @return
*/
public static String systemCharset () {
return Charset.defaultCharset().name();
}
}

View File

@ -1,904 +0,0 @@
package com.muyu.utils.text;
import com.muyu.utils.StringUtils;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.text.NumberFormat;
import java.util.Set;
/**
*
*
* @author muyu
*/
public class Convert {
/**
* <br>
* null<br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static String toStr (Object value, String defaultValue) {
if (null == value) {
return defaultValue;
}
if (value instanceof String) {
return (String) value;
}
return value.toString();
}
/**
* <br>
* <code>null</code><code>null</code><br>
*
*
* @param value
*
* @return
*/
public static String toStr (Object value) {
return toStr(value, null);
}
/**
* <br>
* null<br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static Character toChar (Object value, Character defaultValue) {
if (null == value) {
return defaultValue;
}
if (value instanceof Character) {
return (Character) value;
}
final String valueStr = toStr(value, null);
return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);
}
/**
* <br>
* <code>null</code><code>null</code><br>
*
*
* @param value
*
* @return
*/
public static Character toChar (Object value) {
return toChar(value, null);
}
/**
* byte<br>
* <code>null</code><br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static Byte toByte (Object value, Byte defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Byte) {
return (Byte) value;
}
if (value instanceof Number) {
return ((Number) value).byteValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return Byte.parseByte(valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* byte<br>
* <code>null</code><code>null</code><br>
*
*
* @param value
*
* @return
*/
public static Byte toByte (Object value) {
return toByte(value, null);
}
/**
* Short<br>
* <code>null</code><br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static Short toShort (Object value, Short defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Short) {
return (Short) value;
}
if (value instanceof Number) {
return ((Number) value).shortValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return Short.parseShort(valueStr.trim());
} catch (Exception e) {
return defaultValue;
}
}
/**
* Short<br>
* <code>null</code><code>null</code><br>
*
*
* @param value
*
* @return
*/
public static Short toShort (Object value) {
return toShort(value, null);
}
/**
* Number<br>
* <br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static Number toNumber (Object value, Number defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Number) {
return (Number) value;
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return NumberFormat.getInstance().parse(valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* Number<br>
* <code>null</code><br>
*
*
* @param value
*
* @return
*/
public static Number toNumber (Object value) {
return toNumber(value, null);
}
/**
* int<br>
* <br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static Integer toInt (Object value, Integer defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Integer) {
return (Integer) value;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return Integer.parseInt(valueStr.trim());
} catch (Exception e) {
return defaultValue;
}
}
/**
* int<br>
* <code>null</code><code>null</code><br>
*
*
* @param value
*
* @return
*/
public static Integer toInt (Object value) {
return toInt(value, null);
}
/**
* Integer<br>
*
* @param str
*
* @return
*/
public static Integer[] toIntArray (String str) {
return toIntArray(",", str);
}
/**
* Long<br>
*
* @param str
*
* @return
*/
public static Long[] toLongArray (String str) {
return toLongArray(",", str);
}
/**
* Integer<br>
*
* @param split
* @param str
*
* @return
*/
public static Integer[] toIntArray (String split, String str) {
if (StringUtils.isEmpty(str)) {
return new Integer[]{};
}
String[] arr = str.split(split);
final Integer[] ints = new Integer[arr.length];
for (int i = 0 ; i < arr.length ; i++) {
final Integer v = toInt(arr[i], 0);
ints[i] = v;
}
return ints;
}
/**
* Long<br>
*
* @param split
* @param str
*
* @return
*/
public static Long[] toLongArray (String split, String str) {
if (StringUtils.isEmpty(str)) {
return new Long[]{};
}
String[] arr = str.split(split);
final Long[] longs = new Long[arr.length];
for (int i = 0 ; i < arr.length ; i++) {
final Long v = toLong(arr[i], null);
longs[i] = v;
}
return longs;
}
/**
* String<br>
*
* @param str
*
* @return
*/
public static String[] toStrArray (String str) {
return toStrArray(",", str);
}
/**
* String<br>
*
* @param split
* @param str
*
* @return
*/
public static String[] toStrArray (String split, String str) {
return str.split(split);
}
/**
* long<br>
* <br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static Long toLong (Object value, Long defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Long) {
return (Long) value;
}
if (value instanceof Number) {
return ((Number) value).longValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
// 支持科学计数法
return new BigDecimal(valueStr.trim()).longValue();
} catch (Exception e) {
return defaultValue;
}
}
/**
* long<br>
* <code>null</code><code>null</code><br>
*
*
* @param value
*
* @return
*/
public static Long toLong (Object value) {
return toLong(value, null);
}
/**
* double<br>
* <br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static Double toDouble (Object value, Double defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Double) {
return (Double) value;
}
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
// 支持科学计数法
return new BigDecimal(valueStr.trim()).doubleValue();
} catch (Exception e) {
return defaultValue;
}
}
/**
* double<br>
* <code>null</code><br>
*
*
* @param value
*
* @return
*/
public static Double toDouble (Object value) {
return toDouble(value, null);
}
/**
* Float<br>
* <br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static Float toFloat (Object value, Float defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Float) {
return (Float) value;
}
if (value instanceof Number) {
return ((Number) value).floatValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return Float.parseFloat(valueStr.trim());
} catch (Exception e) {
return defaultValue;
}
}
/**
* Float<br>
* <code>null</code><br>
*
*
* @param value
*
* @return
*/
public static Float toFloat (Object value) {
return toFloat(value, null);
}
/**
* boolean<br>
* Stringtruefalseyesokno1,0 <br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static Boolean toBool (Object value, Boolean defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Boolean) {
return (Boolean) value;
}
String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
valueStr = valueStr.trim().toLowerCase();
switch (valueStr) {
case "true":
case "yes":
case "ok":
case "1":
return true;
case "false":
case "no":
case "0":
return false;
default:
return defaultValue;
}
}
/**
* boolean<br>
* <code>null</code><br>
*
*
* @param value
*
* @return
*/
public static Boolean toBool (Object value) {
return toBool(value, null);
}
/**
* Enum<br>
* <br>
*
* @param clazz EnumClass
* @param value
* @param defaultValue
*
* @return Enum
*/
public static <E extends Enum<E>> E toEnum (Class<E> clazz, Object value, E defaultValue) {
if (value == null) {
return defaultValue;
}
if (clazz.isAssignableFrom(value.getClass())) {
@SuppressWarnings("unchecked")
E myE = (E) value;
return myE;
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return Enum.valueOf(clazz, valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* Enum<br>
* <code>null</code><br>
*
* @param clazz EnumClass
* @param value
*
* @return Enum
*/
public static <E extends Enum<E>> E toEnum (Class<E> clazz, Object value) {
return toEnum(clazz, value, null);
}
/**
* BigInteger<br>
* <br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static BigInteger toBigInteger (Object value, BigInteger defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof BigInteger) {
return (BigInteger) value;
}
if (value instanceof Long) {
return BigInteger.valueOf((Long) value);
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return new BigInteger(valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* BigInteger<br>
* <code>null</code><br>
*
*
* @param value
*
* @return
*/
public static BigInteger toBigInteger (Object value) {
return toBigInteger(value, null);
}
/**
* BigDecimal<br>
* <br>
*
*
* @param value
* @param defaultValue
*
* @return
*/
public static BigDecimal toBigDecimal (Object value, BigDecimal defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof BigDecimal) {
return (BigDecimal) value;
}
if (value instanceof Long) {
return new BigDecimal((Long) value);
}
if (value instanceof Double) {
return BigDecimal.valueOf((Double) value);
}
if (value instanceof Integer) {
return new BigDecimal((Integer) value);
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return new BigDecimal(valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* BigDecimal<br>
* <br>
*
*
* @param value
*
* @return
*/
public static BigDecimal toBigDecimal (Object value) {
return toBigDecimal(value, null);
}
/**
* <br>
* 1ByteByteBuffer 2Arrays.toString
*
* @param obj
*
* @return
*/
public static String utf8Str (Object obj) {
return str(obj, CharsetKit.CHARSET_UTF_8);
}
/**
* <br>
* 1ByteByteBuffer 2Arrays.toString
*
* @param obj
* @param charsetName
*
* @return
*/
public static String str (Object obj, String charsetName) {
return str(obj, Charset.forName(charsetName));
}
/**
* <br>
* 1ByteByteBuffer 2Arrays.toString
*
* @param obj
* @param charset
*
* @return
*/
public static String str (Object obj, Charset charset) {
if (null == obj) {
return null;
}
if (obj instanceof String) {
return (String) obj;
} else if (obj instanceof byte[] || obj instanceof Byte[]) {
if (obj instanceof byte[]) {
return str((byte[]) obj, charset);
} else {
Byte[] bytes = (Byte[]) obj;
int length = bytes.length;
byte[] dest = new byte[length];
for (int i = 0 ; i < length ; i++) {
dest[i] = bytes[i];
}
return str(dest, charset);
}
} else if (obj instanceof ByteBuffer) {
return str((ByteBuffer) obj, charset);
}
return obj.toString();
}
/**
* byte
*
* @param bytes byte
* @param charset
*
* @return
*/
public static String str (byte[] bytes, String charset) {
return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));
}
/**
*
*
* @param data
* @param charset
*
* @return
*/
public static String str (byte[] data, Charset charset) {
if (data == null) {
return null;
}
if (null == charset) {
return new String(data);
}
return new String(data, charset);
}
/**
* byteBuffer
*
* @param data
* @param charset 使
*
* @return
*/
public static String str (ByteBuffer data, String charset) {
if (data == null) {
return null;
}
return str(data, Charset.forName(charset));
}
/**
* byteBuffer
*
* @param data
* @param charset 使
*
* @return
*/
public static String str (ByteBuffer data, Charset charset) {
if (null == charset) {
charset = Charset.defaultCharset();
}
return charset.decode(data).toString();
}
// ----------------------------------------------------------------------- 全角半角转换
/**
*
*
* @param input String.
*
* @return .
*/
public static String toSBC (String input) {
return toSBC(input, null);
}
/**
*
*
* @param input String
* @param notConvertSet
*
* @return .
*/
public static String toSBC (String input, Set<Character> notConvertSet) {
char[] c = input.toCharArray();
for (int i = 0 ; i < c.length ; i++) {
if (null != notConvertSet && notConvertSet.contains(c[i])) {
// 跳过不替换的字符
continue;
}
if (c[i] == ' ') {
c[i] = '\u3000';
} else if (c[i] < '\177') {
c[i] = (char) (c[i] + 65248);
}
}
return new String(c);
}
/**
*
*
* @param input String.
*
* @return
*/
public static String toDBC (String input) {
return toDBC(input, null);
}
/**
*
*
* @param text
* @param notConvertSet
*
* @return
*/
public static String toDBC (String text, Set<Character> notConvertSet) {
char[] c = text.toCharArray();
for (int i = 0 ; i < c.length ; i++) {
if (null != notConvertSet && notConvertSet.contains(c[i])) {
// 跳过不替换的字符
continue;
}
if (c[i] == '\u3000') {
c[i] = ' ';
} else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
c[i] = (char) (c[i] - 65248);
}
}
return new String(c);
}
/**
*
*
* @param n
*
* @return
*/
public static String digitUppercase (double n) {
String[] fraction = {"角", "分"};
String[] digit = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
String[][] unit = {{"元", "万", "亿"}, {"", "拾", "佰", "仟"}};
String head = n < 0 ? "负" : "";
n = Math.abs(n);
String s = "";
for (int i = 0 ; i < fraction.length ; i++) {
// 优化double计算精度丢失问题
BigDecimal nNum = new BigDecimal(n);
BigDecimal decimal = new BigDecimal(10);
BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN);
double d = scale.doubleValue();
s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
}
if (s.length() < 1) {
s = "整";
}
int integerPart = (int) Math.floor(n);
for (int i = 0 ; i < unit[0].length && integerPart > 0 ; i++) {
String p = "";
for (int j = 0 ; j < unit[1].length && n > 0 ; j++) {
p = digit[integerPart % 10] + unit[1][j] + p;
integerPart = integerPart / 10;
}
s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
}
return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
}
}

View File

@ -1,78 +0,0 @@
package com.muyu.utils.text;
import com.muyu.utils.StringUtils;
/**
*
*
* @author muyu
*/
public class StrFormatter {
public static final String EMPTY_JSON = "{}";
public static final char C_BACKSLASH = '\\';
public static final char C_DELIM_START = '{';
public static final char C_DELIM_END = '}';
/**
* <br>
* {} <br>
* {} 使 \\ { {} \ 使 \\\\ <br>
* <br>
* 使format("this is {} for {}", "a", "b") -> this is a for b<br>
* {} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* \ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param strPattern
* @param argArray
*
* @return
*/
public static String format (final String strPattern, final Object... argArray) {
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) {
return strPattern;
}
final int strPatternLength = strPattern.length();
// 初始化定义好的长度以获得更好的性能
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
int handledPosition = 0;
int delimIndex;// 占位符所在位置
for (int argIndex = 0 ; argIndex < argArray.length ; argIndex++) {
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
if (delimIndex == -1) {
if (handledPosition == 0) {
return strPattern;
} else { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
sbuf.append(strPattern, handledPosition, strPatternLength);
return sbuf.toString();
}
} else {
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) {
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) {
// 转义符之前还有一个转义符,占位符依旧有效
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
} else {
// 占位符被转义
argIndex--;
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(C_DELIM_START);
handledPosition = delimIndex + 1;
}
} else {
// 正常占位符
sbuf.append(strPattern, handledPosition, delimIndex);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
}
}
// 加入最后一个占位符后所有的字符
sbuf.append(strPattern, handledPosition, strPattern.length());
return sbuf.toString();
}
}

View File

@ -1,20 +1,16 @@
package com.muyu.vehicle;
import com.alibaba.fastjson2.JSONObject;
import com.muyu.cache.model.MessageTemplateCacheModel;
import com.muyu.system.enums.MessageTemplateValueType;
import com.muyu.utils.StringUtils;
import com.muyu.vehicle.model.VehicleData;
import com.muyu.vehicle.model.properties.MqttProperties;
import com.muyu.vehicle.thread.VehicleThread;
import com.muyu.web.common.SystemConstant;
import com.muyu.web.common.pool.ScheduledThreadPool;
import com.muyu.web.domain.MessageTemplateValue;
import com.muyu.web.domain.VehicleInfo;
import com.muyu.web.domain.Vehicle;
import com.muyu.web.domain.model.PositionModel;
import com.muyu.web.utils.CalculateCheckDigit;
import com.muyu.web.utils.ConversionUtil;
import com.muyu.web.utils.VehicleUtils;
import com.muyu.vehicle.model.VehicleData;
import com.muyu.vehicle.model.properties.MqttProperties;
import com.muyu.vehicle.thread.VehicleThread;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -28,7 +24,6 @@ import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingQueue;
@ -57,19 +52,11 @@ public class VehicleInstance {
/**
*
*/
@Builder.Default
private LinkedBlockingQueue<PositionModel> positionQueue = new LinkedBlockingQueue<>();
/**
*
*/
private VehicleInfo vehicleInfo;
/**
*
*/
private MessageTemplateCacheModel messageTemplate;
private Vehicle vehicle;
/**
*
*/
@ -94,7 +81,7 @@ public class VehicleInstance {
/**
*
*/
private MqttClient client;
private MqttClient client = null;
/**
@ -108,15 +95,7 @@ public class VehicleInstance {
* @return VIN
*/
public String getVin() {
return this.vehicleInfo.getVin();
}
/**
*
* @return ID
*/
public String getTenantId(){
return this.vehicleInfo.getTenantId();
return this.vehicle.getVin();
}
/**
@ -160,12 +139,6 @@ public class VehicleInstance {
client.connect(options);
log.debug("车辆:[{}] 客户端初始化成功连接配置:{}", getVin(),
JSONObject.toJSONString(this.mqttProperties));
VehicleThread vehicleThread = new VehicleThread();
vehicleThread.setVehicleInstance(this);
this.setVehicleThread(vehicleThread);
ScheduledFuture<?> scheduledFuture = ScheduledThreadPool.submit(vehicleThread);
this.setScheduledFuture(scheduledFuture);
log.info("初始化车辆上报模拟线程开始:[{}]", this.getVin());
} catch (MqttException e) {
log.error("车辆:[{}] 客户端初始化异常", getVin(), e);
throw new RuntimeException(e);
@ -206,9 +179,6 @@ public class VehicleInstance {
log.error("车辆:[{}] 客户端关闭异常:[{}]",getVin(), e.getMessage(), e);
}
}
if (this.vehicleThread != null){
this.vehicleThread.stop();
}
}
/**
@ -221,6 +191,46 @@ public class VehicleInstance {
log.info("车辆:{} 设置路径成功", this.getVin());
}
/**
* 线
*/
public void initVehicleThread() {
if (this.positionCode == null){
throw new RuntimeException("车辆["+getVin()+"]未选中路径");
}
if (!isOnline()){
throw new RuntimeException("车辆["+getVin()+"]未和服务器建立链接");
}
VehicleThread vehicleThread = new VehicleThread();
vehicleThread.setVehicleInstance(this);
this.setVehicleThread(vehicleThread);
ScheduledFuture<?> scheduledFuture = ScheduledThreadPool.submit(vehicleThread);
this.setScheduledFuture(scheduledFuture);
log.info("初始化车辆上报模拟线程开始:[{}]", this.getVin());
}
/**
* 线
*/
public void startSend() {
this.msgCode = "上报";
if (this.vehicleThread != null){
this.vehicleThread.resume();
}
log.info("车辆[{}],开始上报", this.getVin());
}
/**
* 线
*/
public void pauseSend() {
this.msgCode = "暂停";
if (this.vehicleThread != null) {
this.vehicleThread.pause();
}
log.info("车辆[{}],暂停上报", this.getVin());
}
/**
*
*/
@ -244,48 +254,31 @@ public class VehicleInstance {
/**
*
*/
public void imitateData() {
public String imitateData() {
String gear = this.vehicleData.getGear();
if (!"D".equals(gear)){
log.info("车辆不是动车档位,不进行模拟数据");
return null;
}
// 获取上一次定位点
PositionModel lastPositionModel = this.lastPosition == null ? positionQueue.poll() : this.lastPosition;
// 获取当前定位点
PositionModel currentPositionModel = positionQueue.poll();
if (currentPositionModel == null) {
currentPositionModel = PositionModel.builder()
.latitude(this.vehicleInfo.getLastLatitude())
.longitude(this.vehicleInfo.getLastLongitude())
.build();
}else {
this.vehicleInfo.setLastLatitude(currentPositionModel.getLatitude());
this.vehicleInfo.setLastLongitude(currentPositionModel.getLongitude());
}
if (lastPositionModel == null){
lastPositionModel = currentPositionModel;
return "表示当前定位点已经跑完,需要其他操作";
}
// 两点之间的距离
BigDecimal distance = null;
if (currentPositionModel != null) {
distance = VehicleUtils.distance(Objects.requireNonNull(lastPositionModel), currentPositionModel);
}
if (lastPositionModel == currentPositionModel){
distance = new BigDecimal("0.01");
}
BigDecimal distance = VehicleUtils.distance(lastPositionModel, currentPositionModel);
// 车辆总里程 相加
vehicleData.setMileage(vehicleData.getMileage().add(distance));
// 定位点填写
vehicleData.setLongitude(
currentPositionModel == null || currentPositionModel.getLongitude() == null ? this.vehicleInfo.getLastLongitude() : currentPositionModel.getLongitude()
);
vehicleData.setLatitude(
currentPositionModel == null || currentPositionModel.getLatitude() == null ? this.vehicleInfo.getLastLatitude() : currentPositionModel.getLatitude()
);
vehicleData.setLongitude(currentPositionModel.getLongitude());
vehicleData.setLatitude(currentPositionModel.getLatitude());
// 当前电量减少
// 电池浮动
BigDecimal batteryFloat = VehicleUtils.batteryFloat();
// 百公里占比
BigDecimal hundredKMScale = null;
if (distance != null) {
hundredKMScale = distance.divide(SystemConstant.hundredKilometers).setScale(3, RoundingMode.HALF_UP);
}
BigDecimal hundredKMScale = distance.divide(SystemConstant.hundredKilometers).setScale(3, RoundingMode.HALF_UP);
// 使用电量
BigDecimal powerUsage = powerConsumption.multiply(hundredKMScale)
.multiply(batteryFloat)
@ -297,43 +290,15 @@ public class VehicleInstance {
powerConsumption.multiply(batteryFloat).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_UP).toString()
);
// 计算总速度
if (distance != null) {
vehicleData.setSpeed(
distance.divide(new BigDecimal(2))
.multiply(new BigDecimal("3600"))
.setScale(2, RoundingMode.HALF_UP).toString()
);
}
List<MessageTemplateValue> messageTemplateValueList
= this.messageTemplate.getMessageTemplateValueList();
if (messageTemplateValueList != null){
for (MessageTemplateValue messageTemplateValue : messageTemplateValueList) {
String valueType = messageTemplateValue.getValueType();
MessageTemplateValueType messageTemplateValueType
= MessageTemplateValueType.get(valueType);
switch (messageTemplateValueType){
// 固定值
case FIXED -> {
String fixedValue = messageTemplateValue.getFixedValue();
String[] split = fixedValue.split(",");
vehicleData.putData(messageTemplateValue.getCode(), split[0]);
}
// 区间值
case INTERVAL -> {
vehicleData.putData(
messageTemplateValue.getCode(),
vehicleData.getValue(
vehicleData.genValue(
messageTemplateValue.getMinValue(),
messageTemplateValue.getMaxValue()
),
messageTemplateValue.getLength()
)
);
}
}
}
}
vehicleData.setSpeed(
distance.divide(new BigDecimal(2))
.multiply(new BigDecimal("3600"))
.setScale(2, RoundingMode.HALF_UP).toString()
);
vehicleData.imitateBase();
vehicleData.imitateMotor();
vehicleData.imitateBatteryPack();
return null;
}
/**
@ -344,38 +309,4 @@ public class VehicleInstance {
this.vehicleData.setGear(gear);
}
public String imitateDataAndMsg () {
this.imitateData();
List<MessageTemplateValue> messageTemplateValueList
= this.messageTemplate.getMessageTemplateValueList();
StringBuilder elBuilder = new StringBuilder();
messageTemplateValueList.stream()
.filter(MessageTemplateValue::isEl)
.sorted(Comparator.comparing(MessageTemplateValue::getStartLocation))
.forEach(value -> {
String elValue = value.getElValue();
switch (elValue){
case "this.vin" -> elBuilder.append(this.vehicleData.getVin());
case "this.latitude" -> elBuilder.append(this.vehicleData.getLatitude());
case "this.longitude" -> elBuilder.append(this.vehicleData.getLongitude());
case "this.timeMillis" -> elBuilder.append(System.currentTimeMillis());
}
});
StringBuilder fixedBuilder = new StringBuilder();
messageTemplateValueList.stream()
.filter(MessageTemplateValue::isFixed)
.sorted(Comparator.comparing(MessageTemplateValue::getStartLocation))
.forEach(value -> fixedBuilder.append(this.vehicleData.getData(value.getCode())));
StringBuilder intervalBuilder = new StringBuilder();
messageTemplateValueList.stream()
.filter(MessageTemplateValue::isInterval)
.sorted(Comparator.comparing(MessageTemplateValue::getStartLocation))
.forEach(value -> intervalBuilder.append(this.vehicleData.getData(value.getCode())));
return StringUtils.format(
"{}#{}#{}~{}{}{}",
elBuilder.length(), fixedBuilder.length(), intervalBuilder.length(),
elBuilder.toString(), fixedBuilder.toString(), intervalBuilder.toString()
);
}
}

View File

@ -19,8 +19,10 @@ public interface ClientAdmin {
* @return
*/
@Post(
url = "{vehicleLoadUrl}",
interceptor = SimpleInterceptor.class
url = "{vehicleLoadUrl}"/*,
headers = {
"X-co-il: DH5I9OIG+N=="
}*/
)
public Result<MqttServerModel> getVehicleLoadAddr ( @JSONBody VehicleConnectionReq vehicleConnectionReq);
}

View File

@ -1,28 +0,0 @@
package com.muyu.vehicle.api;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.interceptor.Interceptor;
import com.muyu.system.constants.TokenConstants;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Log4j2
@Component
public class SimpleInterceptor<T> implements Interceptor<T> {
@Autowired
private HttpServletRequest request;
/**
* , false
* @Param request Forest
*/
@Override
public boolean beforeExecute(ForestRequest req) {
// 执行在发送请求之前处理的代码
req.addHeader(TokenConstants.AUTHENTICATION, request.getHeader(TokenConstants.AUTHENTICATION)); // 添加Header
return true; // 继续执行请求返回true
}
}

View File

@ -1,6 +1,6 @@
package com.muyu.vehicle.api.req;
import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@ -1,12 +1,11 @@
package com.muyu.vehicle.core;
import com.muyu.system.handle.SystemHandler;
import com.muyu.vehicle.VehicleInstance;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author DongZl
@ -15,26 +14,10 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public class LocalContainer {
private static final Map<String, Map<String, VehicleInstance>> tenantVehicleDataMap
= new ConcurrentHashMap<>();
/**
* ID
* @param tenantId ID
* @return
*
*/
public static Map<String, VehicleInstance> getVehicleDataMap(String tenantId) {
return tenantVehicleDataMap
.computeIfAbsent(tenantId, k -> new ConcurrentHashMap<>());
}
/**
*
* @return
*/
public static Map<String, VehicleInstance> getTenantVehicleDataMap() {
return getVehicleDataMap(SystemHandler.getTenantId());
}
public static final Map<String, VehicleInstance> vehicleDataMap = new HashMap<>();
/**
*
@ -44,8 +27,7 @@ public class LocalContainer {
vehicleInstance.forEach(LocalContainer::setVehicleInstance);
}
public static void setVehicleInstance(VehicleInstance vehicleInstance){
String vin = vehicleInstance.getVehicleInfo().getVin();
Map<String, VehicleInstance> vehicleDataMap = getVehicleDataMap(vehicleInstance.getTenantId());
String vin = vehicleInstance.getVehicle().getVin();
if (!vehicleDataMap.containsKey(vin)) {
vehicleDataMap.put(vin, vehicleInstance);
}
@ -57,7 +39,6 @@ public class LocalContainer {
* @return
*/
public static VehicleInstance getVehicleInstance(String vin){
Map<String, VehicleInstance> vehicleDataMap = getTenantVehicleDataMap();
return vehicleDataMap.get(vin);
}
@ -66,12 +47,10 @@ public class LocalContainer {
* @return
*/
public static long total () {
Map<String, VehicleInstance> vehicleDataMap = getTenantVehicleDataMap();
return vehicleDataMap.size();
}
public static Collection<VehicleInstance> getVehicleInstanceAll () {
Map<String, VehicleInstance> vehicleDataMap = getTenantVehicleDataMap();
return vehicleDataMap.values();
}
@ -80,29 +59,15 @@ public class LocalContainer {
* 线
* @return 线
*/
public static List<VehicleInstance> getTenantOnlineVehicleInstance (){
Map<String, VehicleInstance> vehicleDataMap = getTenantVehicleDataMap();
public static List<VehicleInstance> getOnlineVehicleInstance(){
return vehicleDataMap.values().stream().filter(VehicleInstance::isOnline).toList();
}
/**
* 线
* @return 线
*/
public static List<VehicleInstance> getOnlineVehicleInstance (){
return tenantVehicleDataMap.values()
.stream()
.map(Map::values)
.flatMap(Collection::stream)
.filter(VehicleInstance::isOnline).toList();
}
/**
* 线
* @return 线VIN
*/
public static List<String> getOnlineVehicleVin(){
return getTenantOnlineVehicleInstance()
return getOnlineVehicleInstance()
.stream()
.map(VehicleInstance::getVin)
.toList();
@ -113,7 +78,6 @@ public class LocalContainer {
* @return 线
*/
public static List<VehicleInstance> getOfflineVehicleInstance(){
Map<String, VehicleInstance> vehicleDataMap = getTenantVehicleDataMap();
return vehicleDataMap.values().stream().filter(vehicleInstance -> !vehicleInstance.isOnline()).toList();
}
@ -122,7 +86,6 @@ public class LocalContainer {
* @param vin VIN
*/
public static void removeByVin(String vin) {
Map<String, VehicleInstance> vehicleDataMap = getTenantVehicleDataMap();
vehicleDataMap.remove(vin);
}
}

View File

@ -0,0 +1,79 @@
package com.muyu.vehicle.core;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.muyu.web.common.pool.FixedThreadPool;
import com.muyu.web.common.pool.ScheduledThreadPool;
import com.muyu.web.domain.Vehicle;
import com.muyu.web.service.VehicleInstanceService;
import com.muyu.web.service.VehicleService;
import com.muyu.vehicle.VehicleInstance;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PreDestroy;
import java.util.List;
/**
* @author DongZeLiang
* @version 1.0
* @description
* @date 2023/11/9
*/
@Log4j2
@Configuration
@AllArgsConstructor
public class VehicleConfiguration implements ApplicationRunner {
private final VehicleService vehicleService;
private final VehicleInstanceService vehicleInstanceService;
/**
*
*/
public void vehiclePageInit (){
long startTime = System.currentTimeMillis();
int page = 0, pageSize = 10;
log.info("初始开始,批量从数据库当中加载数据到内存当中,每次[{}]条", pageSize);
while (true){
Page<Vehicle> vehiclePage = vehicleService.page(new Page<>(page++, pageSize));
List<Vehicle> vehicleList = vehiclePage.getRecords();
vehicleList.forEach(vehicleInstanceService::init);
log.debug("第[{}]页,[{}]条", page, vehicleList.size());
if (vehicleList.size() < pageSize){
break;
}
}
log.info("数据加载完成,耗时:{} MS", System.currentTimeMillis() - startTime);
}
@Override
public void run (ApplicationArguments args) {
this.vehiclePageInit();
// 提交给线程池 一分钟 执行一次
// ThreadPool.submit(new Thread(vehicleService::syncDb), 30);
}
/**
*
*/
@PreDestroy
public void destroy(){
log.info("数据库同步");
vehicleService.syncDb();
log.info("下线所有车辆");
List<VehicleInstance> onlineVehicleInstanceList = LocalContainer.getOnlineVehicleInstance();
onlineVehicleInstanceList.forEach(VehicleInstance::closeClient);
log.info("关闭线程池");
ScheduledThreadPool.shutdown();
FixedThreadPool.shutDown();
}
}

View File

@ -1,16 +1,15 @@
package com.muyu.vehicle.model;
import com.muyu.web.domain.VehicleInfo;
import com.muyu.web.domain.Vehicle;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import static com.muyu.web.utils.VehicleUtils.genValue;
/**
* @author
@ -27,6 +26,10 @@ public class VehicleData {
* VIN
*/
private String vin;
/**
* 线
*/
private String drivingRoute;
/**
*
@ -48,51 +51,324 @@ public class VehicleData {
*/
private BigDecimal mileage;
/**
*
*/
private String voltage;
/**
*
*/
private String current;
/**
*
*/
private String resistance;
/**
*
*/
@Builder.Default
private String gear = "P";
/**
*
*
*/
private BigDecimal remainingBattery;
private String accelerationPedal;
/**
*
*
*/
private BigDecimal batteryLevel;
private String brakePedal;
/**
*
*/
private String fuelConsumptionRate;
@Builder.Default
private Map<String, String> dataMap = new HashMap<String, String>();
/**
*
*/
private String motorControllerTemperature;
/**
*
* @param key
* @param value
*
*/
public void putData(String key, String value) {
dataMap.put(key, value);
}
private String motorSpeed;
/**
*
* @param key
* @return
*
*/
public String getData(String key) {
return dataMap.get(key);
}
private String motorTorque;
public String genValue(double start, double end) {
Random random = new Random();
return String.valueOf(random.nextDouble() * (end - start) + start);
/**
*
*/
private String motorTemperature;
/**
*
*/
private String motorVoltage;
/**
*
*/
private String motorCurrent;
/**
* SOC
*/
private BigDecimal remainingBattery;
/**
*
*/
private BigDecimal batteryLevel;
/**
*
*/
private String maximumFeedbackPower;
/**
*
*/
private String maximumDischargePower;
/**
* BMS
*/
private String selfCheckCounter;
/**
*
*/
private String totalBatteryCurrent;
/**
* V3
*/
private String totalBatteryVoltage;
/**
*
*/
private String singleBatteryMaxVoltage;
/**
*
*/
private String singleBatteryMinVoltage;
/**
*
*/
private String singleBatteryMaxTemperature;
/**
*
*/
private String singleBatteryMinTemperature;
/**
*
*/
private String availableBatteryCapacity;
/**
*
*/
private int vehicleStatus = 1;
/**
*
*/
private int chargingStatus = 1;
/**
*
*/
private int operatingStatus = 1;
/**
* SOC
*/
private int socStatus = 1;
/**
*
*/
private int chargingEnergyStorageStatus = 1;
/**
*
*/
private int driveMotorStatus = 1;
/**
*
*/
private int positionStatus = 1;
/**
* EAS()
*/
private int easStatus = 1;
/**
* PTC()
*/
private int ptcStatus = 1;
/**
* EPS()
*/
private int epsStatus = 1;
/**
* ABS()
*/
private int absStatus = 1;
/**
* MCU(/)
*/
private int mcuStatus = 1;
/**
*
*/
private int heatingStatus = 1;
/**
*
*/
private int batteryStatus = 1;
/**
*
*/
private int batteryInsulationStatus = 1;
/**
* DCDC()
*/
private int dcdcStatus = 1;
/**
* CHG()
*/
private int chgStatus = 1;
/**
*
*/
private String vehicleStatusMsg;
/**
*
*/
private String smartHardwareMsg;
/**
*
*/
private String batteryMsg;
public String getMsg(){
//第一位VIN
return vin +
// 当前时间戳
System.currentTimeMillis() +
//第二位经度 longitude latitude
getValue(longitude, 11) +
//第三位维度 longitude latitude
getValue(latitude, 10) +
//车速
getValue(speed, 6) +
//总里程
getValue(mileage == null ? "" : mileage.toString(), 11) +
// 总电压
getValue(voltage, 6) +
//总电流
getValue(current, 5) +
//绝缘电阻 79 - 87
getValue(resistance, 9) +
//档位
(gear == null ? "D" : gear) +
// 加速踏板行程值
getValue(accelerationPedal, 2) +
// 制动踏板行程值
getValue(brakePedal, 2) +
// 燃料消耗率
getValue(fuelConsumptionRate, 5) +
//电机控制器温度
getValue(motorControllerTemperature, 6) +
//电机转速
getValue(motorSpeed, 5) +
//点击转矩
getValue(motorTorque, 4) +
//电机温度
getValue(motorTemperature, 6) +
//电机电压
getValue(motorVoltage, 5) +
//电机电流
getValue(motorCurrent, 8) +
//动力电池剩余电量SOC
getValue(remainingBattery == null ? "" : remainingBattery.toString(), 6) +
//当前状态允许的最大反馈功率
getValue(maximumFeedbackPower, 6) +
//当前状态允许最大放电功率
getValue(maximumDischargePower, 6) +
//BMS自检计数器
getValue(selfCheckCounter, 2) +
//动力电池充放电电流
getValue(totalBatteryCurrent, 5) +
//动力电池负载端总电压V3
getValue(totalBatteryVoltage, 6) +
//单次最大电压
getValue(singleBatteryMaxVoltage, 4) +
//单体电池最低电压
getValue(singleBatteryMinVoltage, 4) +
//单体电池最高温度
getValue(singleBatteryMaxTemperature, 6) +
//单体电池最低温度
getValue(singleBatteryMinTemperature, 6) +
//动力电池可用容量
getValue(availableBatteryCapacity, 6) +
//车辆状态
vehicleStatus +
//充电状态
chargingStatus +
//运行状态
operatingStatus +
//SOC
socStatus +
//可充电储能装置工作状态
chargingEnergyStorageStatus +
//驱动电机状态
driveMotorStatus +
//定位是否有效
positionStatus +
//EAS
easStatus +
//PTC
ptcStatus +
//EPS
epsStatus +
//ABS
absStatus +
//MCU
mcuStatus +
//动力电池加热状态
heatingStatus +
//动力电池当前状态
batteryStatus +
//动力电池保温状态
batteryInsulationStatus +
//DCDC
dcdcStatus +
//CHG
chgStatus;
}
public String getValue(String val , int valLength){
@ -109,16 +385,136 @@ public class VehicleData {
/**
* VIN
* @param vehicleInfo
* @param vehicle
* @return
*/
public static VehicleData vehicleBuild (VehicleInfo vehicleInfo) {
public static VehicleData vehicleBuild (Vehicle vehicle) {
return VehicleData.builder()
.vin(vehicleInfo.getVin())
.vin(vehicle.getVin())
.gear("P")
.remainingBattery(vehicleInfo.getRemainingBattery())
.batteryLevel(vehicleInfo.getBatteryLevel())
.mileage(vehicleInfo.getTotalMileage())
.remainingBattery(vehicle.getRemainingBattery())
.batteryLevel(vehicle.getBatteryLevel())
.mileage(vehicle.getTotalMileage())
.vehicleStatus(1)
.chargingStatus(1)
.operatingStatus(1)
.socStatus(1)
.chargingEnergyStorageStatus(1)
.driveMotorStatus(1)
.positionStatus(1)
.easStatus(1)
.ptcStatus(1)
.epsStatus(1)
.absStatus(1)
.mcuStatus(1)
.heatingStatus(1)
.batteryStatus(1)
.batteryInsulationStatus(1)
.dcdcStatus(1)
.chgStatus(1)
.build();
}
/**
*
*/
public void imitateBase(){
// 总电压
this.voltage = genValue(110, 750);
// 总电流
this.current = genValue(3, 50);
// 绝缘电阻
this.resistance = genValue(0,30000);
// 加速踏板行程值
this.accelerationPedal = genValue(0, 10);
// 制动踏板行程值
this.brakePedal = genValue(0, 10);
}
/**
*
*/
public void imitateMotor(){
// 电机控制器温度
this.motorControllerTemperature = genValue(0, 100);
// 电机转速
this.motorSpeed = genValue(0, 99999);
// 电机转矩
this.motorTorque = genValue(0, 1000);
// 电机温度
this.motorTemperature = genValue(0, 150);
// 电机电压
this.motorVoltage = genValue(110, 300);
// 电机电流
this.motorCurrent = genValue(0, 15000);
}
/**
*
*/
public void imitateBatteryPack(){
// 当前状态允许的最大反馈功率
this.maximumFeedbackPower = genValue(0, 100);
// 当前状态允许最大放电功率
this.maximumDischargePower = genValue(0, 100);
// BMS自检计数器
this.selfCheckCounter = genValue(0, 15);
// 动力电池充放电电流
this.totalBatteryCurrent = genValue(0, 15);
// 动力电池负载端总电压V3
this.totalBatteryVoltage = genValue(220, 750);
// 单体电池最高电压
this.singleBatteryMaxVoltage = genValue(3, 5);
// 单体电池最低电压
this.singleBatteryMinVoltage = genValue(3, 5);
// 单体电池最高温度
this.singleBatteryMaxTemperature = genValue(0, 100);
// 单体电池最低温度
this.singleBatteryMinTemperature = genValue(0, 100);
// 动力电池可用容量
this.availableBatteryCapacity = genValue(0,100 );
}
/**
vehicleStatus;
chargingStatus;
operatingStatus;
SOC
socStatus;
chargingEnergyStorageStatus;
driveMotorStatus;
positionStatus;
*/
/**
EAS()
easStatus;
PTC()
ptcStatus;
EPS()
epsStatus;
ABS()
absStatus;
MCU(/)
mcuStatus;
*/
/**
heatingStatus;
batteryStatus;
batteryInsulationStatus;
DCDC()
dcdcStatus;
CHG()
chgStatus;
*/
}

View File

@ -4,6 +4,8 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author DongZeLiang
@ -41,9 +43,5 @@ public class MqttProperties {
* ID
*/
private String clientId;
/**
*
*/
private int qos = 0;
}

View File

@ -13,6 +13,11 @@ public class VehicleThread implements Runnable {
*/
private volatile boolean isStop = false;
/**
*
*/
private volatile boolean isPaused;
/**
*
*/
@ -22,9 +27,19 @@ public class VehicleThread implements Runnable {
public void run() {
try {
if (!isStop){
String msg = this.vehicleInstance.imitateDataAndMsg();
log.info("{} - 上报数据: [{}]", this.vehicleInstance.getVin(), msg);
this.vehicleInstance.sendMsg( msg );
if (!isPaused){
log.info("{} - 上报数据", this.vehicleInstance.getVin());
String imitateResult = this.vehicleInstance.imitateData();
if (imitateResult == null){
this.vehicleInstance.sendMsg(
this.vehicleInstance.getVehicleData().getMsg()
);
}else {
log.warn("车辆[{}]数据模拟:{}", this.vehicleInstance.getVin(), imitateResult);
}
}else {
log.info("暂停模拟和上报:[{}]", this.vehicleInstance.getVin());
}
}else {
log.info("终止模拟和上报:[{}]", this.vehicleInstance.getVin());
vehicleInstance.cancelExecution();
@ -34,6 +49,21 @@ public class VehicleThread implements Runnable {
}
}
/**
* 线
*/
public void pause() {
isPaused = true;
}
/**
* 线
*/
public void resume() {
isPaused = false;
}
/**
*
*/

View File

@ -0,0 +1,25 @@
package com.muyu.web.config;
import com.muyu.web.common.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @author DongZeLiang
* @version 1.0
* @description
* @date 2023/11/15
*/
@RestControllerAdvice
public class ExceptionAdvice {
/**
*
* @param runtimeException
* @return
*/
@ExceptionHandler(value = RuntimeException.class)
public Result<String> runtimeExceptionHandler(RuntimeException runtimeException){
return Result.error(runtimeException.getMessage());
}
}

View File

@ -1,11 +1,13 @@
package com.muyu.config;
package com.muyu.web.config;
import com.dtflys.forest.annotation.BindingVar;
import com.muyu.system.handle.SystemHandler;
import com.dtflys.forest.reflection.ForestMethod;
import com.muyu.web.config.properties.ServiceConfigProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
/**
* Forest
* @Author: DongZeLiang
* @date: 2024/6/10
* @Description: Forest
@ -14,6 +16,9 @@ import org.springframework.stereotype.Service;
@Service("forsetConfig")
public class ForsetConfig {
@Autowired
private ServiceConfigProperties serviceConfigProperties;
/**
* 使 @BindingVar
* baseUrl
@ -21,7 +26,7 @@ public class ForsetConfig {
*/
@BindingVar("vehicleLoadUrl")
public String getBaseUrl() {
return SystemHandler.getLoadReqUrl();
return serviceConfigProperties.getLoadReqUrl();
}
}

View File

@ -0,0 +1,31 @@
package com.muyu.web.config;
import com.muyu.web.config.properties.ServiceConfigProperties;
import com.muyu.web.domain.model.ServerConfigModel;
import com.muyu.web.service.ServerConfigService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: DongZeLiang
* @date: 2024/6/10
* @Description:
* @Version: 1.0
*/
@Configuration
public class LoadServerConfig {
/**
*
*/
private static final ServiceConfigProperties serviceConfigProperties = new ServiceConfigProperties();
@Bean
public ServiceConfigProperties serverConfig(ServerConfigService serverConfigService) {
return serviceConfigProperties.modelToProperties(serverConfigService.get());
}
public static void modelToProperties(ServerConfigModel serverConfigModel){
serviceConfigProperties.modelToProperties(serverConfigModel);
}
}

View File

@ -0,0 +1,29 @@
package com.muyu.web.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
*
*
*/
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill...");
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill...");
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}

View File

@ -1,11 +1,8 @@
package com.muyu.config;
package com.muyu.web.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.muyu.config.tenant.CustomTenantHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -14,9 +11,16 @@ import org.springframework.context.annotation.Configuration;
*/
@Configuration
public class MybatisPlusConfig {
/**
*
* @return
*/
/**@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
return paginationInterceptor;
}*/
@Autowired
private CustomTenantHandler customTenantHandler;
/**
* ,mybatis,
@ -24,10 +28,7 @@ public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
tenantInterceptor.setTenantLineHandler(customTenantHandler);
interceptor.addInnerInterceptor(tenantInterceptor);
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
}

View File

@ -0,0 +1,66 @@
package com.muyu.web.config.properties;
import com.muyu.web.domain.model.ServerConfigModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: DongZeLiang
* @date: 2024/6/10
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ServiceConfigProperties {
/**
*
*/
private String host;
/**
*
*/
private String port;
/**
*
*/
private String loadUrl;
/**
*
*/
private String loadReqUrl;
/**
* MQTT
*/
private String mqttAddr;
/**
* MQTT
*/
private String mqttTopic;
/**
* MQTT
*/
private Integer mqttQos;
/**
*
* @param serverConfigModel
* @return
*/
public ServiceConfigProperties modelToProperties(ServerConfigModel serverConfigModel) {
this.host = serverConfigModel.getHost();
this.port = serverConfigModel.getPort();
this.loadUrl = serverConfigModel.getLoadUrl();
this.mqttAddr = serverConfigModel.getDefaultMqttAddr();
this.mqttTopic = serverConfigModel.getDefaultMqttTopic();
this.mqttQos = serverConfigModel.getDefaultMqttQos();
this.loadReqUrl = String.format("http://%s:%s%s", host, port, loadUrl.startsWith("/") ? loadUrl : "/" + loadUrl);
return this;
}
}

View File

@ -1,102 +0,0 @@
package com.muyu.web.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.muyu.web.common.Result;
import com.muyu.web.domain.MessageTemplate;
import com.muyu.web.domain.MessageTemplateValue;
import com.muyu.web.domain.req.MessageTemplateSaveReq;
import com.muyu.web.domain.req.MessageTemplateValueSaveReq;
import com.muyu.web.service.MessageService;
import com.muyu.web.service.MessageTemplateService;
import com.muyu.web.service.MessageTemplateValueService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Author: DongZeLiang
* @date: 2024/9/18
* @Description:
* @Version: 1.0
*/
@RestController
@RequestMapping("/message")
public class MessageController {
@Autowired
private MessageService messageService;
@Autowired
private MessageTemplateService messageTemplateService;
@Autowired
private MessageTemplateValueService messageTemplateValueService;
/**
*
* @return
*/
@GetMapping("/template/list")
public Result<List<MessageTemplate>> templateList(){
return Result.success(
messageTemplateService.list()
);
}
/**
*
* @return
*/
@PostMapping("/template")
public Result<String> save(@RequestBody @Validated MessageTemplateSaveReq messageTemplateSaveReq){
messageService.saveMessageTemplate(messageTemplateSaveReq);
return Result.success();
}
/**
*
* @return
*/
@GetMapping("/template/{messageTemplateId}/value")
public Result<List<MessageTemplateValue>> templateValueList(@PathVariable("messageTemplateId") Long messageTemplateId) {
return Result.success(
this.messageTemplateValueService.list(
new LambdaQueryWrapper<>(){{
eq(MessageTemplateValue::getMessageId, messageTemplateId);
}}
)
);
}
/**
*
* @return
*/
@PostMapping("/template/{messageTemplateId}/value")
public Result<String> templateValueSave(
@RequestBody @Validated MessageTemplateValueSaveReq messageTemplateValueSaveReq,
@PathVariable("messageTemplateId") Long messageTemplateId
){
messageTemplateValueService.save(
MessageTemplateValue.builder()
.messageId(messageTemplateId)
.code(messageTemplateValueSaveReq.getCode())
.category(messageTemplateValueSaveReq.getCategory())
.label(messageTemplateValueSaveReq.getLabel())
.length(messageTemplateValueSaveReq.getLength())
.maxValue(messageTemplateValueSaveReq.getMaxValue())
.minValue(messageTemplateValueSaveReq.getMinValue())
.valueType(messageTemplateValueSaveReq.getValueType())
.elValue(messageTemplateValueSaveReq.getElValue())
.fixedValue(messageTemplateValueSaveReq.getFixedValue())
.startLocation(messageTemplateValueSaveReq.getStartLocation())
.endLocation(messageTemplateValueSaveReq.getEndLocation())
.build()
);
return Result.success();
}
}

View File

@ -1,60 +0,0 @@
package com.muyu.web.controller;
import com.muyu.system.domain.LoginUserInfo;
import com.muyu.web.common.Result;
import com.muyu.web.domain.req.UserLoginReq;
import com.muyu.web.domain.req.UserRegReq;
import com.muyu.web.service.SystemAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @Author: DongZeLiang
* @date: 2024/9/12
* @Description:
* @Version: 1.0
*/
@RestController
@RequestMapping("/system/auth")
public class SystemAuthController {
@Autowired
private SystemAuthService systemAuthService;
@PostMapping("/reg")
public Result<String> reg(@RequestBody @Validated UserRegReq userRegReq) {
systemAuthService.reg(userRegReq);
return Result.success();
}
/**
*
* @param userLoginReq
* @return token
*/
@PostMapping("/login")
public Result<String> login(@RequestBody @Validated UserLoginReq userLoginReq){
String token = systemAuthService.login(userLoginReq.getUserName(), userLoginReq.getPassword());
return Result.success(token);
}
/**
* 退
* @return token
*/
@GetMapping("/info")
public Result<LoginUserInfo> info(){
return Result.success(systemAuthService.info());
}
/**
* 退
* @return token
*/
@PostMapping("/logout")
public Result<String> logout(){
systemAuthService.logout();
return Result.success();
}
}

View File

@ -1,9 +1,9 @@
package com.muyu.web.controller;
import com.muyu.web.common.Result;
import com.muyu.web.domain.VehicleInfo;
import com.muyu.web.domain.Vehicle;
import com.muyu.web.domain.req.VehicleCreateAddReq;
import com.muyu.web.service.VehicleInfoService;
import com.muyu.web.service.VehicleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -20,11 +20,11 @@ import java.util.List;
public class VehicleController {
@Autowired
private VehicleInfoService vehicleInfoService;
private VehicleService vehicleService;
@GetMapping("/list")
public Result<List<VehicleInfo>> list(){
return Result.success(vehicleInfoService.list());
public Result<List<Vehicle>> list(){
return Result.success(vehicleService.list());
}
/**
@ -32,12 +32,9 @@ public class VehicleController {
* @param sum
* @return
*/
@GetMapping("/gen/{sum}/{messageTemplateId}")
public Result<String> generate(
@PathVariable(value = "sum") Integer sum,
@PathVariable("messageTemplateId") Long messageTemplateId
){
vehicleInfoService.generate(sum, messageTemplateId);
@GetMapping("/gen/{sum}")
public Result<String> generate(@PathVariable(value = "sum") Integer sum){
vehicleService.generate(sum);
return Result.success();
}
/**
@ -47,7 +44,7 @@ public class VehicleController {
*/
@PostMapping("/create")
public Result<String> create(@RequestBody VehicleCreateAddReq vehicleCreateAddReq){
vehicleInfoService.create(vehicleCreateAddReq.getVinList(), vehicleCreateAddReq.getMessageTemplateId());
vehicleService.create(vehicleCreateAddReq.getVinStr());
return Result.success();
}
@ -59,7 +56,7 @@ public class VehicleController {
*/
@DeleteMapping("/{vin}")
public Result<String> delete(@PathVariable("vin") String vin){
this.vehicleInfoService.delete(vin);
this.vehicleService.delete(vin);
return Result.success(null,"删除成功");
}
}

View File

@ -1,14 +1,15 @@
package com.muyu.web.controller;
import com.muyu.vehicle.core.LocalContainer;
import com.muyu.vehicle.model.VehicleData;
import com.muyu.web.common.PageList;
import com.muyu.web.common.Result;
import com.muyu.web.domain.req.CheckPositionReq;
import com.muyu.web.domain.req.GearReq;
import com.muyu.web.domain.req.MsgReq;
import com.muyu.web.domain.req.VehicleInstanceListReq;
import com.muyu.web.domain.resp.VehicleInstanceResp;
import com.muyu.web.service.VehicleInstanceService;
import com.muyu.vehicle.core.LocalContainer;
import com.muyu.vehicle.model.VehicleData;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -28,83 +29,80 @@ public class VehicleInstanceController {
/**
*
*
* @param vehicleInstanceListReq
* @return
*/
@PostMapping("/list")
public Result<PageList<VehicleInstanceResp>> list(@RequestBody VehicleInstanceListReq vehicleInstanceListReq) {
public Result<PageList<VehicleInstanceResp>> list(@RequestBody VehicleInstanceListReq vehicleInstanceListReq){
PageList<VehicleInstanceResp> pageList = vehicleInstanceService.queryList(vehicleInstanceListReq);
return Result.success(pageList);
}
/**
* VIN
*
* @param vin VIN
* @return
*/
@GetMapping("/data/{vin}")
public Result<VehicleData> getVehicleData(@PathVariable("vin") String vin) {
public Result<VehicleData> getVehicleData(@PathVariable("vin") String vin){
return Result.success(LocalContainer.getVehicleInstance(vin).getVehicleData());
}
/**
*
*
* @param vin vin
* @return
*/
@PostMapping("/client/start/{vin}")
public Result<String> vehicleClientInit(@PathVariable("vin") String vin) {
this.vehicleInstanceService.vehicleClientStart(vin);
this.vehicleInstanceService.checkPosition(
CheckPositionReq.builder()
.vin(vin)
.positionCode("路径1")
.build()
);
@PostMapping("/client/init/{vin}")
public Result<String> vehicleClientInit(@PathVariable("vin") String vin){
this.vehicleInstanceService.vehicleClientInit(vin);
return Result.success();
}
/**
*
*
* @param vin vin
* @return
*/
@PostMapping("/client/close/{vin}")
public Result<String> vehicleClientClose(@PathVariable("vin") String vin) {
public Result<String> vehicleClientClose(@PathVariable("vin") String vin){
this.vehicleInstanceService.vehicleClientClose(vin);
return Result.success();
}
/**
*
*
* @param checkPositionReq
* @return
*/
@PostMapping("/position/check")
public Result<String> checkPosition(@RequestBody CheckPositionReq checkPositionReq) {
public Result<String> checkPosition(@RequestBody CheckPositionReq checkPositionReq){
this.vehicleInstanceService.checkPosition(checkPositionReq);
return Result.success();
}
/**
*
* @return
*/
@PostMapping("/msg")
public Result<String> msg(@RequestBody MsgReq msgReq){
this.vehicleInstanceService.msg(msgReq);
return Result.success();
}
/**
*
*
* @return
*/
@PostMapping("/gear")
public Result<String> gear(@RequestBody GearReq gearReq) {
public Result<String> gear(@RequestBody GearReq gearReq){
this.vehicleInstanceService.gear(gearReq);
return Result.success();
}
/**
*
*
* @param statusKey
* @param vin
* @param statusValue
@ -113,7 +111,7 @@ public class VehicleInstanceController {
@PutMapping("/status/{vin}/{statusKey}/{statusValue}")
public Result<String> editStatus(@PathVariable("statusKey") String statusKey,
@PathVariable("vin") String vin,
@PathVariable("statusValue") Integer statusValue) {
@PathVariable("statusValue") Integer statusValue){
this.vehicleInstanceService.editStatus(vin, statusKey, statusValue);
return Result.success();
}

View File

@ -1,8 +1,7 @@
package com.muyu.web.controller;
import com.muyu.system.handle.SystemHandler;
import com.muyu.web.common.Result;
import com.muyu.system.properties.ServerConfigProperties;
import com.muyu.web.config.properties.ServiceConfigProperties;
import com.muyu.web.domain.model.MqttServerModel;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
@ -19,6 +18,8 @@ import org.springframework.web.bind.annotation.RestController;
@AllArgsConstructor
public class VerifyController {
private final ServiceConfigProperties serviceConfigProperties;
/**
* 线
@ -26,11 +27,10 @@ public class VerifyController {
*/
@PostMapping("/vehicleConnection")
public Result<MqttServerModel> vehicleConnection(){
ServerConfigProperties serverConfig = SystemHandler.getServerConfig();
return Result.success(
MqttServerModel.builder()
.broker(serverConfig.getMqttAddr())
.topic(serverConfig.getMqttTopic())
.broker(serviceConfigProperties.getMqttAddr())
.topic(serviceConfigProperties.getMqttTopic())
.build()
);
}

View File

@ -1,51 +0,0 @@
package com.muyu.web.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* @Description:
* @Author: DongZeLiang
* @date: 2024/9/18
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "message_template")
public class MessageTemplate {
/**
*
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* ID
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String tenantId;
/**
*
*/
private String messageName;
/**
*
*/
private String description;
/**
*
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
}

View File

@ -1,95 +0,0 @@
package com.muyu.web.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.muyu.system.enums.MessageTemplateValueType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: DongZeLiang
* @date: 2024/9/18
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "message_template_value")
public class MessageTemplateValue {
/**
*
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* ID
*/
@TableField(fill = FieldFill.INSERT)
private String tenantId;
/**
*
*/
private Long messageId;
/**
*
*/
private Integer length;
/**
*
*/
private String category;
/**
*
*/
private String code;
/**
*
*/
private String label;
/**
*
*/
private Integer startLocation;
/**
*
*/
private Integer endLocation;
/**
*
*/
private String valueType;
/**
*
*/
private String elValue;
/**
*
*/
private String fixedValue;
/**
*
*/
private Double minValue;
/**
*
*/
private Double maxValue;
public boolean isEl () {
return MessageTemplateValueType.EL.code().equals(valueType);
}
public boolean isInterval () {
return MessageTemplateValueType.INTERVAL.code().equals(valueType);
}
public boolean isFixed () {
return MessageTemplateValueType.FIXED.code().equals(valueType);
}
}

View File

@ -1,6 +1,5 @@
package com.muyu.web.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@ -20,7 +19,7 @@ import java.util.Date;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("position_route_info")
@TableName("route_info")
public class PositionRouteInfo {
/**
@ -29,12 +28,6 @@ public class PositionRouteInfo {
@TableId("id")
private Long id;
/**
* ID
*/
@TableField(value = "tenant_id", fill = FieldFill.INSERT)
private String tenantId;
/**
*
*/
@ -44,12 +37,12 @@ public class PositionRouteInfo {
/**
*
*/
@TableField(value = "route_data")
@TableField(value = "data")
private String routeData;
/**
*
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
@TableField(value = "create_time")
private Date createTime;
}

View File

@ -1,7 +1,6 @@
package com.muyu.web.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.muyu.system.handle.SystemHandler;
import com.baomidou.mybatisplus.annotation.TableName;
import com.muyu.web.domain.model.ServerConfigModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -26,18 +25,7 @@ public class ServerConfig {
/**
*
*/
@TableId(
value = "id",
type = IdType.AUTO
)
private Long id;
/**
* ID
*/
@TableField(value = "tenant_id", fill = FieldFill.INSERT)
private String tenantId;
private Integer id;
/**
*
*/
@ -49,7 +37,7 @@ public class ServerConfig {
/**
*
*/
private String uri;
private String loadUrl;
/**
* MQTT
*/
@ -63,13 +51,12 @@ public class ServerConfig {
*/
private Integer defaultMqttQos;
public static ServerConfig modeBuild (ServerConfigModel serverConfigModel, Supplier<Long> idKey) {
public static ServerConfig modeBuild (ServerConfigModel serverConfigModel, Supplier<Integer> idKey) {
return builder()
.id(idKey.get())
.tenantId(SystemHandler.getTenantId())
.host(serverConfigModel.getHost())
.port(serverConfigModel.getPort())
.uri(serverConfigModel.getUri())
.loadUrl(serverConfigModel.getLoadUrl())
.defaultMqttAddr(serverConfigModel.getDefaultMqttAddr())
.defaultMqttTopic(serverConfigModel.getDefaultMqttTopic())
.defaultMqttQos(serverConfigModel.getDefaultMqttQos())

View File

@ -1,46 +0,0 @@
package com.muyu.web.domain;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* @Author: DongZeLiang
* @date: 2024/9/12
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {
/**
*
*/
private Long id;
/**
*
*/
private String userName;
/**
*
*/
private String password;
/**
* ID
*/
private String tenantId;
/**
*
*/
private Date createTime;
/**
*
*/
private Date updateTime;
}

View File

@ -1,9 +1,11 @@
package com.muyu.web.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.muyu.web.utils.VehicleUtils;
import com.muyu.vehicle.VehicleInstance;
import com.muyu.vehicle.model.VehicleData;
import com.muyu.web.utils.VehicleUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -11,7 +13,6 @@ import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.Date;
import java.util.function.Supplier;
/**
* @author DongZeLiang
@ -23,33 +24,14 @@ import java.util.function.Supplier;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("vehicle_info")
public class VehicleInfo {
/**
*
*/
@TableId(
value = "id",
type = IdType.AUTO
)
private Long id;
@TableName("vehicle")
public class Vehicle {
/**
* VIN
*/
@TableId(value = "vin")
private String vin;
/**
* VIN
*/
@TableField(value = "tenant_id", fill = FieldFill.INSERT)
private String tenantId;
/**
*
*/
@TableField("message_template_id")
private Long messageTemplateId;
/**
*
@ -63,18 +45,6 @@ public class VehicleInfo {
@TableField("battery_level")
private BigDecimal batteryLevel;
/**
*
*/
@TableField("last_longitude")
private String lastLongitude;
/**
*
*/
@TableField("last_latitude")
private String lastLatitude;
/**
*
*/
@ -84,27 +54,25 @@ public class VehicleInfo {
/**
*
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
@TableField("create_time")
private Date createTime;
/**
*
* @param messageTemplateId ID
* @return
*/
public static VehicleInfo gen(Supplier<Long> messageTemplateId) {
return VehicleInfo.create(VehicleUtils.genVin(), messageTemplateId);
public static Vehicle gen() {
return Vehicle.create(VehicleUtils.genVin());
}
/**
*
* @return
*/
public static VehicleInfo create(String vin, Supplier<Long> messageTemplateId) {
public static Vehicle create(String vin) {
BigDecimal battery = VehicleUtils.genBattery();
return VehicleInfo.builder()
return Vehicle.builder()
.vin(vin)
.messageTemplateId(messageTemplateId.get())
.createTime(new Date())
.batteryLevel(battery)
.remainingBattery(battery)
@ -113,9 +81,9 @@ public class VehicleInfo {
}
public static VehicleInfo instanceBuild (VehicleInstance vehicleInstance) {
public static Vehicle instanceBuild (VehicleInstance vehicleInstance) {
VehicleData vehicle = vehicleInstance.getVehicleData();
return VehicleInfo.builder()
return Vehicle.builder()
.vin(vehicleInstance.getVin())
.remainingBattery(vehicle.getRemainingBattery())
.totalMileage(vehicle.getMileage())

View File

@ -1,6 +1,6 @@
package com.muyu.web.domain.model;
import com.muyu.system.properties.ServerConfigProperties;
import com.baomidou.mybatisplus.annotation.TableName;
import com.muyu.web.domain.ServerConfig;
import com.muyu.web.domain.req.ServerConfigEditReq;
import lombok.AllArgsConstructor;
@ -31,7 +31,7 @@ public class ServerConfigModel {
/**
*
*/
private String uri;
private String loadUrl;
/**
* MQTT
*/
@ -49,7 +49,7 @@ public class ServerConfigModel {
return builder()
.host(serverConfig.getHost().trim())
.port(serverConfig.getPort())
.uri(serverConfig.getUri().trim())
.loadUrl(serverConfig.getLoadUrl().trim())
.defaultMqttAddr(serverConfig.getDefaultMqttAddr().trim())
.defaultMqttTopic(serverConfig.getDefaultMqttTopic().trim())
.defaultMqttQos(serverConfig.getDefaultMqttQos())
@ -60,21 +60,10 @@ public class ServerConfigModel {
return builder()
.host(serverConfigReq.getHost().trim())
.port(serverConfigReq.getPort())
.uri(serverConfigReq.getUri().trim())
.loadUrl(serverConfigReq.getLoadUrl().trim())
.defaultMqttAddr(serverConfigReq.getDefaultMqttAddr().trim())
.defaultMqttTopic(serverConfigReq.getDefaultMqttTopic().trim())
.defaultMqttQos(serverConfigReq.getDefaultMqttQos())
.build();
}
public static ServerConfigModel serverConfigPropertiesBuild (ServerConfigProperties serverConfigProperties) {
return builder()
.host(serverConfigProperties.getHost().trim())
.port(serverConfigProperties.getPort())
.uri(serverConfigProperties.getUri().trim())
.defaultMqttAddr(serverConfigProperties.getMqttAddr().trim())
.defaultMqttTopic(serverConfigProperties.getMqttTopic().trim())
.defaultMqttQos(serverConfigProperties.getMqttQos())
.build();
}
}

View File

@ -1,29 +0,0 @@
package com.muyu.web.domain.req;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: DongZeLiang
* @date: 2024/9/18
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MessageTemplateSaveReq {
/**
*
*/
private String messageName;
/**
*
*/
private String description;
}

View File

@ -1,66 +0,0 @@
package com.muyu.web.domain.req;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: DongZeLiang
* @date: 2024/9/19
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MessageTemplateValueSaveReq {
/**
*
*/
private String category;
/**
*
*/
private String code;
/**
*
*/
private String label;
/**
*
*/
private Integer length;
/**
*
*/
private Integer startLocation;
/**
*
*/
private Integer endLocation;
/**
*
*/
private String valueType;
/**
*
*/
private String elValue;
/**
*
*/
private String fixedValue;
/**
*
*/
private Double minValue;
/**
*
*/
private Double maxValue;
}

View File

@ -1,5 +1,6 @@
package com.muyu.web.domain.req;
import com.muyu.web.domain.model.ServerConfigModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -28,7 +29,7 @@ public class ServerConfigEditReq {
/**
*
*/
private String uri;
private String loadUrl;
/**
* MQTT
*/

View File

@ -1,32 +0,0 @@
package com.muyu.web.domain.req;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: DongZeLiang
* @date: 2024/9/12
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserLoginReq {
/**
*
*/
@NotEmpty(message = "请输入用户名称")
private String userName;
/**
*
*/
@NotEmpty(message = "请输入用户密码")
private String password;
}

View File

@ -1,32 +0,0 @@
package com.muyu.web.domain.req;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: DongZeLiang
* @date: 2024/9/12
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserRegReq {
/**
*
*/
@NotEmpty(message = "请输入用户名称")
private String userName;
/**
*
*/
@NotEmpty(message = "请输入用户密码")
private String password;
}

View File

@ -5,8 +5,6 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author DongZl
* @description:
@ -21,10 +19,5 @@ public class VehicleCreateAddReq {
/**
* VIN
*/
private List<String> vinList;
/**
*
*/
private Long messageTemplateId;
private String vinStr;
}

View File

@ -1,5 +1,6 @@
package com.muyu.web.domain.resp;
import com.baomidou.mybatisplus.annotation.TableName;
import com.muyu.web.domain.model.ServerConfigModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -29,7 +30,7 @@ public class ServerConfigResp {
/**
*
*/
private String uri;
private String loadUrl;
/**
* MQTT
*/
@ -48,7 +49,7 @@ public class ServerConfigResp {
return builder()
.host(serverConfigModel.getHost())
.port(serverConfigModel.getPort())
.uri(serverConfigModel.getUri())
.loadUrl(serverConfigModel.getLoadUrl())
.defaultMqttAddr(serverConfigModel.getDefaultMqttAddr())
.defaultMqttTopic(serverConfigModel.getDefaultMqttTopic())
.defaultMqttQos(serverConfigModel.getDefaultMqttQos())

View File

@ -1,15 +0,0 @@
package com.muyu.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.muyu.web.domain.MessageTemplate;
import org.apache.ibatis.annotations.Mapper;
/**
* @Author: DongZeLiang
* @date: 2024/6/10
* @Description: Mapper
* @Version: 1.0
*/
@Mapper
public interface MessageTemplateMapper extends BaseMapper<MessageTemplate> {
}

View File

@ -1,15 +0,0 @@
package com.muyu.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.muyu.web.domain.MessageTemplateValue;
import org.apache.ibatis.annotations.Mapper;
/**
* @Author: DongZeLiang
* @date: 2024/6/10
* @Description: Mapper
* @Version: 1.0
*/
@Mapper
public interface MessageTemplateValueMapper extends BaseMapper<MessageTemplateValue> {
}

View File

@ -1,15 +0,0 @@
package com.muyu.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.muyu.web.domain.UserInfo;
import org.apache.ibatis.annotations.Mapper;
/**
* @Author: DongZeLiang
* @date: 2024/9/12
* @Description:
* @Version: 1.0
*/
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

View File

@ -1,7 +1,7 @@
package com.muyu.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.muyu.web.domain.VehicleInfo;
import com.muyu.web.domain.Vehicle;
import org.apache.ibatis.annotations.Mapper;
/**
@ -13,6 +13,6 @@ import org.apache.ibatis.annotations.Mapper;
* @since 2022-07-05
*/
@Mapper
public interface VehicleInfoMapper extends BaseMapper<VehicleInfo> {
public interface VehicleMapper extends BaseMapper<Vehicle> {
}

View File

@ -1,19 +0,0 @@
package com.muyu.web.service;
import com.muyu.web.domain.req.MessageTemplateSaveReq;
/**
* @Author: DongZeLiang
* @date: 2024/9/20
* @Description:
* @Version: 1.0
*/
public interface MessageService {
/**
*
* @param messageTemplateSaveReq
*/
void saveMessageTemplate (MessageTemplateSaveReq messageTemplateSaveReq);
}

View File

@ -1,14 +0,0 @@
package com.muyu.web.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.muyu.web.domain.MessageTemplate;
/**
* @Author: DongZeLiang
* @date: 2024-9-18
* @Description:
* @Version: 1.0
*/
public interface MessageTemplateService extends IService<MessageTemplate> {
}

View File

@ -1,22 +0,0 @@
package com.muyu.web.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.muyu.web.domain.MessageTemplateValue;
import java.util.List;
/**
* @Author: DongZeLiang
* @date: 2024-9-18
* @Description:
* @Version: 1.0
*/
public interface MessageTemplateValueService extends IService<MessageTemplateValue> {
/**
* ID
* @param msgId ID
* @return
*/
List<MessageTemplateValue> valueListByMsgId (Long msgId);
}

View File

@ -1,38 +0,0 @@
package com.muyu.web.service;
import com.muyu.system.domain.LoginUserInfo;
import com.muyu.web.domain.req.UserRegReq;
/**
* @Author: DongZeLiang
* @date: 2024/9/12
* @Description:
* @Version: 1.0
*/
public interface SystemAuthService {
/**
*
* @param userName
* @param password
* @return
*/
String login (String userName, String password);
/**
*
*/
void logout ();
/**
*
* @return
*/
LoginUserInfo info ();
/**
*
* @param userRegReq
*/
void reg (UserRegReq userRegReq);
}

View File

@ -1,9 +1,10 @@
package com.muyu.web.service;
import com.muyu.web.common.PageList;
import com.muyu.web.domain.VehicleInfo;
import com.muyu.web.domain.Vehicle;
import com.muyu.web.domain.req.CheckPositionReq;
import com.muyu.web.domain.req.GearReq;
import com.muyu.web.domain.req.MsgReq;
import com.muyu.web.domain.req.VehicleInstanceListReq;
import com.muyu.web.domain.resp.VehicleInstanceResp;
@ -17,9 +18,9 @@ public interface VehicleInstanceService {
/**
*
* @param vehicleInfo
* @param vehicle
*/
public void init(VehicleInfo vehicleInfo);
public void init(Vehicle vehicle);
/**
@ -35,7 +36,7 @@ public interface VehicleInstanceService {
*
* @param vin vin
*/
void vehicleClientStart (String vin);
void vehicleClientInit (String vin);
/**
*
@ -49,6 +50,12 @@ public interface VehicleInstanceService {
*/
void checkPosition (CheckPositionReq checkPositionReq);
/**
*
* @param msgReq
*/
void msg (MsgReq msgReq);
/**
*
* @param gearReq

View File

@ -1,9 +1,7 @@
package com.muyu.web.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.muyu.web.domain.VehicleInfo;
import java.util.List;
import com.muyu.web.domain.Vehicle;
/**
* <p>
@ -13,23 +11,19 @@ import java.util.List;
* @author DongZeLiang
* @since 2022-07-05
*/
public interface VehicleInfoService extends IService<VehicleInfo> {
public interface VehicleService extends IService<Vehicle> {
/**
*
*
* @param sum
* @param messageTemplateId
* @param sum
*/
void generate(Integer sum, Long messageTemplateId);
void generate(Integer sum);
/**
* IVN
*
* @param vinList VIN
* @param messageTemplateId ID
* @param vinStr VIN
*/
void create (List<String> vinList, Long messageTemplateId);
void create (String vinStr);
/**
*

View File

@ -1,44 +0,0 @@
package com.muyu.web.service.impl;
import com.muyu.system.enums.MessageTemplateValueType;
import com.muyu.web.domain.MessageTemplate;
import com.muyu.web.domain.MessageTemplateValue;
import com.muyu.web.domain.req.MessageTemplateSaveReq;
import com.muyu.web.service.MessageService;
import com.muyu.web.service.MessageTemplateService;
import com.muyu.web.service.MessageTemplateValueService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
/**
* @Author: DongZeLiang
* @date: 2024/9/20
* @Description:
* @Version: 1.0
*/
@Service
public class MessageServiceImpl implements MessageService {
@Autowired
private MessageTemplateService messageTemplateService;
@Autowired
private MessageTemplateValueService messageTemplateValueService;
/**
*
*
* @param messageTemplateSaveReq
*/
@Override
public void saveMessageTemplate (MessageTemplateSaveReq messageTemplateSaveReq) {
MessageTemplate messageTemplate = MessageTemplate.builder().messageName(messageTemplateSaveReq.getMessageName()).description(messageTemplateSaveReq.getDescription()).build();
messageTemplateService.save(messageTemplate);
messageTemplateValueService.saveBatch(new ArrayList<>() {{
add(MessageTemplateValue.builder().messageId(messageTemplate.getId()).code("vin").label("VIN").category("base").length(17).startLocation(1).endLocation(17).valueType(MessageTemplateValueType.EL.code()).elValue("this.vin").build());
add(MessageTemplateValue.builder().messageId(messageTemplate.getId()).code("timeMillis").label("报文采集毫秒").category("base").length(13).startLocation(18).endLocation(30).valueType(MessageTemplateValueType.EL.code()).elValue("this.timeMillis").build());
}});
}
}

View File

@ -1,19 +0,0 @@
package com.muyu.web.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.muyu.web.domain.MessageTemplate;
import com.muyu.web.mapper.MessageTemplateMapper;
import com.muyu.web.service.MessageTemplateService;
import org.springframework.stereotype.Service;
/**
* @Author: DongZeLiang
* @date: 2024/9/18
* @Description:
* @Version: 1.0
*/
@Service
public class MessageTemplateServiceImpl
extends ServiceImpl<MessageTemplateMapper, MessageTemplate>
implements MessageTemplateService {
}

View File

@ -1,37 +0,0 @@
package com.muyu.web.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.muyu.web.domain.MessageTemplateValue;
import com.muyu.web.mapper.MessageTemplateValueMapper;
import com.muyu.web.service.MessageTemplateValueService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Author: DongZeLiang
* @date: 2024/9/18
* @Description:
* @Version: 1.0
*/
@Service
public class MessageTemplateValueServiceImpl
extends ServiceImpl<MessageTemplateValueMapper, MessageTemplateValue>
implements MessageTemplateValueService {
/**
* ID
*
* @param msgId ID
*
* @return
*/
@Override
public List<MessageTemplateValue> valueListByMsgId (Long msgId) {
return this.list(
new LambdaQueryWrapper<>(){{
this.eq(MessageTemplateValue::getMessageId, msgId);
}}
);
}
}

View File

@ -4,6 +4,8 @@ import com.muyu.vehicle.VehicleInstance;
import com.muyu.vehicle.core.LocalContainer;
import com.muyu.web.domain.model.OverviewModel;
import com.muyu.web.service.OverviewService;
import com.muyu.web.service.VehicleInstanceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collection;
@ -25,7 +27,7 @@ public class OverviewServiceImpl implements OverviewService {
@Override
public OverviewModel overview () {
// 车辆实例对象
Collection<VehicleInstance> instanceList = LocalContainer.getTenantVehicleDataMap().values();
Collection<VehicleInstance> instanceList = LocalContainer.vehicleDataMap.values();
return OverviewModel.builder()

View File

@ -1,13 +1,13 @@
package com.muyu.web.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.muyu.system.handle.SystemHandler;
import com.muyu.system.properties.ServerConfigProperties;
import com.muyu.web.config.LoadServerConfig;
import com.muyu.web.config.properties.ServiceConfigProperties;
import com.muyu.web.domain.ServerConfig;
import com.muyu.web.domain.model.ServerConfigModel;
import com.muyu.web.service.ServerConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
@ -18,6 +18,12 @@ import org.springframework.stereotype.Service;
*/
@Service
public class ServerConfigServiceImpl extends ServiceImpl<BaseMapper<ServerConfig>, ServerConfig> implements ServerConfigService {
/**
* Key
*/
private final Integer key = 1;
/**
*
*
@ -25,7 +31,8 @@ public class ServerConfigServiceImpl extends ServiceImpl<BaseMapper<ServerConfig
*/
@Override
public ServerConfigModel get () {
return ServerConfigModel.serverConfigPropertiesBuild(SystemHandler.getServerConfig());
ServerConfig serverConfig = getById(key);
return ServerConfigModel.serverConfigBuild(serverConfig);
}
/**
@ -35,11 +42,8 @@ public class ServerConfigServiceImpl extends ServiceImpl<BaseMapper<ServerConfig
*/
@Override
public void edit (ServerConfigModel serverConfigModel) {
ServerConfig serverConfig = ServerConfig.modeBuild(serverConfigModel, SystemHandler::getUserId);
update(serverConfig, new UpdateWrapper<>());
SystemHandler.setServerConfig(
ServerConfigProperties.modelToProperties(serverConfigModel)
);
ServerConfig serverConfig = ServerConfig.modeBuild(serverConfigModel, () -> key);
updateById(serverConfig);
LoadServerConfig.modelToProperties(serverConfigModel);
}
}

View File

@ -1,162 +0,0 @@
package com.muyu.web.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.muyu.config.tenant.CustomTenantHandler;
import com.muyu.system.constants.SecurityConstants;
import com.muyu.system.domain.LoginUserInfo;
import com.muyu.system.handle.SystemHandler;
import com.muyu.system.properties.ServerConfigProperties;
import com.muyu.utils.IdUtils;
import com.muyu.utils.JwtUtils;
import com.muyu.web.domain.PositionRouteInfo;
import com.muyu.web.domain.ServerConfig;
import com.muyu.web.domain.UserInfo;
import com.muyu.web.domain.req.UserRegReq;
import com.muyu.web.mapper.UserInfoMapper;
import com.muyu.web.service.PositionRouteService;
import com.muyu.web.service.ServerConfigService;
import com.muyu.web.service.SystemAuthService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: DongZeLiang
* @date: 2024/9/12
* @Description:
* @Version: 1.0
*/
@Service
public class SystemAuthServiceImpl implements SystemAuthService {
@Autowired
private UserInfoMapper userInfoMapper;
@Autowired
private ServerConfigService serverConfigService;
@Resource( name = "loginUserCache")
private Cache<String, LoginUserInfo> loginUserInfoCache;
@Autowired
private CustomTenantHandler customTenantHandler;
@Autowired
private PositionRouteService positionRouteService;
/**
*
*
* @param userName
* @param password
*
* @return
*/
@Override
public String login (String userName, String password) {
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UserInfo::getUserName, userName);
queryWrapper.eq(UserInfo::getPassword, password);
List<UserInfo> userInfoList = userInfoMapper.selectList(queryWrapper);
if (userInfoList.isEmpty()){
throw new RuntimeException("用户用户名或者密码错误");
}
UserInfo userInfo = userInfoList.get(0);
LambdaQueryWrapper<ServerConfig> serverConfigQueryWrapper = new LambdaQueryWrapper<>();
serverConfigQueryWrapper.eq(ServerConfig::getTenantId, userInfo.getTenantId());
customTenantHandler.ignore();
ServerConfig serverConfig = serverConfigService.getOne(serverConfigQueryWrapper);
customTenantHandler.remove();
LoginUserInfo loginUserInfo = LoginUserInfo.builder()
.id(userInfo.getId())
.tenantId(userInfo.getTenantId())
.userName(userInfo.getUserName())
.serverConfig(
ServerConfigProperties.configToProperties(serverConfig)
)
.build();
String userKey = IdUtils.fastUUID();
loginUserInfo.setUserKey(userKey);
loginUserInfoCache.put(userKey, loginUserInfo);
// Jwt存储信息
Map<String, Object> claimsMap = new HashMap<String, Object>();
claimsMap.put(SecurityConstants.USER_KEY, userKey);
claimsMap.put(SecurityConstants.DETAILS_USER_ID, userInfo.getId());
claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
return JwtUtils.createToken(claimsMap);
}
/**
*
*/
@Override
public void logout () {
loginUserInfoCache.invalidate(SystemHandler.getUserKey());
}
/**
*
*
* @return
*/
@Override
public LoginUserInfo info () {
return SystemHandler.getUserInfo();
}
/**
*
*
* @param userRegReq
*/
@Override
@Transactional
public void reg (UserRegReq userRegReq) {
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UserInfo::getUserName, userRegReq.getUserName());
Long selectCount = userInfoMapper.selectCount(queryWrapper);
if (!selectCount.equals(0L)){
throw new RuntimeException("用户名称重复,请重新输入");
}
UserInfo userInfo = UserInfo.builder()
.userName(userRegReq.getUserName())
.password(userRegReq.getPassword())
.createTime(new Date())
.tenantId("TX_" + IdUtils.simpleUUID().substring(0, 10).toUpperCase())
.build();
this.userInfoMapper.insert(userInfo);
customTenantHandler.ignore();
LambdaQueryWrapper<PositionRouteInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(PositionRouteInfo::getTenantId, "TX_8689BE3CDB");
List<PositionRouteInfo> positionRouteInfoList = positionRouteService.list(lambdaQueryWrapper);
for (PositionRouteInfo positionRouteInfo : positionRouteInfoList) {
positionRouteInfo.setId(null);
positionRouteInfo.setTenantId(userInfo.getTenantId());
}
positionRouteService.saveBatch(positionRouteInfoList);
serverConfigService.save(
ServerConfig.builder()
.tenantId(userInfo.getTenantId())
.host("127.0.0.1")
.port("81")
.uri("/verify/vehicleConnection")
.defaultMqttAddr("127.0.0.1")
.defaultMqttTopic("vehicle")
.defaultMqttQos(1)
.build()
);
customTenantHandler.remove();
}
}

View File

@ -3,11 +3,10 @@ package com.muyu.web.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.muyu.system.handle.SystemHandler;
import com.muyu.web.domain.VehicleInfo;
import com.muyu.web.mapper.VehicleInfoMapper;
import com.muyu.web.domain.Vehicle;
import com.muyu.web.mapper.VehicleMapper;
import com.muyu.web.service.VehicleInstanceService;
import com.muyu.web.service.VehicleInfoService;
import com.muyu.web.service.VehicleService;
import com.muyu.vehicle.VehicleInstance;
import com.muyu.vehicle.core.LocalContainer;
import lombok.extern.log4j.Log4j2;
@ -31,7 +30,7 @@ import java.util.stream.Stream;
*/
@Log4j2
@Service
public class VechileInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, VehicleInfo> implements VehicleInfoService {
public class VechileServiceImpl extends ServiceImpl<VehicleMapper, Vehicle> implements VehicleService {
@Autowired
@ -40,37 +39,32 @@ public class VechileInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
/**
*
*
* @param sum
* @param messageTemplateId
* @param sum
*/
@Override
@Transactional
public void generate (Integer sum, Long messageTemplateId) {
List<VehicleInfo> vehicleInfoList =
Stream.generate(() -> VehicleInfo.gen(() -> messageTemplateId == null ? 0 : messageTemplateId))
.limit(sum)
.toList();
this.saveBatch(vehicleInfoList);
vehicleInfoList.forEach(vehicleInstanceService::init);
public void generate (Integer sum) {
List<Vehicle> vehicleList = Stream.generate(Vehicle::gen).limit(sum).toList();
this.saveBatch(vehicleList);
vehicleList.forEach(vehicleInstanceService::init);
}
/**
* IVN
*
* @param vinStr VIN
* @param messageTemplateId
* @param vinStr VIN
*/
@Override
@Transactional
public void create (List<String> vinList, Long messageTemplateId) {
public void create (String vinStr) {
String[] vinList = vinStr.split("\n");
StringBuilder errorMsg = new StringBuilder();
for (String vin : vinList) {
if (vin.length() != 17) {
errorMsg.append("vin[").append(vin).append("]").append("不为17位\n");
} else {
LambdaQueryWrapper<VehicleInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(VehicleInfo::getVin, vin);
queryWrapper.eq(VehicleInfo::getTenantId, SystemHandler.getTenantId());
LambdaQueryWrapper<Vehicle> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Vehicle::getVin, vin);
long count = this.count(queryWrapper);
if (count == 1) {
errorMsg.append("vin[").append(vin).append("]").append("已经存在\n");
@ -80,11 +74,9 @@ public class VechileInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
if (!errorMsg.isEmpty()) {
throw new RuntimeException(errorMsg.toString());
}
List<VehicleInfo> vehicleInfoList = vinList.stream()
.map((String vin) -> VehicleInfo.create(vin, () -> messageTemplateId == null ? 0 : messageTemplateId))
.toList();
this.saveBatch(vehicleInfoList);
vehicleInfoList.forEach(vehicleInstanceService::init);
List<Vehicle> vehicleList = Arrays.stream(vinList).map(Vehicle::create).toList();
this.saveBatch(vehicleList);
vehicleList.forEach(vehicleInstanceService::init);
}
/**
@ -96,18 +88,18 @@ public class VechileInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
// vehicleInstanceService.isTaskStatus();
log.info("同步数据库开始");
long startTime = System.currentTimeMillis();
Collection<VehicleInstance> vehicleInstanceList = LocalContainer.getTenantOnlineVehicleInstance();
Collection<VehicleInstance> vehicleInstanceList = LocalContainer.getOnlineVehicleInstance();
// 成功数量
AtomicInteger syncSuccessSum = new AtomicInteger();
List<VehicleInfo> vehicleInfoList = vehicleInstanceList.stream()
List<Vehicle> vehicleList = vehicleInstanceList.stream()
.filter(VehicleInstance::isOnline)
.map(VehicleInfo::instanceBuild)
.map(Vehicle::instanceBuild)
.toList();
vehicleInfoList.forEach(vehicle -> {
LambdaUpdateWrapper<VehicleInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(VehicleInfo::getRemainingBattery, vehicle.getRemainingBattery());
updateWrapper.set(VehicleInfo::getTotalMileage, vehicle.getTotalMileage());
updateWrapper.eq(VehicleInfo::getVin, vehicle.getVin());
vehicleList.forEach(vehicle -> {
LambdaUpdateWrapper<Vehicle> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(Vehicle::getRemainingBattery, vehicle.getRemainingBattery());
updateWrapper.set(Vehicle::getTotalMileage, vehicle.getTotalMileage());
updateWrapper.eq(Vehicle::getVin, vehicle.getVin());
try {
this.update(updateWrapper);
syncSuccessSum.incrementAndGet();
@ -117,7 +109,7 @@ public class VechileInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
}
});
log.info("同步数据库结束 - 耗时:[{}MS],同步量:[{}辆],成功:[{}辆],失败:[{}辆]",
System.currentTimeMillis() - startTime, vehicleInfoList.size(),syncSuccessSum.get(), vehicleInfoList.size() - syncSuccessSum.get());
System.currentTimeMillis() - startTime, vehicleList.size(),syncSuccessSum.get(), vehicleList.size() - syncSuccessSum.get());
}catch (Exception exception){
log.error("数据同步异常:{}", exception.getMessage(), exception);
}

View File

@ -1,7 +1,5 @@
package com.muyu.web.service.impl;
import com.github.benmanes.caffeine.cache.Cache;
import com.muyu.cache.model.MessageTemplateCacheModel;
import com.muyu.vehicle.VehicleInstance;
import com.muyu.vehicle.api.ClientAdmin;
import com.muyu.vehicle.api.req.VehicleConnectionReq;
@ -10,18 +8,18 @@ import com.muyu.vehicle.model.VehicleData;
import com.muyu.vehicle.model.properties.MqttProperties;
import com.muyu.web.common.PageList;
import com.muyu.web.common.Result;
import com.muyu.web.domain.VehicleInfo;
import com.muyu.web.domain.Vehicle;
import com.muyu.web.domain.model.MqttServerModel;
import com.muyu.web.domain.model.PositionModel;
import com.muyu.web.domain.req.CheckPositionReq;
import com.muyu.web.domain.req.GearReq;
import com.muyu.web.domain.req.MsgReq;
import com.muyu.web.domain.req.VehicleInstanceListReq;
import com.muyu.web.domain.resp.VehicleInstanceResp;
import com.muyu.web.service.PositionRouteService;
import com.muyu.web.service.VehicleInstanceService;
import com.muyu.web.utils.MD5Util;
import com.muyu.web.utils.ReflectUtils;
import jakarta.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -30,7 +28,6 @@ import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Stream;
/**
@ -49,28 +46,19 @@ public class VehicleInstanceServiceImpl implements VehicleInstanceService {
@Autowired
private ClientAdmin clientAdmin;
/**
*
*/
@Resource(name = "messageTemplateCache")
private Cache<Long, MessageTemplateCacheModel> messageTemplateCache;
/**
*
*
* @param vehicleInfo
* @param vehicle
*/
@Override
public void init(VehicleInfo vehicleInfo) {
public void init(Vehicle vehicle) {
VehicleInstance vehicleInstance = new VehicleInstance();
vehicleInstance.setVehicleInfo(vehicleInfo);
vehicleInstance.setVehicleData(VehicleData.vehicleBuild(vehicleInfo));
vehicleInstance.setMessageTemplate(
messageTemplateCache.get(vehicleInfo.getMessageTemplateId(), messageTemplateId -> MessageTemplateCacheModel.builder().build())
);
vehicleInstance.setVehicle(vehicle);
vehicleInstance.setVehicleData(VehicleData.vehicleBuild(vehicle));
LocalContainer.setVehicleInstance(vehicleInstance);
log.debug("构建车辆对象: [{}]", vehicleInfo.getVin());
log.debug("构建车辆对象: [{}]", vehicle.getVin());
}
/**
@ -82,7 +70,7 @@ public class VehicleInstanceServiceImpl implements VehicleInstanceService {
*/
@Override
public PageList<VehicleInstanceResp> queryList (VehicleInstanceListReq vehicleInstanceListReq) {
Stream<VehicleInstance> stream = LocalContainer.getTenantVehicleDataMap().values()
Stream<VehicleInstance> stream = LocalContainer.vehicleDataMap.values()
.stream();
if (StringUtils.isNotBlank(vehicleInstanceListReq.getVin())){
stream = stream.filter(vehicleInstance ->
@ -111,7 +99,7 @@ public class VehicleInstanceServiceImpl implements VehicleInstanceService {
* @param vin vin
*/
@Override
public void vehicleClientStart (String vin) {
public void vehicleClientInit (String vin) {
log.info("vin[{}],开始上线", vin);
VehicleInstance vehicleInstance = LocalContainer.getVehicleInstance(vin);
if (vehicleInstance == null){
@ -128,9 +116,7 @@ public class VehicleInstanceServiceImpl implements VehicleInstanceService {
Result<MqttServerModel> result = clientAdmin.getVehicleLoadAddr(connectionReq);
if (result.getCode() != 200){
log.error("车辆:[{}],申请上线异常:[{}]", vin, result.getMsg());
throw new RuntimeException(
String.format("车辆:[%s],申请上线异常:[%s]", vin, result.getMsg())
);
throw new RuntimeException("远程服务器没有【"+vin+"】车辆");
}
MqttServerModel mqttServerModel = result.getData();
MqttProperties mqttProperties = MqttProperties.builder()
@ -171,6 +157,27 @@ public class VehicleInstanceServiceImpl implements VehicleInstanceService {
vehicleInstance.setPositionCode(checkPositionReq.getPositionCode());
}
/**
*
*
* @param msgReq
*/
@Override
public void msg (MsgReq msgReq) {
VehicleInstance vehicleInstance = LocalContainer.getVehicleInstance(msgReq.getVin());
switch (msgReq.getMsgCode()){
case "上报" -> {
if(vehicleInstance.getVehicleThread() == null){
vehicleInstance.initVehicleThread();
}
vehicleInstance.startSend();
}
case "暂停" -> vehicleInstance.pauseSend();
case "停止" -> vehicleInstance.stopSend();
default -> throw new RuntimeException("车辆消息事件错误");
}
}
/**
*
*

View File

@ -6,6 +6,7 @@ import com.muyu.vehicle.core.LocalContainer;
import com.muyu.web.domain.PositionRouteInfo;
import com.muyu.web.domain.model.PositionModel;
import com.muyu.web.domain.model.TaskModel;
import com.muyu.web.domain.req.MsgReq;
import com.muyu.web.domain.resp.UnifiedTaskResp;
import com.muyu.web.service.PositionRouteService;
import com.muyu.web.service.VehicleInstanceService;
@ -50,7 +51,7 @@ public class VehicleUnifiedServiceImpl implements VehicleUnifiedService {
.map(VehicleInstance::getVin)
.toList();
taskModel.submit("一键上线", vinList, (vin) -> {
vehicleInstanceService.vehicleClientStart(vin);
vehicleInstanceService.vehicleClientInit(vin);
});
}
@ -95,6 +96,12 @@ public class VehicleUnifiedServiceImpl implements VehicleUnifiedService {
vehicleInstance.setPositionCode(positionCode);
// 设置车辆档位
vehicleInstance.setGear("D");
vehicleInstanceService.msg(
MsgReq.builder()
.vin(vin)
.msgCode("上报")
.build()
);
});
}
@ -136,6 +143,12 @@ public class VehicleUnifiedServiceImpl implements VehicleUnifiedService {
// 获取在线车辆VIN
List<String> vinList = LocalContainer.getOnlineVehicleVin();
taskModel.submit("一键取消上报", vinList, (vin) -> {
vehicleInstanceService.msg(
MsgReq.builder()
.vin(vin)
.msgCode("停止")
.build()
);
});
}

View File

@ -1,23 +1,36 @@
server:
port: 9865
port: 81
spring:
main:
allow-circular-references: true
mvc:
static-path-pattern: /static/**
# 数据源配置
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: 2ZitL3jpzknSZrWv7sXHKxVrqb6a+IESAbAQ7JPw71zjt+9oPTC40vnZ6ocXjW6/m8uUerZINCQtVyBbz0GFI8ycOxuM9zgxLswJu1P/yW2crEvrVXA2Fu4v1c9bWpZ1cWRBXhYq1VYu/nYAetZuTaX9WVgzLwClczrZjMT8kJVleiDsvZLx6e5z0W9vfzxuGPLpwZpAeBT8QzcVoZaONGPzCcIcSXPysjKvhrPiYoA=
username: HskuzU7cEWAMeTvYdlc4yg==
password: 4ULjnyG3ZFlyKeCCT6hySw==
name: vehicle-test-db
generate-unique-name: false
username: muyu
password: 123456
# 如果需要数据本地化,则改成 file 方式
# jdbc:h2:mem:testDB;DB_CLOSE_DELAY=-1
url: jdbc:h2:file:./db/vehicleSimulationDataBaseFile;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1
driver-class-name: org.h2.Driver
h2:
# 开启这个配置就可以通过 web 页面访问了例如http://localhost:8080/springboot-h2/h2-console
console:
enabled: true
settings:
# 开启h2 console 跟踪 方便调试 默认 false
trace: false
# 允许console 远程访问 默认false
web-allow-others: true
# h2 访问路径上下文
path: /h2-console
# mybatis-plus 配置
mybatis-plus:
mapper-locations: classpath*:/com.muyu.mapper/**/*.xml
#实体扫描多个package用逗号或者分号分隔
typeAliasesPackage: com.dmo.entity
global-config:
#数据库相关配置
db-config:

View File

@ -1 +0,0 @@
.box-card[data-v-6151d512]{margin-top:20px}.grid-content[data-v-6151d512]{margin-top:10px;border-radius:4px;overflow-x:hidden;overflow-y:auto}.grid-content[data-v-6151d512]::-webkit-scrollbar{width:4px}.grid-content[data-v-6151d512]::-webkit-scrollbar-thumb{border-radius:10px;background:rgba(0,0,0,.2)}.grid-content[data-v-6151d512]::-webkit-scrollbar-track{border-radius:0;background:rgba(0,0,0,.1)}.el-dialog[data-v-6151d512]{background-color:#fff}

View File

@ -0,0 +1 @@
.app-container[data-v-26d8c57e]{padding:10px 5px 0 10px;background-color:#f4f4f5}.el-row[data-v-26d8c57e]{&:last-child{margin-bottom:0}}.bg-purple[data-v-26d8c57e]{background:#f4f4f5}.grid-content[data-v-26d8c57e]{border-radius:4px;overflow-x:hidden;overflow-y:auto}.grid-content[data-v-26d8c57e]::-webkit-scrollbar{width:4px}.grid-content[data-v-26d8c57e]::-webkit-scrollbar-thumb{border-radius:10px;background:rgba(0,0,0,.2)}.grid-content[data-v-26d8c57e]::-webkit-scrollbar-track{border-radius:0;background:rgba(0,0,0,.1)}.vehicleDiv[data-v-26d8c57e]{height:50px;margin:0 0 10px 0}.contentMain[data-v-26d8c57e]{margin-top:10px}.vehicleDataTab[data-v-26d8c57e]{width:100%;overflow-y:auto;overflow-x:hidden}.vehicleDataTab[data-v-26d8c57e]::-webkit-scrollbar{width:4px}.vehicleDataTab[data-v-26d8c57e]::-webkit-scrollbar-thumb{border-radius:10px;background:rgba(0,0,0,.2)}.vehicleDataTab[data-v-26d8c57e]::-webkit-scrollbar-track{border-radius:0;background:rgba(0,0,0,.1)}.el-form-item__label[data-v-26d8c57e]{padding:0}.el-form-item[data-v-26d8c57e]{margin-bottom:5px}

View File

@ -1 +0,0 @@
.el-col[data-v-7a92ea84]{margin-top:20px}

View File

@ -0,0 +1 @@
@supports(-webkit-mask:none) and (not (cater-color:#fff)){.login-container .el-input input{color:#fff}}.login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#fff;height:47px;caret-color:#fff}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #283443 inset!important;box-shadow:inset 0 0 0 1000px #283443!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container[data-v-5d9ae9a2]{min-height:100%;width:100%;background-color:#2d3a4b;overflow:hidden}.login-container .login-form[data-v-5d9ae9a2]{position:relative;width:520px;max-width:100%;padding:160px 35px 0;margin:0 auto;overflow:hidden}.login-container .tips[data-v-5d9ae9a2]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips span[data-v-5d9ae9a2]:first-of-type{margin-right:16px}.login-container .svg-container[data-v-5d9ae9a2]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title-container[data-v-5d9ae9a2]{position:relative}.login-container .title-container .title[data-v-5d9ae9a2]{font-size:26px;color:#eee;margin:0 auto 40px auto;text-align:center;font-weight:700}.login-container .show-pwd[data-v-5d9ae9a2]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}

View File

@ -1 +0,0 @@
.app-container[data-v-2ab19043]{padding:10px 5px 0 10px;background-color:#f4f4f5}.el-row[data-v-2ab19043]{&:last-child{margin-bottom:0}}.bg-purple[data-v-2ab19043]{background:#f4f4f5}.grid-content[data-v-2ab19043]{border-radius:4px;overflow-x:hidden;overflow-y:auto}.grid-content[data-v-2ab19043]::-webkit-scrollbar{width:4px}.grid-content[data-v-2ab19043]::-webkit-scrollbar-thumb{border-radius:10px;background:rgba(0,0,0,.2)}.grid-content[data-v-2ab19043]::-webkit-scrollbar-track{border-radius:0;background:rgba(0,0,0,.1)}.vehicleDiv[data-v-2ab19043]{height:50px;margin:0 0 10px 0}.contentMain[data-v-2ab19043]{margin-top:10px}.vehicleDataTab[data-v-2ab19043]{width:100%;overflow-y:auto;overflow-x:hidden}.vehicleDataTab[data-v-2ab19043]::-webkit-scrollbar{width:4px}.vehicleDataTab[data-v-2ab19043]::-webkit-scrollbar-thumb{border-radius:10px;background:rgba(0,0,0,.2)}.vehicleDataTab[data-v-2ab19043]::-webkit-scrollbar-track{border-radius:0;background:rgba(0,0,0,.1)}.el-form-item__label[data-v-2ab19043]{padding:0}.el-form-item[data-v-2ab19043]{margin-bottom:5px}

View File

@ -1 +0,0 @@
.el-dialog{background-color:#2d3a4b}@supports(-webkit-mask:none) and (not (cater-color:#fff)){.login-container .el-input input{color:#fff}}.login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#fff;height:47px;caret-color:#fff}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #283443 inset!important;box-shadow:inset 0 0 0 1000px #283443!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container[data-v-7fa60b7a]{min-height:100%;width:100%;background-color:#2d3a4b;overflow:hidden}.login-container .login-form[data-v-7fa60b7a]{position:relative;width:520px;max-width:100%;padding:160px 35px 0;margin:0 auto;overflow:hidden}.login-container .tips[data-v-7fa60b7a]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips span[data-v-7fa60b7a]:first-of-type{margin-right:16px}.login-container .svg-container[data-v-7fa60b7a]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title-container[data-v-7fa60b7a]{position:relative}.login-container .title-container .title[data-v-7fa60b7a]{font-size:26px;color:#eee;margin:0 auto 40px auto;text-align:center;font-weight:700}.login-container .show-pwd[data-v-7fa60b7a]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}

View File

@ -0,0 +1 @@
.el-col[data-v-1fac6224]{margin-top:20px}

View File

@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=/favicon.ico><title>车辆</title><link href=/static/css/app.e2ca9161.css rel=preload as=style><link href=/static/css/chunk-elementUI.c1c3b808.css rel=preload as=style><link href=/static/css/chunk-libs.3dfb7769.css rel=preload as=style><link href=/static/js/app.a2f5934b.js rel=preload as=script><link href=/static/js/chunk-elementUI.2491fb2f.js rel=preload as=script><link href=/static/js/chunk-libs.5e39c7d0.js rel=preload as=script><link href=/static/css/chunk-elementUI.c1c3b808.css rel=stylesheet><link href=/static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=/static/css/app.e2ca9161.css rel=stylesheet></head><body><noscript><strong>We're sorry but 车辆 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function t(t){for(var r,c,u=t[0],f=t[1],i=t[2],l=0,d=[];l<u.length;l++)c=u[l],Object.prototype.hasOwnProperty.call(o,c)&&o[c]&&d.push(o[c][0]),o[c]=0;for(r in f)Object.prototype.hasOwnProperty.call(f,r)&&(e[r]=f[r]);s&&s(t);while(d.length)d.shift()();return a.push.apply(a,i||[]),n()}function n(){for(var e,t=0;t<a.length;t++){for(var n=a[t],r=!0,c=1;c<n.length;c++){var u=n[c];0!==o[u]&&(r=!1)}r&&(a.splice(t--,1),e=f(f.s=n[0]))}return e}var r={},c={runtime:0},o={runtime:0},a=[];function u(e){return f.p+"static/js/"+({}[e]||e)+"."+{"chunk-00a52ac4":"5f82d470","chunk-159c7f2c":"0fa7a8a3","chunk-2cbbeb82":"e1753706","chunk-643fd843":"ad8a85d9","chunk-6f60c8f1":"f16bf298","chunk-0e8cf5f4":"b7552abc","chunk-7d1a163b":"4d8cc933","chunk-8f81ac56":"da9fce35"}[e]+".js"}function f(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,f),n.l=!0,n.exports}f.e=function(e){var t=[],n={"chunk-00a52ac4":1,"chunk-159c7f2c":1,"chunk-2cbbeb82":1,"chunk-643fd843":1,"chunk-0e8cf5f4":1,"chunk-8f81ac56":1};c[e]?t.push(c[e]):0!==c[e]&&n[e]&&t.push(c[e]=new Promise((function(t,n){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-00a52ac4":"71c8f52e","chunk-159c7f2c":"3c7f5ad9","chunk-2cbbeb82":"59a1d200","chunk-643fd843":"5488218b","chunk-6f60c8f1":"31d6cfe0","chunk-0e8cf5f4":"3328abfd","chunk-7d1a163b":"31d6cfe0","chunk-8f81ac56":"1efc9dd1"}[e]+".css",o=f.p+r,a=document.getElementsByTagName("link"),u=0;u<a.length;u++){var i=a[u],l=i.getAttribute("data-href")||i.getAttribute("href");if("stylesheet"===i.rel&&(l===r||l===o))return t()}var d=document.getElementsByTagName("style");for(u=0;u<d.length;u++){i=d[u],l=i.getAttribute("data-href");if(l===r||l===o)return t()}var s=document.createElement("link");s.rel="stylesheet",s.type="text/css",s.onload=t,s.onerror=function(t){var r=t&&t.target&&t.target.src||o,a=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");a.code="CSS_CHUNK_LOAD_FAILED",a.request=r,delete c[e],s.parentNode.removeChild(s),n(a)},s.href=o;var h=document.getElementsByTagName("head")[0];h.appendChild(s)})).then((function(){c[e]=0})));var r=o[e];if(0!==r)if(r)t.push(r[2]);else{var a=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=a);var i,l=document.createElement("script");l.charset="utf-8",l.timeout=120,f.nc&&l.setAttribute("nonce",f.nc),l.src=u(e);var d=new Error;i=function(t){l.onerror=l.onload=null,clearTimeout(s);var n=o[e];if(0!==n){if(n){var r=t&&("load"===t.type?"missing":t.type),c=t&&t.target&&t.target.src;d.message="Loading chunk "+e+" failed.\n("+r+": "+c+")",d.name="ChunkLoadError",d.type=r,d.request=c,n[1](d)}o[e]=void 0}};var s=setTimeout((function(){i({type:"timeout",target:l})}),12e4);l.onerror=l.onload=i,document.head.appendChild(l)}return Promise.all(t)},f.m=e,f.c=r,f.d=function(e,t,n){f.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},f.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,t){if(1&t&&(e=f(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(f.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)f.d(n,r,function(t){return e[t]}.bind(null,r));return n},f.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return f.d(t,"a",t),t},f.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},f.p="/",f.oe=function(e){throw console.error(e),e};var i=window["webpackJsonp"]=window["webpackJsonp"]||[],l=i.push.bind(i);i.push=t,i=i.slice();for(var d=0;d<i.length;d++)t(i[d]);var s=l;n()})([]);</script><script src=/static/js/chunk-elementUI.2491fb2f.js></script><script src=/static/js/chunk-libs.5e39c7d0.js></script><script src=/static/js/app.a2f5934b.js></script></body></html>
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=/favicon.ico><title>车辆</title><link href=/static/css/app.63269458.css rel=preload as=style><link href=/static/css/chunk-elementUI.c1c3b808.css rel=preload as=style><link href=/static/css/chunk-libs.3dfb7769.css rel=preload as=style><link href=/static/js/app.aa5f6632.js rel=preload as=script><link href=/static/js/chunk-elementUI.2491fb2f.js rel=preload as=script><link href=/static/js/chunk-libs.2ec7c235.js rel=preload as=script><link href=/static/css/chunk-elementUI.c1c3b808.css rel=stylesheet><link href=/static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=/static/css/app.63269458.css rel=stylesheet></head><body><noscript><strong>We're sorry but 车辆 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function t(t){for(var r,o,u=t[0],i=t[1],f=t[2],l=0,s=[];l<u.length;l++)o=u[l],Object.prototype.hasOwnProperty.call(c,o)&&c[o]&&s.push(c[o][0]),c[o]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);d&&d(t);while(s.length)s.shift()();return a.push.apply(a,f||[]),n()}function n(){for(var e,t=0;t<a.length;t++){for(var n=a[t],r=!0,o=1;o<n.length;o++){var u=n[o];0!==c[u]&&(r=!1)}r&&(a.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},o={runtime:0},c={runtime:0},a=[];function u(e){return i.p+"static/js/"+({}[e]||e)+"."+{"chunk-019c66da":"ded8571e","chunk-123c65a8":"078492c0","chunk-6f60c8f1":"f16bf298","chunk-4a014042":"2fe4ac72","chunk-6fb69ae7":"8ca4dbc6","chunk-e4980b30":"83907799","chunk-22cea610":"fd8494c8","chunk-510f32e7":"792568de"}[e]+".js"}function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.e=function(e){var t=[],n={"chunk-123c65a8":1,"chunk-4a014042":1,"chunk-e4980b30":1,"chunk-22cea610":1,"chunk-510f32e7":1};o[e]?t.push(o[e]):0!==o[e]&&n[e]&&t.push(o[e]=new Promise((function(t,n){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-019c66da":"31d6cfe0","chunk-123c65a8":"887652d5","chunk-6f60c8f1":"31d6cfe0","chunk-4a014042":"3328abfd","chunk-6fb69ae7":"31d6cfe0","chunk-e4980b30":"27dfab27","chunk-22cea610":"3c7f5ad9","chunk-510f32e7":"1510e3c5"}[e]+".css",c=i.p+r,a=document.getElementsByTagName("link"),u=0;u<a.length;u++){var f=a[u],l=f.getAttribute("data-href")||f.getAttribute("href");if("stylesheet"===f.rel&&(l===r||l===c))return t()}var s=document.getElementsByTagName("style");for(u=0;u<s.length;u++){f=s[u],l=f.getAttribute("data-href");if(l===r||l===c)return t()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=t,d.onerror=function(t){var r=t&&t.target&&t.target.src||c,a=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");a.code="CSS_CHUNK_LOAD_FAILED",a.request=r,delete o[e],d.parentNode.removeChild(d),n(a)},d.href=c;var h=document.getElementsByTagName("head")[0];h.appendChild(d)})).then((function(){o[e]=0})));var r=c[e];if(0!==r)if(r)t.push(r[2]);else{var a=new Promise((function(t,n){r=c[e]=[t,n]}));t.push(r[2]=a);var f,l=document.createElement("script");l.charset="utf-8",l.timeout=120,i.nc&&l.setAttribute("nonce",i.nc),l.src=u(e);var s=new Error;f=function(t){l.onerror=l.onload=null,clearTimeout(d);var n=c[e];if(0!==n){if(n){var r=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;s.message="Loading chunk "+e+" failed.\n("+r+": "+o+")",s.name="ChunkLoadError",s.type=r,s.request=o,n[1](s)}c[e]=void 0}};var d=setTimeout((function(){f({type:"timeout",target:l})}),12e4);l.onerror=l.onload=f,document.head.appendChild(l)}return Promise.all(t)},i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var f=window["webpackJsonp"]=window["webpackJsonp"]||[],l=f.push.bind(f);f.push=t,f=f.slice();for(var s=0;s<f.length;s++)t(f[s]);var d=l;n()})([]);</script><script src=/static/js/chunk-elementUI.2491fb2f.js></script><script src=/static/js/chunk-libs.2ec7c235.js></script><script src=/static/js/app.aa5f6632.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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