remove gson
This commit is contained in:
14
pom.xml
14
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.4.0</version>
|
<version>3.5.11</version>
|
||||||
<relativePath/>
|
<relativePath/>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<description>imyeyu.com API</description>
|
<description>imyeyu.com API</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<springboot.version>3.4.0</springboot.version>
|
<springboot.version>3.5.11</springboot.version>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
<maven.compiler.multilingualField>21</maven.compiler.multilingualField>
|
<maven.compiler.multilingualField>21</maven.compiler.multilingualField>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
@@ -122,12 +122,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.imyeyu.spring</groupId>
|
<groupId>com.imyeyu.spring</groupId>
|
||||||
<artifactId>timi-spring</artifactId>
|
<artifactId>timi-spring</artifactId>
|
||||||
<version>0.0.2</version>
|
<version>0.0.9</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.imyeyu.network</groupId>
|
<groupId>com.imyeyu.network</groupId>
|
||||||
<artifactId>timi-network</artifactId>
|
<artifactId>timi-network</artifactId>
|
||||||
<version>0.0.2</version>
|
<version>0.0.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.imyeyu.lang</groupId>
|
<groupId>com.imyeyu.lang</groupId>
|
||||||
@@ -184,12 +184,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jgit</groupId>
|
<groupId>org.eclipse.jgit</groupId>
|
||||||
<artifactId>org.eclipse.jgit</artifactId>
|
<artifactId>org.eclipse.jgit</artifactId>
|
||||||
<version>6.7.0.202309050840-r</version>
|
<version>7.2.1.202505142326-r</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jgit</groupId>
|
<groupId>org.eclipse.jgit</groupId>
|
||||||
<artifactId>org.eclipse.jgit.archive</artifactId>
|
<artifactId>org.eclipse.jgit.archive</artifactId>
|
||||||
<version>6.7.0.202309050840-r</version>
|
<version>7.2.1.202505142326-r</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
@@ -220,7 +220,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.tika</groupId>
|
<groupId>org.apache.tika</groupId>
|
||||||
<artifactId>tika-core</artifactId>
|
<artifactId>tika-core</artifactId>
|
||||||
<version>2.9.2</version>
|
<version>3.2.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jcodec</groupId>
|
<groupId>org.jcodec</groupId>
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.imyeyu.api.bean;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author 夜雨
|
|
||||||
* @since 2025-01-13 11:42
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class IOCBeans {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Yaml yaml() {
|
|
||||||
return new Yaml();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
package com.imyeyu.api.config;
|
package com.imyeyu.api.config;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.imyeyu.utils.Time;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author 夜雨
|
* @author 夜雨
|
||||||
@@ -10,7 +15,17 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class BeanConfig {
|
public class BeanConfig {
|
||||||
|
|
||||||
public Gson gson() {
|
@Bean
|
||||||
return new Gson();
|
public ObjectMapper jackson() {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
mapper.setDateFormat(Time.dateTime);
|
||||||
|
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||||
|
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Yaml yaml() {
|
||||||
|
return new Yaml();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.imyeyu.spring.bean.RedisConfigParams;
|
|||||||
import com.imyeyu.spring.config.AbstractRedisConfig;
|
import com.imyeyu.spring.config.AbstractRedisConfig;
|
||||||
import com.imyeyu.spring.util.Redis;
|
import com.imyeyu.spring.util.Redis;
|
||||||
import com.imyeyu.spring.util.RedisSerializers;
|
import com.imyeyu.spring.util.RedisSerializers;
|
||||||
|
import io.lettuce.core.api.StatefulConnection;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||||
@@ -155,12 +156,13 @@ public class RedisConfig extends AbstractRedisConfig {
|
|||||||
/** @return 连接池配置 */
|
/** @return 连接池配置 */
|
||||||
@Bean
|
@Bean
|
||||||
@Override
|
@Override
|
||||||
public GenericObjectPoolConfig<?> getPoolConfig() {
|
public GenericObjectPoolConfig<StatefulConnection<?, ?>> getPoolConfig() {
|
||||||
GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();
|
RedisConfigParams configArgs = configParams();
|
||||||
config.setMaxTotal(lettuce.pool.maxActive);
|
GenericObjectPoolConfig<StatefulConnection<?, ?>> config = new GenericObjectPoolConfig<>();
|
||||||
config.setMinIdle(lettuce.pool.minIdle);
|
config.setMaxTotal(8);
|
||||||
config.setMaxIdle(lettuce.pool.maxIdle);
|
config.setMinIdle(configArgs.getMinIdle());
|
||||||
config.setMaxWait(Duration.ofMillis(lettuce.pool.maxWait));
|
config.setMaxIdle(configArgs.getMaxIdle());
|
||||||
|
config.setMaxWait(Duration.ofMillis(-1));
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +226,7 @@ public class RedisConfig extends AbstractRedisConfig {
|
|||||||
/** @return 文章访问统计,文章 ID: {@link ArticleRanking}(JSON) */
|
/** @return 文章访问统计,文章 ID: {@link ArticleRanking}(JSON) */
|
||||||
@Bean("redisArticleRanking")
|
@Bean("redisArticleRanking")
|
||||||
public Redis<Long, ArticleRanking> getArticleRankingRedisTemplate() {
|
public Redis<Long, ArticleRanking> getArticleRankingRedisTemplate() {
|
||||||
return getRedis(database.articleRanking, RedisSerializers.LONG, RedisSerializers.gsonSerializer(ArticleRanking.class));
|
return getRedis(database.articleRanking, RedisSerializers.LONG, RedisSerializers.jacksonSerializer(ArticleRanking.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return 文章访问记录,IP: [文章 ID] */
|
/** @return 文章访问记录,IP: [文章 ID] */
|
||||||
|
|||||||
@@ -1,32 +1,28 @@
|
|||||||
package com.imyeyu.api.config;
|
package com.imyeyu.api.config;
|
||||||
|
|
||||||
import com.google.gson.GsonBuilder;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.MapperFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||||
import com.imyeyu.api.annotation.EnableSettingInterceptor;
|
import com.imyeyu.api.annotation.EnableSettingInterceptor;
|
||||||
import com.imyeyu.api.annotation.RequestRateLimitInterceptor;
|
import com.imyeyu.api.annotation.RequestRateLimitInterceptor;
|
||||||
import com.imyeyu.api.annotation.RequiredTokenInterceptor;
|
import com.imyeyu.api.annotation.RequiredTokenInterceptor;
|
||||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
|
||||||
import com.imyeyu.api.modules.common.vo.user.UserProfileView;
|
|
||||||
import com.imyeyu.api.modules.common.vo.user.UserView;
|
|
||||||
import com.imyeyu.api.modules.journal.util.JournalAPIInterceptor;
|
import com.imyeyu.api.modules.journal.util.JournalAPIInterceptor;
|
||||||
import com.imyeyu.api.modules.minecraft.annotation.RequiredFMCServerTokenInterceptor;
|
import com.imyeyu.api.modules.minecraft.annotation.RequiredFMCServerTokenInterceptor;
|
||||||
import com.imyeyu.api.modules.minecraft.entity.MinecraftPlayer;
|
|
||||||
import com.imyeyu.api.modules.mirror.vo.MirrorView;
|
|
||||||
import com.imyeyu.api.modules.system.util.SystemAPIInterceptor;
|
import com.imyeyu.api.modules.system.util.SystemAPIInterceptor;
|
||||||
import com.imyeyu.api.util.GsonSerializerAdapter;
|
import com.imyeyu.spring.annotation.RequestBodyValueArgumentResolver;
|
||||||
import com.imyeyu.spring.annotation.RequestSingleParamResolver;
|
import com.imyeyu.utils.Time;
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.json.GsonHttpMessageConverter;
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
import java.io.Writer;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,12 +36,11 @@ import java.util.List;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class WebConfig implements WebMvcConfigurer {
|
public class WebConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
private final ObjectMapper jackson;
|
||||||
private final SystemAPIInterceptor systemAPIInterceptor;
|
private final SystemAPIInterceptor systemAPIInterceptor;
|
||||||
private final GsonSerializerAdapter gsonSerializerAdapter;
|
|
||||||
private final JournalAPIInterceptor journalAPIInterceptor;
|
private final JournalAPIInterceptor journalAPIInterceptor;
|
||||||
private final RequiredTokenInterceptor requiredTokenInterceptor;
|
private final RequiredTokenInterceptor requiredTokenInterceptor;
|
||||||
private final EnableSettingInterceptor enableSettingInterceptor;
|
private final EnableSettingInterceptor enableSettingInterceptor;
|
||||||
private final RequestSingleParamResolver requestSingleParamResolver;
|
|
||||||
private final RequestRateLimitInterceptor requestRateLimitInterceptor;
|
private final RequestRateLimitInterceptor requestRateLimitInterceptor;
|
||||||
private final RequiredFMCServerTokenInterceptor requiredFMCServerTokenInterceptor;
|
private final RequiredFMCServerTokenInterceptor requiredFMCServerTokenInterceptor;
|
||||||
|
|
||||||
@@ -66,7 +61,7 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||||
argumentResolvers.add(requestSingleParamResolver);
|
argumentResolvers.add(new RequestBodyValueArgumentResolver(jackson));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,22 +71,17 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
GsonHttpMessageConverter converter = new GsonHttpMessageConverter() {
|
JsonMapper jsonMapper = JsonMapper.builder()
|
||||||
|
// 设置默认属性包含规则:忽略 null 值
|
||||||
@Override
|
.serializationInclusion(JsonInclude.Include.NON_NULL)
|
||||||
protected void writeInternal(@NotNull Object object, Type type, @NonNull Writer writer) {
|
// 日期格式化
|
||||||
// 忽略参数类型,因为接口返回对象会被全局返回处理器包装为 TimiResponse,否则会序列化转型错误
|
.defaultDateFormat(Time.dateTime)
|
||||||
getGson().toJson(object, writer);
|
// 忽略不存在字段
|
||||||
}
|
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
|
||||||
};
|
// 启用默认视图包含
|
||||||
|
.enable(MapperFeature.DEFAULT_VIEW_INCLUSION).build();
|
||||||
GsonBuilder builder = new GsonBuilder();
|
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(jsonMapper);
|
||||||
builder.registerTypeAdapter(Attachment.class, gsonSerializerAdapter);
|
converter.setDefaultCharset(StandardCharsets.UTF_8);
|
||||||
builder.registerTypeAdapter(UserView.class, gsonSerializerAdapter);
|
|
||||||
builder.registerTypeAdapter(MirrorView.class, gsonSerializerAdapter);
|
|
||||||
builder.registerTypeAdapter(UserProfileView.class, gsonSerializerAdapter);
|
|
||||||
builder.registerTypeAdapter(MinecraftPlayer.class, gsonSerializerAdapter);
|
|
||||||
converter.setGson(builder.create());
|
|
||||||
converters.add(converter);
|
converters.add(converter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
package com.imyeyu.api.modules.bill.controller;
|
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import com.imyeyu.java.bean.timi.TimiCode;
|
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
|
||||||
import com.imyeyu.api.modules.bill.entity.Bill;
|
|
||||||
import com.imyeyu.api.modules.bill.service.BillService;
|
|
||||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
|
||||||
import com.imyeyu.api.modules.common.service.SettingService;
|
|
||||||
import com.imyeyu.spring.TimiSpring;
|
|
||||||
import com.imyeyu.spring.annotation.AOPLog;
|
|
||||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收支帐单接口
|
|
||||||
*
|
|
||||||
* @author 夜雨
|
|
||||||
* @since 2023-02-04 01:02
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@RestController
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@RequestMapping("/bill")
|
|
||||||
public class BillController {
|
|
||||||
|
|
||||||
private final BillService service;
|
|
||||||
private final SettingService settingService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建收支帐单
|
|
||||||
*
|
|
||||||
* @param bill 账单
|
|
||||||
*/
|
|
||||||
@AOPLog
|
|
||||||
@RequestRateLimit
|
|
||||||
@PostMapping("/create")
|
|
||||||
public void createREBill(@Valid @RequestBody Bill bill) {
|
|
||||||
if (!settingService.getAsString(SettingKey.BILL_API_TOKEN).equals(TimiSpring.getToken())) {
|
|
||||||
throw new TimiException(TimiCode.REQUEST_BAD).msgKey("token.illegal");
|
|
||||||
}
|
|
||||||
service.create(bill);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
package com.imyeyu.api.modules.bill.entity;
|
|
||||||
|
|
||||||
import jakarta.validation.constraints.DecimalMin;
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Getter;
|
|
||||||
import com.imyeyu.spring.entity.Entity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收支账单
|
|
||||||
*
|
|
||||||
* @author 夜雨
|
|
||||||
* @since 2022-03-29 11:28
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
public class Bill extends Entity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 类型
|
|
||||||
*
|
|
||||||
* @author 夜雨
|
|
||||||
* @since 2022-03-29 11:28
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
public enum Type {
|
|
||||||
|
|
||||||
/** 收入 */
|
|
||||||
REVENUE,
|
|
||||||
|
|
||||||
/** 支出 */
|
|
||||||
EXPENDITURE
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收入类型
|
|
||||||
*
|
|
||||||
* @author 夜雨
|
|
||||||
* @since 2022-03-29 11:28
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
public enum RevenueType {
|
|
||||||
|
|
||||||
/** 工作 */
|
|
||||||
WORK,
|
|
||||||
|
|
||||||
/** 退款 */
|
|
||||||
REFUND,
|
|
||||||
|
|
||||||
/** 其他 */
|
|
||||||
OTHER
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支出类型
|
|
||||||
*
|
|
||||||
* @author 夜雨
|
|
||||||
* @since 2022-03-29 11:28
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
public enum ExpenditureType {
|
|
||||||
|
|
||||||
/** 饮食 */
|
|
||||||
FOOD,
|
|
||||||
|
|
||||||
/** 生活 */
|
|
||||||
LIFE,
|
|
||||||
|
|
||||||
/** 通信 */
|
|
||||||
COMMUNICATION,
|
|
||||||
|
|
||||||
/** 交通 */
|
|
||||||
TRAFFIC,
|
|
||||||
|
|
||||||
/** 娱乐 */
|
|
||||||
GAME,
|
|
||||||
|
|
||||||
/** 工作 */
|
|
||||||
WORK,
|
|
||||||
|
|
||||||
/** 服饰 */
|
|
||||||
CLOTHES,
|
|
||||||
|
|
||||||
/** 医疗 */
|
|
||||||
HEALTH,
|
|
||||||
|
|
||||||
/** 其他 */
|
|
||||||
OTHER
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 收入类型 */
|
|
||||||
private RevenueType revenueType;
|
|
||||||
|
|
||||||
/** 支出类型 */
|
|
||||||
private ExpenditureType expenditureType;
|
|
||||||
|
|
||||||
/** 描述 */
|
|
||||||
@NotBlank(message = "bill.description.empty")
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
/** 金额(未确保计算精度,放大了 100 倍) */
|
|
||||||
@NotNull(message = "bill.decimal.empty")
|
|
||||||
@DecimalMin(value = "0", message = "bill.decimal.limit")
|
|
||||||
private Long decimal;
|
|
||||||
|
|
||||||
/** 备注 */
|
|
||||||
private String remarks;
|
|
||||||
|
|
||||||
/** @return true 为收入账单 */
|
|
||||||
public boolean isRevenue() {
|
|
||||||
return revenueType != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return true 为支出账单 */
|
|
||||||
public boolean isExpenditure() {
|
|
||||||
return expenditureType != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.imyeyu.api.modules.bill.mapper;
|
|
||||||
|
|
||||||
import com.imyeyu.api.modules.bill.entity.Bill;
|
|
||||||
import com.imyeyu.spring.mapper.BaseMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收支帐单表
|
|
||||||
*
|
|
||||||
* @author 夜雨
|
|
||||||
* @since 2022-04-01 16:26
|
|
||||||
*/
|
|
||||||
public interface BillMapper extends BaseMapper<Bill, Long> {
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.imyeyu.api.modules.bill.service;
|
|
||||||
|
|
||||||
import com.imyeyu.api.modules.bill.entity.Bill;
|
|
||||||
import com.imyeyu.spring.service.CreatableService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收支帐单服务
|
|
||||||
*
|
|
||||||
* @author 夜雨
|
|
||||||
* @since 2022-04-01 16:24
|
|
||||||
*/
|
|
||||||
public interface BillService extends CreatableService<Bill> {
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package com.imyeyu.api.modules.bill.service.implement;
|
|
||||||
|
|
||||||
import com.imyeyu.api.modules.bill.entity.Bill;
|
|
||||||
import com.imyeyu.api.modules.bill.mapper.BillMapper;
|
|
||||||
import com.imyeyu.api.modules.bill.service.BillService;
|
|
||||||
import com.imyeyu.spring.mapper.BaseMapper;
|
|
||||||
import com.imyeyu.spring.service.AbstractEntityService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收支账单服务
|
|
||||||
*
|
|
||||||
* @author 夜雨
|
|
||||||
* @since 2022-04-01 16:25
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class BillServiceImplement extends AbstractEntityService<Bill, Long> implements BillService {
|
|
||||||
|
|
||||||
private final BillMapper mapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BaseMapper<Bill, Long> mapper() {
|
|
||||||
return mapper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.blog.entity;
|
package com.imyeyu.api.modules.blog.entity;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.imyeyu.api.modules.common.bean.CommentSupport;
|
import com.imyeyu.api.modules.common.bean.CommentSupport;
|
||||||
import com.imyeyu.spring.entity.Destroyable;
|
import com.imyeyu.spring.entity.Destroyable;
|
||||||
import com.imyeyu.spring.entity.Entity;
|
import com.imyeyu.spring.entity.Entity;
|
||||||
@@ -48,7 +48,7 @@ public class Article extends Entity implements CommentSupport, Destroyable {
|
|||||||
protected String data;
|
protected String data;
|
||||||
|
|
||||||
/** 扩展数据 */
|
/** 扩展数据 */
|
||||||
protected JsonElement extendData;
|
protected JsonNode extendData;
|
||||||
|
|
||||||
/** 阅读数量 */
|
/** 阅读数量 */
|
||||||
protected int reads;
|
protected int reads;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.common.controller;
|
package com.imyeyu.api.modules.common.controller;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.api.bean.CaptchaFrom;
|
import com.imyeyu.api.bean.CaptchaFrom;
|
||||||
import com.imyeyu.api.modules.common.bean.ImageType;
|
import com.imyeyu.api.modules.common.bean.ImageType;
|
||||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||||
@@ -95,12 +95,28 @@ public class CommonController {
|
|||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
private final ClipboardService clipboardService;
|
private final ClipboardService clipboardService;
|
||||||
|
|
||||||
private final Gson gson;
|
private final ObjectMapper jackson;
|
||||||
private final Yaml yaml;
|
private final Yaml yaml;
|
||||||
private final GridFSBucket gridFSBucket;
|
private final GridFSBucket gridFSBucket;
|
||||||
private final CaptchaManager captchaManager;
|
private final CaptchaManager captchaManager;
|
||||||
private final ResourceHandler resourceHandler;
|
private final ResourceHandler resourceHandler;
|
||||||
|
|
||||||
|
private String writeJson(Object value) {
|
||||||
|
try {
|
||||||
|
return jackson.writeValueAsString(value);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TimiException(TimiCode.ERROR, "write json error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> readJsonMap(String value) {
|
||||||
|
try {
|
||||||
|
return jackson.readValue(value, new TypeReference<>() {});
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TimiException(TimiCode.ERROR, "read json error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@AOPLog
|
@AOPLog
|
||||||
@RequestMapping("")
|
@RequestMapping("")
|
||||||
public String root() {
|
public String root() {
|
||||||
@@ -253,12 +269,12 @@ public class CommonController {
|
|||||||
case JSON -> {
|
case JSON -> {
|
||||||
if (setting.getType() == Setting.Type.YAML) {
|
if (setting.getType() == Setting.Type.YAML) {
|
||||||
Map<String, Object> obj = yaml.load(setting.getValue());
|
Map<String, Object> obj = yaml.load(setting.getValue());
|
||||||
result = gson.toJson(obj);
|
result = writeJson(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case YAML -> {
|
case YAML -> {
|
||||||
if (setting.getType() == Setting.Type.JSON) {
|
if (setting.getType() == Setting.Type.JSON) {
|
||||||
Map<String, Object> obj = gson.fromJson(setting.getValue(), new TypeToken<Map<String, Object>>() {}.getType());
|
Map<String, Object> obj = readJsonMap(setting.getValue());
|
||||||
result = yaml.dump(obj);
|
result = yaml.dump(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,12 +300,12 @@ public class CommonController {
|
|||||||
case JSON -> {
|
case JSON -> {
|
||||||
if (setting.getType() == Setting.Type.YAML) {
|
if (setting.getType() == Setting.Type.YAML) {
|
||||||
Map<String, Object> obj = new Yaml().load(setting.getValue());
|
Map<String, Object> obj = new Yaml().load(setting.getValue());
|
||||||
setting.setValue(gson.toJson(obj));
|
setting.setValue(writeJson(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case YAML -> {
|
case YAML -> {
|
||||||
if (setting.getType() == Setting.Type.JSON) {
|
if (setting.getType() == Setting.Type.JSON) {
|
||||||
Map<String, Object> obj = gson.fromJson(setting.getValue(), new TypeToken<Map<String, Object>>() {}.getType());
|
Map<String, Object> obj = readJsonMap(setting.getValue());
|
||||||
setting.setValue(new Yaml().dump(obj));
|
setting.setValue(new Yaml().dump(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,7 +499,7 @@ public class CommonController {
|
|||||||
GridFSFile file = attachmentService.readByMongoId(mongoId);
|
GridFSFile file = attachmentService.readByMongoId(mongoId);
|
||||||
@Cleanup
|
@Cleanup
|
||||||
GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(file.getObjectId());
|
GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(file.getObjectId());
|
||||||
RequestRange range = TimiSpring.requestRange(attach.getSize());
|
RequestRange range = TimiSpring.getRequestRange(attach.getSize());
|
||||||
if (range == null) {
|
if (range == null) {
|
||||||
// 完整文件
|
// 完整文件
|
||||||
resp.setContentLengthLong(attach.getSize());
|
resp.setContentLengthLong(attach.getSize());
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import com.imyeyu.java.TimiJava;
|
|||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
import com.imyeyu.spring.annotation.AOPLog;
|
import com.imyeyu.spring.annotation.AOPLog;
|
||||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||||
import com.imyeyu.spring.annotation.RequestSingleParam;
|
|
||||||
import com.imyeyu.spring.annotation.RequiredToken;
|
import com.imyeyu.spring.annotation.RequiredToken;
|
||||||
import com.imyeyu.spring.bean.CaptchaData;
|
import com.imyeyu.spring.bean.CaptchaData;
|
||||||
import com.imyeyu.spring.bean.Page;
|
import com.imyeyu.spring.bean.Page;
|
||||||
@@ -184,7 +183,7 @@ public class UserController implements TimiJava {
|
|||||||
@RequiredToken
|
@RequiredToken
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@PostMapping("/cancel")
|
@PostMapping("/cancel")
|
||||||
public void cancel(@RequestSingleParam String password) {
|
public void cancel(@RequestBody String password) {
|
||||||
service.cancel(password);
|
service.cancel(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +274,7 @@ public class UserController implements TimiJava {
|
|||||||
@RequiredToken
|
@RequiredToken
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@PostMapping("/comment/delete")
|
@PostMapping("/comment/delete")
|
||||||
public void deleteComment(@RequestSingleParam Long commentId) {
|
public void deleteComment(@RequestBody Long commentId) {
|
||||||
commentService.get(commentId);
|
commentService.get(commentId);
|
||||||
commentService.delete(commentId);
|
commentService.delete(commentId);
|
||||||
}
|
}
|
||||||
@@ -298,7 +297,7 @@ public class UserController implements TimiJava {
|
|||||||
@RequiredToken
|
@RequiredToken
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@PostMapping("/comment/reply/delete")
|
@PostMapping("/comment/reply/delete")
|
||||||
public void deleteCommentReply(@RequestSingleParam Long replyId) {
|
public void deleteCommentReply(@RequestBody Long replyId) {
|
||||||
CommentReply reply = commentReplyService.get(replyId);
|
CommentReply reply = commentReplyService.get(replyId);
|
||||||
TimiException.requiredTrue(reply.getSenderId().equals(service.getLoginUser().getId()), "user.comment.reply.delete.not_owner");
|
TimiException.requiredTrue(reply.getSenderId().equals(service.getLoginUser().getId()), "user.comment.reply.delete.not_owner");
|
||||||
commentReplyService.delete(replyId);
|
commentReplyService.delete(replyId);
|
||||||
@@ -308,7 +307,7 @@ public class UserController implements TimiJava {
|
|||||||
@RequiredToken
|
@RequiredToken
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@PostMapping("/comment/reply/ignore")
|
@PostMapping("/comment/reply/ignore")
|
||||||
public void ignoreCommentReply(@RequestSingleParam Long replyId) {
|
public void ignoreCommentReply(@RequestBody Long replyId) {
|
||||||
CommentReply reply = commentReplyService.get(replyId);
|
CommentReply reply = commentReplyService.get(replyId);
|
||||||
TimiException.requiredTrue(reply.getReceiverId().equals(service.getLoginUser().getId()), "user.comment.reply.ignore.not_owner");
|
TimiException.requiredTrue(reply.getReceiverId().equals(service.getLoginUser().getId()), "user.comment.reply.ignore.not_owner");
|
||||||
reply.setIgnoredAt(Time.now());
|
reply.setIgnoredAt(Time.now());
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.common.entity;
|
package com.imyeyu.api.modules.common.entity;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.imyeyu.api.TimiServerAPI;
|
import com.imyeyu.api.TimiServerAPI;
|
||||||
import com.imyeyu.api.bean.MultilingualHandler;
|
import com.imyeyu.api.bean.MultilingualHandler;
|
||||||
import com.imyeyu.api.modules.common.service.AttachmentService;
|
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||||
@@ -81,7 +81,7 @@ public class Attachment extends Entity implements MultilingualHandler {
|
|||||||
|
|
||||||
protected String mimeType;
|
protected String mimeType;
|
||||||
|
|
||||||
protected JsonObject metadata;
|
protected JsonNode metadata;
|
||||||
|
|
||||||
protected Long size;
|
protected Long size;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.imyeyu.api.modules.common.service;
|
package com.imyeyu.api.modules.common.service;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonObject;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||||
import com.imyeyu.api.modules.common.entity.Setting;
|
import com.imyeyu.api.modules.common.entity.Setting;
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
@@ -60,15 +60,15 @@ public interface SettingService extends UpdatableService<Setting> {
|
|||||||
*/
|
*/
|
||||||
boolean not(SettingKey key);
|
boolean not(SettingKey key);
|
||||||
|
|
||||||
JsonElement getAsJsonElement(SettingKey key);
|
JsonNode getAsJsonNode(SettingKey key);
|
||||||
|
|
||||||
JsonObject getAsJsonObject(SettingKey key);
|
ObjectNode getAsJsonObject(SettingKey key);
|
||||||
|
|
||||||
JsonArray getAsJsonArray(SettingKey key);
|
ArrayNode getAsArrayNode(SettingKey key);
|
||||||
|
|
||||||
<T> T fromJson(SettingKey key, Class<T> clazz);
|
<T> T fromJson(SettingKey key, Class<T> clazz);
|
||||||
|
|
||||||
<T> T fromJson(SettingKey key, TypeToken<T> typeToken);
|
<T> T fromJson(SettingKey key, TypeReference<T> typeReference);
|
||||||
|
|
||||||
<T> T fromYaml(SettingKey key, Class<T> clazz);
|
<T> T fromYaml(SettingKey key, Class<T> clazz);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.common.service.implement;
|
package com.imyeyu.api.modules.common.service.implement;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.JsonObject;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||||
import com.imyeyu.api.modules.common.bean.MediaAttach;
|
import com.imyeyu.api.modules.common.bean.MediaAttach;
|
||||||
import com.imyeyu.api.modules.common.bean.Metadata;
|
import com.imyeyu.api.modules.common.bean.Metadata;
|
||||||
@@ -55,7 +55,7 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
|
|||||||
|
|
||||||
private final AttachmentMapper mapper;
|
private final AttachmentMapper mapper;
|
||||||
|
|
||||||
private final Gson gson;
|
private final ObjectMapper jackson;
|
||||||
private final GridFSBucket gridFSBucket;
|
private final GridFSBucket gridFSBucket;
|
||||||
private final GridFsTemplate gridFsTemplate;
|
private final GridFsTemplate gridFsTemplate;
|
||||||
|
|
||||||
@@ -90,10 +90,10 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
|
|||||||
attachment.setIsDestroyed(false);
|
attachment.setIsDestroyed(false);
|
||||||
if (attachment.getMimeType().startsWith("image")) {
|
if (attachment.getMimeType().startsWith("image")) {
|
||||||
BufferedImage image = ImageIO.read(gridFSBucket.openDownloadStream(gridFSFile.getObjectId()));
|
BufferedImage image = ImageIO.read(gridFSBucket.openDownloadStream(gridFSFile.getObjectId()));
|
||||||
attachment.setMetadata(TimiJava.defaultIfNull(attachment.getMetadata(), new JsonObject()));
|
attachment.setMetadata(TimiJava.defaultIfNull(attachment.getMetadata(), jackson.createObjectNode()));
|
||||||
JsonObject metadata = attachment.getMetadata();
|
ObjectNode metadata = (ObjectNode) attachment.getMetadata();
|
||||||
metadata.addProperty("width", image.getWidth());
|
metadata.put("width", image.getWidth());
|
||||||
metadata.addProperty("height", image.getHeight());
|
metadata.put("height", image.getHeight());
|
||||||
}
|
}
|
||||||
mapper.insert(attachment);
|
mapper.insert(attachment);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -166,7 +166,7 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
|
|||||||
thumbAttach.setBizType(attachment.getBizType());
|
thumbAttach.setBizType(attachment.getBizType());
|
||||||
thumbAttach.setBizId(attachment.getBizId());
|
thumbAttach.setBizId(attachment.getBizId());
|
||||||
thumbAttach.setAttachTypeValue(MediaAttach.Type.THUMB);
|
thumbAttach.setAttachTypeValue(MediaAttach.Type.THUMB);
|
||||||
thumbAttach.setMetadata(gson.toJsonTree(thumbMetadata).getAsJsonObject());
|
thumbAttach.setMetadata(jackson.valueToTree(thumbMetadata));
|
||||||
thumbAttach.setInputStream(new ByteArrayInputStream(thumbStream.toByteArray()));
|
thumbAttach.setInputStream(new ByteArrayInputStream(thumbStream.toByteArray()));
|
||||||
create(thumbAttach);
|
create(thumbAttach);
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
|
|||||||
public void deleteMedia(Long thumbId) throws TimiException {
|
public void deleteMedia(Long thumbId) throws TimiException {
|
||||||
Attachment attachment = get(thumbId);
|
Attachment attachment = get(thumbId);
|
||||||
delete(attachment.getId());
|
delete(attachment.getId());
|
||||||
Metadata.ThumbImage thumbMetadata = gson.fromJson(attachment.getMetadata(), Metadata.ThumbImage.class);
|
Metadata.ThumbImage thumbMetadata = jackson.convertValue(attachment.getMetadata(), Metadata.ThumbImage.class);
|
||||||
delete(thumbMetadata.getSourceId());
|
delete(thumbMetadata.getSourceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.imyeyu.api.modules.common.service.implement;
|
package com.imyeyu.api.modules.common.service.implement;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.google.gson.JsonArray;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonObject;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.JsonParser;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||||
import com.imyeyu.api.modules.common.entity.Setting;
|
import com.imyeyu.api.modules.common.entity.Setting;
|
||||||
import com.imyeyu.api.modules.common.mapper.SettingMapper;
|
import com.imyeyu.api.modules.common.mapper.SettingMapper;
|
||||||
@@ -39,7 +39,7 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
|
|||||||
private final SettingMapper mapper;
|
private final SettingMapper mapper;
|
||||||
private final Redis<String, String> redisSetting;
|
private final Redis<String, String> redisSetting;
|
||||||
|
|
||||||
private final Gson gson;
|
private final ObjectMapper jackson;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BaseMapper<Setting, String> mapper() {
|
protected BaseMapper<Setting, String> mapper() {
|
||||||
@@ -59,7 +59,11 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
|
|||||||
|
|
||||||
String cacheValue = redisSetting.get(key.toString());
|
String cacheValue = redisSetting.get(key.toString());
|
||||||
if (TimiJava.isNotEmpty(cacheValue)) {
|
if (TimiJava.isNotEmpty(cacheValue)) {
|
||||||
return gson.fromJson(cacheValue, Setting.class);
|
try {
|
||||||
|
return jackson.readValue(cacheValue, Setting.class);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new TimiException(TimiCode.ERROR, "read setting cache error", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Setting setting = mapper.selectByKey(key);
|
Setting setting = mapper.selectByKey(key);
|
||||||
if (TimiJava.isEmpty(setting.getValue())) {
|
if (TimiJava.isEmpty(setting.getValue())) {
|
||||||
@@ -72,7 +76,11 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
|
|||||||
settingTTL = Integer.parseInt(getByKey(SettingKey.TTL_SETTING).getValue());
|
settingTTL = Integer.parseInt(getByKey(SettingKey.TTL_SETTING).getValue());
|
||||||
}
|
}
|
||||||
if (0 < settingTTL) {
|
if (0 < settingTTL) {
|
||||||
redisSetting.set(key.toString(), gson.toJson(setting), Time.M * settingTTL);
|
try {
|
||||||
|
redisSetting.set(key.toString(), jackson.writeValueAsString(setting), Time.M * settingTTL);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new TimiException(TimiCode.ERROR, "write setting cache error", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return setting;
|
return setting;
|
||||||
}
|
}
|
||||||
@@ -117,28 +125,36 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonElement getAsJsonElement(SettingKey key) {
|
public JsonNode getAsJsonNode(SettingKey key) {
|
||||||
return JsonParser.parseString(getAsString(key));
|
try {
|
||||||
|
return jackson.readTree(getAsString(key));
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new TimiException(TimiCode.ERROR, "read setting json error", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonObject getAsJsonObject(SettingKey key) {
|
public ObjectNode getAsJsonObject(SettingKey key) {
|
||||||
return getAsJsonElement(key).getAsJsonObject();
|
return (ObjectNode) getAsJsonNode(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonArray getAsJsonArray(SettingKey key) {
|
public ArrayNode getAsArrayNode(SettingKey key) {
|
||||||
return getAsJsonElement(key).getAsJsonArray();
|
return (ArrayNode) getAsJsonNode(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T fromJson(SettingKey key, Class<T> clazz) {
|
public <T> T fromJson(SettingKey key, Class<T> clazz) {
|
||||||
return gson.fromJson(getAsJsonElement(key), clazz);
|
try {
|
||||||
|
return jackson.treeToValue(getAsJsonNode(key), clazz);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new TimiException(TimiCode.ERROR, "read setting json error", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T fromJson(SettingKey key, TypeToken<T> typeToken) {
|
public <T> T fromJson(SettingKey key, TypeReference<T> typeReference) {
|
||||||
return gson.fromJson(getAsJsonElement(key), typeToken);
|
return jackson.convertValue(getAsJsonNode(key), typeReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T fromYaml(SettingKey key, Class<T> clazz) {
|
public <T> T fromYaml(SettingKey key, Class<T> clazz) {
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
package com.imyeyu.api.modules.common.service.implement;
|
package com.imyeyu.api.modules.common.service.implement;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||||
import com.imyeyu.api.modules.common.service.AttachmentService;
|
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||||
@@ -31,8 +29,6 @@ import java.util.List;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class TempFileServiceImplement implements TempFileService {
|
public class TempFileServiceImplement implements TempFileService {
|
||||||
|
|
||||||
private final Gson gson;
|
|
||||||
|
|
||||||
private final SettingService settingService;
|
private final SettingService settingService;
|
||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.common.task;
|
package com.imyeyu.api.modules.common.task;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonObject;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||||
import com.imyeyu.api.modules.common.entity.Multilingual;
|
import com.imyeyu.api.modules.common.entity.Multilingual;
|
||||||
@@ -81,6 +80,7 @@ public class MultilingualTranslateTask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ObjectMapper jackson;
|
||||||
private final SettingService settingService;
|
private final SettingService settingService;
|
||||||
private final MultilingualService service;
|
private final MultilingualService service;
|
||||||
|
|
||||||
@@ -147,18 +147,17 @@ public class MultilingualTranslateTask {
|
|||||||
.execute()
|
.execute()
|
||||||
.returnContent()
|
.returnContent()
|
||||||
.asString();
|
.asString();
|
||||||
JsonObject jo = JsonParser.parseString(response).getAsJsonObject();
|
JsonNode jo = jackson.readTree(response);
|
||||||
if (jo.has("error_code")) {
|
if (jo.has("error_code")) {
|
||||||
System.err.println(jo);
|
System.err.println(jo);
|
||||||
throw new TimiException(TimiCode.ERROR, jo.get("error_msg").getAsString());
|
throw new TimiException(TimiCode.ERROR, jo.get("error_msg").asText());
|
||||||
}
|
}
|
||||||
JsonArray ja = jo.get("trans_result").getAsJsonArray();
|
JsonNode ja = jo.get("trans_result");
|
||||||
|
|
||||||
JsonObject resultJO;
|
|
||||||
Map<String, String> result = new HashMap<>();
|
Map<String, String> result = new HashMap<>();
|
||||||
for (int i = 0; i < ja.size(); i++) {
|
for (int i = 0; i < ja.size(); i++) {
|
||||||
resultJO = ja.get(i).getAsJsonObject();
|
JsonNode resultJO = ja.get(i);
|
||||||
result.put(resultJO.get("src").getAsString(), resultJO.get("dst").getAsString());
|
result.put(resultJO.get("src").asText(), resultJO.get("dst").asText());
|
||||||
}
|
}
|
||||||
wait(200);
|
wait(200);
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.git.bean.gitea;
|
package com.imyeyu.api.modules.git.bean.gitea;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,6 +12,6 @@ public class Branch {
|
|||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@SerializedName("protected")
|
@JsonProperty("protected")
|
||||||
private boolean isProtected;
|
private boolean isProtected;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.git.bean.gitea;
|
package com.imyeyu.api.modules.git.bean.gitea;
|
||||||
|
|
||||||
import com.google.gson.annotations.JsonAdapter;
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.imyeyu.api.modules.git.util.GiteaTimestampAdapter;
|
import com.imyeyu.api.modules.git.util.GiteaTimestampAdapter;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ public class File {
|
|||||||
|
|
||||||
private String lastCommitSha;
|
private String lastCommitSha;
|
||||||
|
|
||||||
@JsonAdapter(GiteaTimestampAdapter.class)
|
@JsonSerialize(using = GiteaTimestampAdapter.Serializer.class)
|
||||||
|
@JsonDeserialize(using = GiteaTimestampAdapter.Deserializer.class)
|
||||||
private Long lastCommitterDate;
|
private Long lastCommitterDate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.git.bean.gitea;
|
package com.imyeyu.api.modules.git.bean.gitea;
|
||||||
|
|
||||||
import com.google.gson.annotations.JsonAdapter;
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.imyeyu.api.modules.git.util.GiteaTimestampAdapter;
|
import com.imyeyu.api.modules.git.util.GiteaTimestampAdapter;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -35,13 +36,16 @@ public class Repository {
|
|||||||
|
|
||||||
private Boolean archived;
|
private Boolean archived;
|
||||||
|
|
||||||
@JsonAdapter(GiteaTimestampAdapter.class)
|
@JsonSerialize(using = GiteaTimestampAdapter.Serializer.class)
|
||||||
|
@JsonDeserialize(using = GiteaTimestampAdapter.Deserializer.class)
|
||||||
private Long createdAt;
|
private Long createdAt;
|
||||||
|
|
||||||
@JsonAdapter(GiteaTimestampAdapter.class)
|
@JsonSerialize(using = GiteaTimestampAdapter.Serializer.class)
|
||||||
|
@JsonDeserialize(using = GiteaTimestampAdapter.Deserializer.class)
|
||||||
private Long updatedAt;
|
private Long updatedAt;
|
||||||
|
|
||||||
@JsonAdapter(GiteaTimestampAdapter.class)
|
@JsonSerialize(using = GiteaTimestampAdapter.Serializer.class)
|
||||||
|
@JsonDeserialize(using = GiteaTimestampAdapter.Deserializer.class)
|
||||||
private Long archivedAt;
|
private Long archivedAt;
|
||||||
|
|
||||||
private List<String> licenses;
|
private List<String> licenses;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package com.imyeyu.api.modules.git.service.implement;
|
package com.imyeyu.api.modules.git.service.implement;
|
||||||
|
|
||||||
import com.google.gson.FieldNamingPolicy;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import com.imyeyu.java.TimiJava;
|
import com.imyeyu.java.TimiJava;
|
||||||
import com.imyeyu.java.bean.timi.TimiCode;
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
@@ -56,17 +55,18 @@ import java.util.List;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RepositoryServiceImplement implements RepositoryService {
|
public class RepositoryServiceImplement implements RepositoryService {
|
||||||
|
|
||||||
private final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
|
||||||
|
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final GiteaService giteaService;
|
private final GiteaService giteaService;
|
||||||
private final SettingService settingService;
|
private final SettingService settingService;
|
||||||
|
private final ObjectMapper jackson;
|
||||||
|
|
||||||
private User owner;
|
private User owner;
|
||||||
|
private ObjectMapper giteaJackson;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
private void postConstruct() {
|
private void postConstruct() {
|
||||||
owner = giteaService.getOwner();
|
owner = giteaService.getOwner();
|
||||||
|
giteaJackson = jackson.copy().setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,8 +80,7 @@ public class RepositoryServiceImplement implements RepositoryService {
|
|||||||
put("limit", page.getLimit());
|
put("limit", page.getLimit());
|
||||||
}})).execute().returnResponse();
|
}})).execute().returnResponse();
|
||||||
String respText = EntityUtils.toString(resp.getEntity());
|
String respText = EntityUtils.toString(resp.getEntity());
|
||||||
GiteaResponse<List<Repository>> respObj = gson.fromJson(respText, new TypeToken<GiteaResponse<List<Repository>>>() {
|
GiteaResponse<List<Repository>> respObj = giteaJackson.readValue(respText, new TypeReference<>() {});
|
||||||
}.getType());
|
|
||||||
|
|
||||||
PageResult<Repository> result = new PageResult<>();
|
PageResult<Repository> result = new PageResult<>();
|
||||||
result.setTotal(Long.parseLong(resp.getHeader("X-Total-Count").getValue()));
|
result.setTotal(Long.parseLong(resp.getHeader("X-Total-Count").getValue()));
|
||||||
@@ -100,7 +99,7 @@ public class RepositoryServiceImplement implements RepositoryService {
|
|||||||
put("owner", owner.getName());
|
put("owner", owner.getName());
|
||||||
put("repoName", repoName);
|
put("repoName", repoName);
|
||||||
}})).execute().returnContent().asString();
|
}})).execute().returnContent().asString();
|
||||||
return gson.fromJson(respText, Repository.class);
|
return giteaJackson.readValue(respText, Repository.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("get repository error", e);
|
log.error("get repository error", e);
|
||||||
throw new TimiException(TimiCode.ERROR, "get repository error", e);
|
throw new TimiException(TimiCode.ERROR, "get repository error", e);
|
||||||
@@ -110,11 +109,11 @@ public class RepositoryServiceImplement implements RepositoryService {
|
|||||||
@Override
|
@Override
|
||||||
public List<Branch> listBranches(String repoName) {
|
public List<Branch> listBranches(String repoName) {
|
||||||
try {
|
try {
|
||||||
String respText = Request.get(API.REPO_BRANCHES_LIST.buildURL(new HashMap<>() {{
|
String respText = Request.get(API.REPO_BRANCHES_LIST.buildURL(new HashMap<>() {{
|
||||||
put("owner", owner.getName());
|
put("owner", owner.getName());
|
||||||
put("repoName", repoName);
|
put("repoName", repoName);
|
||||||
}})).execute().returnContent().asString();
|
}})).execute().returnContent().asString();
|
||||||
return gson.fromJson(respText, new TypeToken<List<Branch>>() {}.getType());
|
return giteaJackson.readValue(respText, new TypeReference<>() {});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("list repository branches error", e);
|
log.error("list repository branches error", e);
|
||||||
throw new TimiException(TimiCode.ERROR, "list repository branches error", e);
|
throw new TimiException(TimiCode.ERROR, "list repository branches error", e);
|
||||||
@@ -124,14 +123,14 @@ public class RepositoryServiceImplement implements RepositoryService {
|
|||||||
@Override
|
@Override
|
||||||
public List<File> listFile(String repoName, String branch, String path) {
|
public List<File> listFile(String repoName, String branch, String path) {
|
||||||
try {
|
try {
|
||||||
String respText = Request.get(API.REPO_FILE_LIST.buildURL(new HashMap<>() {{
|
String respText = Request.get(API.REPO_FILE_LIST.buildURL(new HashMap<>() {{
|
||||||
put("owner", owner.getName());
|
put("owner", owner.getName());
|
||||||
put("repoName", repoName);
|
put("repoName", repoName);
|
||||||
put("path", path);
|
put("path", path);
|
||||||
}}, new HashMap<>() {{
|
}}, new HashMap<>() {{
|
||||||
put("ref", branch);
|
put("ref", branch);
|
||||||
}})).execute().returnContent().asString();
|
}})).execute().returnContent().asString();
|
||||||
List<File> list = gson.fromJson(respText, new TypeToken<List<File>>() {}.getType());
|
List<File> list = giteaJackson.readValue(respText, new TypeReference<>() {});
|
||||||
// 排序
|
// 排序
|
||||||
list.sort((f1, f2) -> {
|
list.sort((f1, f2) -> {
|
||||||
if (f1.getType() == File.Type.dir && f2.getType() == File.Type.file) {
|
if (f1.getType() == File.Type.dir && f2.getType() == File.Type.file) {
|
||||||
|
|||||||
@@ -1,28 +1,54 @@
|
|||||||
package com.imyeyu.api.modules.git.util;
|
package com.imyeyu.api.modules.git.util;
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.fasterxml.jackson.core.JacksonException;
|
||||||
import com.google.gson.JsonDeserializer;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
import com.google.gson.JsonSerializationContext;
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
import com.google.gson.JsonSerializer;
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author 夜雨
|
* @author 夜雨
|
||||||
* @since 2025-06-26 11:40
|
* @since 2025-06-26 11:40
|
||||||
*/
|
*/
|
||||||
public class GiteaTimestampAdapter implements JsonSerializer<Long>, JsonDeserializer<Long> {
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public final class GiteaTimestampAdapter {
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public Long deserialize(JsonElement json, Type type, JsonDeserializationContext context) {
|
*
|
||||||
return Instant.parse(json.getAsString()).toEpochMilli();
|
*
|
||||||
|
* @author 夜雨
|
||||||
|
* @since 2026-04-07 22:16
|
||||||
|
*/
|
||||||
|
public static class Serializer extends JsonSerializer<Long> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||||
|
if (value == null) {
|
||||||
|
gen.writeNull();
|
||||||
|
} else {
|
||||||
|
gen.writeNumber(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public JsonElement serialize(Long src, Type type, JsonSerializationContext context) {
|
*
|
||||||
return new JsonPrimitive(src);
|
*
|
||||||
|
* @author 夜雨
|
||||||
|
* @since 2026-04-07 22:19
|
||||||
|
*/
|
||||||
|
public static class Deserializer extends JsonDeserializer<Long> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
|
||||||
|
return Instant.parse(p.getText()).toEpochMilli();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package com.imyeyu.api.modules.gitea.bean;
|
package com.imyeyu.api.modules.gitea.bean;
|
||||||
|
|
||||||
import com.google.gson.annotations.JsonAdapter;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.imyeyu.api.modules.gitea.util.GiteaUTCTimestampAdapter;
|
import com.imyeyu.api.modules.gitea.util.GiteaUTCTimestampAdapter;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -50,14 +51,15 @@ public class ActionLogDTO {
|
|||||||
@Data
|
@Data
|
||||||
public static class Commit {
|
public static class Commit {
|
||||||
|
|
||||||
@SerializedName("Sha1")
|
@JsonProperty("Sha1")
|
||||||
private String sha;
|
private String sha;
|
||||||
|
|
||||||
@SerializedName("Message")
|
@JsonProperty("Message")
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
@JsonAdapter(GiteaUTCTimestampAdapter.class)
|
@JsonProperty("Timestamp")
|
||||||
@SerializedName("Timestamp")
|
@JsonSerialize(using = GiteaUTCTimestampAdapter.Serializer.class)
|
||||||
|
@JsonDeserialize(using = GiteaUTCTimestampAdapter.Deserializer.class)
|
||||||
private Long timestamp;
|
private Long timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package com.imyeyu.api.modules.gitea.util;
|
package com.imyeyu.api.modules.gitea.util;
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.fasterxml.jackson.core.JacksonException;
|
||||||
import com.google.gson.JsonDeserializer;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
import com.google.gson.JsonSerializationContext;
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
import com.google.gson.JsonSerializer;
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
@@ -18,15 +19,21 @@ import java.time.ZoneOffset;
|
|||||||
* @author 夜雨
|
* @author 夜雨
|
||||||
* @since 2025-06-27 16:18
|
* @since 2025-06-27 16:18
|
||||||
*/
|
*/
|
||||||
public class GiteaUTCTimestampAdapter implements JsonDeserializer<Long>, JsonSerializer<Long> {
|
public class GiteaUTCTimestampAdapter {
|
||||||
|
|
||||||
@Override
|
public static class Deserializer extends JsonDeserializer<Long> {
|
||||||
public Long deserialize(JsonElement json, Type type, JsonDeserializationContext context) {
|
|
||||||
return OffsetDateTime.parse(json.getAsString()).toInstant().toEpochMilli();
|
@Override
|
||||||
|
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
|
||||||
|
return OffsetDateTime.parse(p.getText()).toInstant().toEpochMilli();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static class Serializer extends JsonSerializer<Long> {
|
||||||
public JsonElement serialize(Long timestamp, Type type, JsonSerializationContext context) {
|
|
||||||
return new JsonPrimitive(OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC).toString());
|
@Override
|
||||||
|
public void serialize(Long timestamp, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||||
|
gen.writeString(OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC).toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package com.imyeyu.api.modules.gitea.vo;
|
package com.imyeyu.api.modules.gitea.vo;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.google.gson.JsonObject;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonParser;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import com.imyeyu.java.TimiJava;
|
import com.imyeyu.java.TimiJava;
|
||||||
import com.imyeyu.api.TimiServerAPI;
|
import com.imyeyu.api.TimiServerAPI;
|
||||||
import com.imyeyu.api.modules.common.service.UserService;
|
import com.imyeyu.api.modules.common.service.UserService;
|
||||||
@@ -34,7 +33,7 @@ public class ActionLogView {
|
|||||||
private UserView operator;
|
private UserView operator;
|
||||||
|
|
||||||
public static ActionLogView fromDTO(ActionLogDTO dto) {
|
public static ActionLogView fromDTO(ActionLogDTO dto) {
|
||||||
Gson gson = TimiServerAPI.applicationContext.getBean(Gson.class);
|
ObjectMapper jackson = TimiServerAPI.applicationContext.getBean(ObjectMapper.class);
|
||||||
UserService userService = TimiServerAPI.applicationContext.getBean(UserService.class);
|
UserService userService = TimiServerAPI.applicationContext.getBean(UserService.class);
|
||||||
|
|
||||||
ActionLogView view = new ActionLogView();
|
ActionLogView view = new ActionLogView();
|
||||||
@@ -45,15 +44,19 @@ public class ActionLogView {
|
|||||||
view.setOperator(userService.view((long) dto.getOperatorId()).doFilter());
|
view.setOperator(userService.view((long) dto.getOperatorId()).doFilter());
|
||||||
{
|
{
|
||||||
if (TimiJava.isNotEmpty(dto.getContent())) {
|
if (TimiJava.isNotEmpty(dto.getContent())) {
|
||||||
JsonObject content = JsonParser.parseString(dto.getContent()).getAsJsonObject();
|
try {
|
||||||
List<ActionLogDTO.Commit> commitList = gson.fromJson(content.get("Commits"), new TypeToken<List<ActionLogDTO.Commit>>() {}.getType());
|
JsonNode content = jackson.readTree(dto.getContent());
|
||||||
view.setCommitList(new ArrayList<>());
|
List<ActionLogDTO.Commit> commitList = jackson.convertValue(content.get("Commits"), new TypeReference<>() {});
|
||||||
for (ActionLogDTO.Commit dtoCommit : commitList) {
|
view.setCommitList(new ArrayList<>());
|
||||||
Commit commit = new Commit();
|
for (ActionLogDTO.Commit dtoCommit : commitList) {
|
||||||
commit.setSha(dtoCommit.getSha());
|
Commit commit = new Commit();
|
||||||
commit.setMessage(dtoCommit.getMessage().trim());
|
commit.setSha(dtoCommit.getSha());
|
||||||
commit.setCommittedAt(dtoCommit.getTimestamp());
|
commit.setMessage(dtoCommit.getMessage().trim());
|
||||||
view.getCommitList().add(commit);
|
commit.setCommittedAt(dtoCommit.getTimestamp());
|
||||||
|
view.getCommitList().add(commit);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException("read gitea action log content error", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,4 +78,4 @@ public class ActionLogView {
|
|||||||
|
|
||||||
private Long committedAt;
|
private Long committedAt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.journal.controller;
|
package com.imyeyu.api.modules.journal.controller;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.api.bean.PreviewPage;
|
import com.imyeyu.api.bean.PreviewPage;
|
||||||
import com.imyeyu.api.bean.wechat.InitCodeResponse;
|
import com.imyeyu.api.bean.wechat.InitCodeResponse;
|
||||||
import com.imyeyu.api.modules.common.bean.MediaAttach;
|
import com.imyeyu.api.modules.common.bean.MediaAttach;
|
||||||
@@ -18,10 +19,8 @@ import com.imyeyu.api.modules.journal.vo.journal.UpdateRequest;
|
|||||||
import com.imyeyu.java.bean.timi.TimiCode;
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
import com.imyeyu.network.ArgMap;
|
import com.imyeyu.network.ArgMap;
|
||||||
import com.imyeyu.network.GsonRequest;
|
|
||||||
import com.imyeyu.spring.annotation.AOPLog;
|
import com.imyeyu.spring.annotation.AOPLog;
|
||||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||||
import com.imyeyu.spring.annotation.RequestSingleParam;
|
|
||||||
import com.imyeyu.spring.bean.Page;
|
import com.imyeyu.spring.bean.Page;
|
||||||
import com.imyeyu.spring.bean.PageResult;
|
import com.imyeyu.spring.bean.PageResult;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
@@ -53,6 +52,7 @@ public class JournalController {
|
|||||||
private final JournalService service;
|
private final JournalService service;
|
||||||
private final SettingService settingService;
|
private final SettingService settingService;
|
||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
|
private final ObjectMapper jackson;
|
||||||
|
|
||||||
private final JournalAPIInterceptor apiInterceptor;
|
private final JournalAPIInterceptor apiInterceptor;
|
||||||
|
|
||||||
@@ -65,14 +65,18 @@ public class JournalController {
|
|||||||
@AOPLog
|
@AOPLog
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@PostMapping("/openid")
|
@PostMapping("/openid")
|
||||||
public String initOpenId(@RequestSingleParam String code) {
|
public String initOpenId(@RequestBody String code) {
|
||||||
try {
|
try {
|
||||||
ArgMap<String, String> args = new ArgMap<>();
|
ArgMap<String, String> args = new ArgMap<>();
|
||||||
args.put("appid", settingService.getAsString(SettingKey.JOURNAL_APP_ID));
|
args.put("appid", settingService.getAsString(SettingKey.JOURNAL_APP_ID));
|
||||||
args.put("secret", settingService.getAsString(SettingKey.JOURNAL_APP_SECRET));
|
args.put("secret", settingService.getAsString(SettingKey.JOURNAL_APP_SECRET));
|
||||||
args.put("js_code", code);
|
args.put("js_code", code);
|
||||||
args.put("grant_type", "authorization_code");
|
args.put("grant_type", "authorization_code");
|
||||||
InitCodeResponse resp = GsonRequest.get(args.toURL("https://api.weixin.qq.com/sns/jscode2session")).resultAs(InitCodeResponse.class);
|
String response = org.apache.hc.client5.http.fluent.Request.get(args.toURL("https://api.weixin.qq.com/sns/jscode2session"))
|
||||||
|
.execute()
|
||||||
|
.returnContent()
|
||||||
|
.asString();
|
||||||
|
InitCodeResponse resp = jackson.readValue(response, InitCodeResponse.class);
|
||||||
return resp.getOpenid();
|
return resp.getOpenid();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("init WeChat openId error", e);
|
log.error("init WeChat openId error", e);
|
||||||
@@ -139,7 +143,7 @@ public class JournalController {
|
|||||||
@AOPLog
|
@AOPLog
|
||||||
@RequiredUploadPermission
|
@RequiredUploadPermission
|
||||||
@PostMapping("/delete")
|
@PostMapping("/delete")
|
||||||
public void delete(@RequestSingleParam Long id) {
|
public void delete(@RequestBody Long id) {
|
||||||
service.delete(id);
|
service.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import com.imyeyu.api.modules.common.bean.SettingKey;
|
|||||||
import com.imyeyu.api.modules.common.entity.Setting;
|
import com.imyeyu.api.modules.common.entity.Setting;
|
||||||
import com.imyeyu.api.modules.common.service.SettingService;
|
import com.imyeyu.api.modules.common.service.SettingService;
|
||||||
import com.imyeyu.api.modules.journal.bean.RequiredUploadPermission;
|
import com.imyeyu.api.modules.journal.bean.RequiredUploadPermission;
|
||||||
import com.imyeyu.spring.annotation.RequestSingleParam;
|
import com.imyeyu.spring.annotation.RequestBodyValue;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -31,7 +31,7 @@ public class ToolController {
|
|||||||
|
|
||||||
@RequiredUploadPermission
|
@RequiredUploadPermission
|
||||||
@PostMapping("/memo/update")
|
@PostMapping("/memo/update")
|
||||||
public void updateMemo(@RequestSingleParam String data) {
|
public void updateMemo(@RequestBodyValue String data) {
|
||||||
Setting setting = settingService.getByKey(SettingKey.JOURNAL_MEMO);
|
Setting setting = settingService.getByKey(SettingKey.JOURNAL_MEMO);
|
||||||
setting.setValue(data);
|
setting.setValue(data);
|
||||||
settingService.update(setting);
|
settingService.update(setting);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.imyeyu.api.modules.journal.entity.Travel;
|
|||||||
import com.imyeyu.api.modules.journal.service.TravelService;
|
import com.imyeyu.api.modules.journal.service.TravelService;
|
||||||
import com.imyeyu.spring.annotation.AOPLog;
|
import com.imyeyu.spring.annotation.AOPLog;
|
||||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||||
import com.imyeyu.spring.annotation.RequestSingleParam;
|
|
||||||
import com.imyeyu.spring.bean.Page;
|
import com.imyeyu.spring.bean.Page;
|
||||||
import com.imyeyu.spring.bean.PageResult;
|
import com.imyeyu.spring.bean.PageResult;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
@@ -67,7 +66,7 @@ public class TravelController {
|
|||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@RequiredUploadPermission
|
@RequiredUploadPermission
|
||||||
@PostMapping("/delete")
|
@PostMapping("/delete")
|
||||||
public void delete(@RequestSingleParam Long id) {
|
public void delete(@RequestBody Long id) {
|
||||||
service.delete(id);
|
service.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import com.imyeyu.api.modules.journal.entity.TravelLocation;
|
|||||||
import com.imyeyu.api.modules.journal.service.TravelLocationService;
|
import com.imyeyu.api.modules.journal.service.TravelLocationService;
|
||||||
import com.imyeyu.spring.annotation.AOPLog;
|
import com.imyeyu.spring.annotation.AOPLog;
|
||||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||||
import com.imyeyu.spring.annotation.RequestSingleParam;
|
|
||||||
import com.imyeyu.spring.bean.Page;
|
import com.imyeyu.spring.bean.Page;
|
||||||
import com.imyeyu.spring.bean.PageResult;
|
import com.imyeyu.spring.bean.PageResult;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
@@ -74,7 +73,7 @@ public class TravelLocationController {
|
|||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@RequiredUploadPermission
|
@RequiredUploadPermission
|
||||||
@PostMapping("/delete")
|
@PostMapping("/delete")
|
||||||
public void delete(@RequestSingleParam Long id) {
|
public void delete(@RequestBody Long id) {
|
||||||
service.delete(id);
|
service.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.journal.service.implement;
|
package com.imyeyu.api.modules.journal.service.implement;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||||
import com.imyeyu.api.modules.common.bean.MediaAttach;
|
import com.imyeyu.api.modules.common.bean.MediaAttach;
|
||||||
import com.imyeyu.api.modules.common.bean.Metadata;
|
import com.imyeyu.api.modules.common.bean.Metadata;
|
||||||
@@ -40,7 +40,7 @@ import java.util.stream.Collectors;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class JournalServiceImplement extends AbstractEntityService<Journal, Long> implements JournalService {
|
public class JournalServiceImplement extends AbstractEntityService<Journal, Long> implements JournalService {
|
||||||
|
|
||||||
private final Gson gson;
|
private final ObjectMapper jackson;
|
||||||
|
|
||||||
private final SettingService settingService;
|
private final SettingService settingService;
|
||||||
private final TempFileService tempFileService;
|
private final TempFileService tempFileService;
|
||||||
@@ -192,7 +192,7 @@ public class JournalServiceImplement extends AbstractEntityService<Journal, Long
|
|||||||
thumbAttach.setBizId(journal.getId());
|
thumbAttach.setBizId(journal.getId());
|
||||||
attachmentService.update(thumbAttach);
|
attachmentService.update(thumbAttach);
|
||||||
|
|
||||||
Metadata.ThumbImage thumbMetadata = gson.fromJson(thumbAttach.getMetadata(), Metadata.ThumbImage.class);
|
Metadata.ThumbImage thumbMetadata = jackson.convertValue(thumbAttach.getMetadata(), Metadata.ThumbImage.class);
|
||||||
Attachment sourceAttach = attachmentService.get(thumbMetadata.getSourceId());
|
Attachment sourceAttach = attachmentService.get(thumbMetadata.getSourceId());
|
||||||
sourceAttach.setBizType(Attachment.BizType.JOURNAL);
|
sourceAttach.setBizType(Attachment.BizType.JOURNAL);
|
||||||
sourceAttach.setBizId(journal.getId());
|
sourceAttach.setBizId(journal.getId());
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class JournalAPIInterceptor implements HandlerInterceptor {
|
|||||||
|
|
||||||
public boolean canAccess() {
|
public boolean canAccess() {
|
||||||
String reqKey = TimiJava.defaultIfEmpty(TimiSpring.getHeader("Key"), TimiSpring.getRequestArg("key"));
|
String reqKey = TimiJava.defaultIfEmpty(TimiSpring.getHeader("Key"), TimiSpring.getRequestArg("key"));
|
||||||
return keys.contains(reqKey);
|
return TimiJava.isNotEmpty(reqKey) && keys.contains(reqKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canUploadKey() {
|
public boolean canUploadKey() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.lyric.service.implement;
|
package com.imyeyu.api.modules.lyric.service.implement;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonParser;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.java.bean.timi.TimiCode;
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
import com.imyeyu.api.modules.lyric.entity.Lyric;
|
import com.imyeyu.api.modules.lyric.entity.Lyric;
|
||||||
@@ -50,6 +50,7 @@ public class LyricServiceImplement implements LyricService {
|
|||||||
|
|
||||||
private final LyricMapper mapper;
|
private final LyricMapper mapper;
|
||||||
private final Map<Long, String> allLyric;
|
private final Map<Long, String> allLyric;
|
||||||
|
private final ObjectMapper jackson;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Lyric get(Long id) {
|
public Lyric get(Long id) {
|
||||||
@@ -113,12 +114,12 @@ public class LyricServiceImplement implements LyricService {
|
|||||||
Request request = Request.get(API_GET_SONG + Encoder.urlArgs(args));
|
Request request = Request.get(API_GET_SONG + Encoder.urlArgs(args));
|
||||||
HEADER.forEach(request::addHeader);
|
HEADER.forEach(request::addHeader);
|
||||||
response = request.execute().returnContent().asString();
|
response = request.execute().returnContent().asString();
|
||||||
JsonObject data = JsonParser.parseString(response).getAsJsonObject().get("data").getAsJsonObject().get("info").getAsJsonArray().get(0).getAsJsonObject();
|
JsonNode data = jackson.readTree(response).path("data").path("info").get(0);
|
||||||
|
|
||||||
args.clear();
|
args.clear();
|
||||||
args.put("cmd", "100");
|
args.put("cmd", "100");
|
||||||
args.put("keyword", data.get("songname").getAsString());
|
args.put("keyword", data.path("songname").asText());
|
||||||
args.put("hash", data.get("hash").getAsString());
|
args.put("hash", data.path("hash").asText());
|
||||||
args.put("timelength", tl);
|
args.put("timelength", tl);
|
||||||
args.put("d", String.valueOf(Math.random()));
|
args.put("d", String.valueOf(Math.random()));
|
||||||
request = Request.get(API_GET_LRC + Encoder.urlArgs(args));
|
request = Request.get(API_GET_LRC + Encoder.urlArgs(args));
|
||||||
@@ -128,8 +129,8 @@ public class LyricServiceImplement implements LyricService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Lyric lyric = new Lyric();
|
Lyric lyric = new Lyric();
|
||||||
lyric.setSong(data.get("songname").getAsString());
|
lyric.setSong(data.path("songname").asText());
|
||||||
lyric.setSinger(data.get("singername").getAsString());
|
lyric.setSinger(data.path("singername").asText());
|
||||||
lyric.setData(response);
|
lyric.setData(response);
|
||||||
return lyric;
|
return lyric;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import com.imyeyu.api.modules.minecraft.vo.TokenRequest;
|
|||||||
import com.imyeyu.api.modules.minecraft.vo.TokenResponse;
|
import com.imyeyu.api.modules.minecraft.vo.TokenResponse;
|
||||||
import com.imyeyu.spring.annotation.AOPLog;
|
import com.imyeyu.spring.annotation.AOPLog;
|
||||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||||
import com.imyeyu.spring.annotation.RequestSingleParam;
|
|
||||||
import com.imyeyu.spring.annotation.RequiredToken;
|
import com.imyeyu.spring.annotation.RequiredToken;
|
||||||
import com.imyeyu.spring.util.Redis;
|
import com.imyeyu.spring.util.Redis;
|
||||||
import com.imyeyu.spring.util.RedisSerializers;
|
import com.imyeyu.spring.util.RedisSerializers;
|
||||||
@@ -73,7 +72,7 @@ public class PlayerController {
|
|||||||
@RequiredToken
|
@RequiredToken
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@PostMapping("/bind")
|
@PostMapping("/bind")
|
||||||
public void bind(@RequestSingleParam String name) {
|
public void bind(@RequestBody String name) {
|
||||||
MinecraftPlayer player = new MinecraftPlayer();
|
MinecraftPlayer player = new MinecraftPlayer();
|
||||||
player.setName(name);
|
player.setName(name);
|
||||||
player.setUserId(userService.getLoginUser().getId());
|
player.setUserId(userService.getLoginUser().getId());
|
||||||
@@ -84,7 +83,7 @@ public class PlayerController {
|
|||||||
@RequiredToken
|
@RequiredToken
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@PostMapping("/unbind")
|
@PostMapping("/unbind")
|
||||||
public void unbind(@RequestSingleParam Long id) {
|
public void unbind(@RequestBody Long id) {
|
||||||
service.listByUserId(userService.getLoginUser().getId())
|
service.listByUserId(userService.getLoginUser().getId())
|
||||||
.stream()
|
.stream()
|
||||||
.filter(player -> player.getId().equals(id))
|
.filter(player -> player.getId().equals(id))
|
||||||
@@ -113,7 +112,7 @@ public class PlayerController {
|
|||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@EnableSetting(value = SettingKey.FMC_PLAYER_LOGIN_ENABLE, message = "登录服务未启用")
|
@EnableSetting(value = SettingKey.FMC_PLAYER_LOGIN_ENABLE, message = "登录服务未启用")
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public TokenResponse login(@RequestSingleParam Long playerId, @RequestHeader("Token") String token) {
|
public TokenResponse login(@RequestBody Long playerId, @RequestHeader("Token") String token) {
|
||||||
return service.login(playerId, token);
|
return service.login(playerId, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.mirror;
|
package com.imyeyu.api.modules.mirror;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||||
import com.imyeyu.api.modules.common.service.AttachmentService;
|
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||||
import com.imyeyu.api.modules.mirror.bean.AttachType;
|
import com.imyeyu.api.modules.mirror.bean.AttachType;
|
||||||
@@ -47,7 +47,7 @@ public class FabricAPIMirror extends AttachmentMirror {
|
|||||||
/** 版本匹配正则 */
|
/** 版本匹配正则 */
|
||||||
private static final Pattern versionRegex = Pattern.compile("^(\\d+\\.){1,2}(\\*|\\d+)$");
|
private static final Pattern versionRegex = Pattern.compile("^(\\d+\\.){1,2}(\\*|\\d+)$");
|
||||||
|
|
||||||
private final Gson gson;
|
private final ObjectMapper jackson;
|
||||||
|
|
||||||
private final MirrorService service;
|
private final MirrorService service;
|
||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
@@ -100,7 +100,7 @@ public class FabricAPIMirror extends AttachmentMirror {
|
|||||||
result.add(item);
|
result.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mirror.setData(gson.toJsonTree(result));
|
mirror.setData(jackson.valueToTree(result));
|
||||||
service.update(mirror);
|
service.update(mirror);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
package com.imyeyu.api.modules.mirror;
|
package com.imyeyu.api.modules.mirror;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonArray;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.imyeyu.java.bean.timi.TimiCode;
|
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
|
||||||
import com.imyeyu.java.ref.Ref;
|
|
||||||
import com.imyeyu.api.modules.mirror.data.OpenJDK;
|
import com.imyeyu.api.modules.mirror.data.OpenJDK;
|
||||||
import com.imyeyu.api.modules.mirror.entity.Mirror;
|
import com.imyeyu.api.modules.mirror.entity.Mirror;
|
||||||
import com.imyeyu.api.modules.mirror.service.MirrorService;
|
import com.imyeyu.api.modules.mirror.service.MirrorService;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
|
import com.imyeyu.java.ref.Ref;
|
||||||
import com.imyeyu.utils.OS;
|
import com.imyeyu.utils.OS;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -27,9 +24,9 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Github JDK 镜像,仅同步下载链接等信息,不储存文件
|
* Github JDK 闀滃儚锛屼粎鍚屾涓嬭浇閾炬帴绛変俊鎭紝涓嶅偍瀛樻枃浠?
|
||||||
*
|
*
|
||||||
* @author 夜雨
|
* @author 澶滈洦
|
||||||
* @version 2024-06-10 10:51
|
* @version 2024-06-10 10:51
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -37,10 +34,10 @@ import java.util.Map;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class OpenJDKGithubMirror extends AbstractMirror {
|
public class OpenJDKGithubMirror extends AbstractMirror {
|
||||||
|
|
||||||
/** 版本发布列表接口,插值 {@link #REPOS_MAP} 的值 */
|
/** 鐗堟湰鍙戝竷鍒楄〃鎺ュ彛锛屾彃鍊?{@link #REPOS_MAP} 鐨勫€?*/
|
||||||
private static final String API_RELEASE = "https://api.github.com/repos/adoptium/%s/releases?page=1";
|
private static final String API_RELEASE = "https://api.github.com/repos/adoptium/%s/releases?page=1";
|
||||||
|
|
||||||
/** 版本仓库映射,key 为版本,value 为对应仓库,只读 */
|
/** 鐗堟湰浠撳簱鏄犲皠锛宬ey 涓虹増鏈紝value 涓哄搴斾粨搴擄紝鍙 */
|
||||||
private static final Map<String, String> REPOS_MAP = Collections.unmodifiableMap(new HashMap<>() {{
|
private static final Map<String, String> REPOS_MAP = Collections.unmodifiableMap(new HashMap<>() {{
|
||||||
put("8", "temurin8-binaries");
|
put("8", "temurin8-binaries");
|
||||||
put("11", "temurin11-binaries");
|
put("11", "temurin11-binaries");
|
||||||
@@ -48,31 +45,30 @@ public class OpenJDKGithubMirror extends AbstractMirror {
|
|||||||
put("21", "temurin21-binaries");
|
put("21", "temurin21-binaries");
|
||||||
}});
|
}});
|
||||||
|
|
||||||
private final Gson gson;
|
private final ObjectMapper jackson;
|
||||||
private final MirrorService service;
|
private final MirrorService service;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void sync(Mirror mirror) throws Exception {
|
protected void sync(Mirror mirror) throws Exception {
|
||||||
mirror.setData(gson.toJsonTree(fetch()));
|
mirror.setData(jackson.valueToTree(fetch()));
|
||||||
service.update(mirror);
|
service.update(mirror);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 {@link OpenJDK} 列表,{@link OpenJDKMirror} 也会使用此接口
|
* 鑾峰彇 {@link OpenJDK} 鍒楄〃锛寋@link OpenJDKMirror} 涔熶細浣跨敤姝ゆ帴鍙?
|
||||||
*
|
*
|
||||||
* @return jdk 列表
|
* @return jdk 鍒楄〃
|
||||||
* @throws Exception 获取异常
|
* @throws Exception 鑾峰彇寮傚父
|
||||||
*/
|
*/
|
||||||
final List<OpenJDK> fetch() throws Exception {
|
final List<OpenJDK> fetch() throws Exception {
|
||||||
List<OpenJDK> result = new ArrayList<>();
|
List<OpenJDK> result = new ArrayList<>();
|
||||||
for (Map.Entry<String, String> repo : REPOS_MAP.entrySet()) {
|
for (Map.Entry<String, String> repo : REPOS_MAP.entrySet()) {
|
||||||
String respText = Request.get(API_RELEASE.formatted(repo.getValue())).connectTimeout(Timeout.ofSeconds(60)).execute().returnContent().asString();
|
String respText = Request.get(API_RELEASE.formatted(repo.getValue())).connectTimeout(Timeout.ofSeconds(60)).execute().returnContent().asString();
|
||||||
JsonArray root = JsonParser.parseString(respText).getAsJsonArray();
|
JsonNode root = jackson.readTree(respText);
|
||||||
JsonObject itemRel = null;
|
JsonNode itemRel = null;
|
||||||
for (JsonElement el : root) {
|
for (JsonNode el : root) {
|
||||||
itemRel = el.getAsJsonObject();
|
itemRel = el;
|
||||||
if (itemRel.get("prerelease").getAsBoolean() || itemRel.get("draft").getAsBoolean()) {
|
if (itemRel.path("prerelease").asBoolean() || itemRel.path("draft").asBoolean()) {
|
||||||
// 忽略草稿或预发布版本
|
|
||||||
itemRel = null;
|
itemRel = null;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -81,12 +77,8 @@ public class OpenJDKGithubMirror extends AbstractMirror {
|
|||||||
if (itemRel == null) {
|
if (itemRel == null) {
|
||||||
throw new TimiException(TimiCode.ERROR, "not found release item for " + repo.getValue());
|
throw new TimiException(TimiCode.ERROR, "not found release item for " + repo.getValue());
|
||||||
}
|
}
|
||||||
JsonArray assets = itemRel.get("assets").getAsJsonArray();
|
for (JsonNode itemAsset : itemRel.path("assets")) {
|
||||||
for (JsonElement asset : assets) {
|
String name = itemAsset.path("name").asText();
|
||||||
JsonObject itemAsset = asset.getAsJsonObject();
|
|
||||||
// OpenJDK21U-jdk_x64_windows_hotspot_21.0.3_9.zip
|
|
||||||
String name = itemAsset.get("name").getAsString();
|
|
||||||
|
|
||||||
if (!name.contains("-") || !name.contains("_")) {
|
if (!name.contains("-") || !name.contains("_")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -102,14 +94,13 @@ public class OpenJDKGithubMirror extends AbstractMirror {
|
|||||||
}
|
}
|
||||||
OS.Platform platform = Ref.toType(OS.Platform.class, split[2].toUpperCase());
|
OS.Platform platform = Ref.toType(OS.Platform.class, split[2].toUpperCase());
|
||||||
OpenJDK.Type type = Ref.toType(OpenJDK.Type.class, split[0].toUpperCase());
|
OpenJDK.Type type = Ref.toType(OpenJDK.Type.class, split[0].toUpperCase());
|
||||||
|
|
||||||
if (platform != null && type != null) {
|
if (platform != null && type != null) {
|
||||||
OpenJDK jdk = new OpenJDK();
|
OpenJDK jdk = new OpenJDK();
|
||||||
jdk.setPlatform(platform);
|
jdk.setPlatform(platform);
|
||||||
jdk.setType(type);
|
jdk.setType(type);
|
||||||
jdk.setName(name);
|
jdk.setName(name);
|
||||||
jdk.setVersion(repo.getKey());
|
jdk.setVersion(repo.getKey());
|
||||||
jdk.setData(URLDecoder.decode(itemAsset.get("browser_download_url").getAsString(), StandardCharsets.UTF_8));
|
jdk.setData(URLDecoder.decode(itemAsset.path("browser_download_url").asText(), StandardCharsets.UTF_8));
|
||||||
result.add(jdk);
|
result.add(jdk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.mirror;
|
package com.imyeyu.api.modules.mirror;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||||
import com.imyeyu.api.modules.common.service.AttachmentService;
|
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||||
import com.imyeyu.api.modules.mirror.bean.AttachType;
|
import com.imyeyu.api.modules.mirror.bean.AttachType;
|
||||||
@@ -30,7 +30,7 @@ import java.util.stream.Collectors;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class OpenJDKMirror extends AttachmentMirror {
|
public class OpenJDKMirror extends AttachmentMirror {
|
||||||
|
|
||||||
private final Gson gson;
|
private final ObjectMapper jackson;
|
||||||
private final MirrorService service;
|
private final MirrorService service;
|
||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
private final OpenJDKGithubMirror githubMirror;
|
private final OpenJDKGithubMirror githubMirror;
|
||||||
@@ -64,7 +64,7 @@ public class OpenJDKMirror extends AttachmentMirror {
|
|||||||
result.add(jdk);
|
result.add(jdk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mirror.setData(gson.toJsonTree(result));
|
mirror.setData(jackson.valueToTree(result));
|
||||||
service.update(mirror);
|
service.update(mirror);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.imyeyu.api.modules.mirror;
|
package com.imyeyu.api.modules.mirror;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import com.imyeyu.api.modules.mirror.data.OpenJDK;
|
import com.imyeyu.api.modules.mirror.data.OpenJDK;
|
||||||
import com.imyeyu.api.modules.mirror.entity.Mirror;
|
import com.imyeyu.api.modules.mirror.entity.Mirror;
|
||||||
import com.imyeyu.api.modules.mirror.service.MirrorService;
|
import com.imyeyu.api.modules.mirror.service.MirrorService;
|
||||||
import com.imyeyu.utils.OS;
|
import com.imyeyu.utils.OS;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
import org.jsoup.nodes.Element;
|
import org.jsoup.nodes.Element;
|
||||||
@@ -41,18 +41,18 @@ public class OpenJDKTunaMirror extends AbstractMirror {
|
|||||||
/** 版本列表 */
|
/** 版本列表 */
|
||||||
private static final String[] VERSIONS = {"8", "11", "17", "21"};
|
private static final String[] VERSIONS = {"8", "11", "17", "21"};
|
||||||
|
|
||||||
private final Gson gson;
|
private final ObjectMapper jackson;
|
||||||
private final MirrorService service;
|
private final MirrorService service;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void sync(Mirror mirror) throws Exception {
|
protected void sync(Mirror mirror) throws Exception {
|
||||||
List<OpenJDK> result = new ArrayList<>();
|
List<OpenJDK> result = new ArrayList<>();
|
||||||
for (int i = 0; i < VERSIONS.length; i++) {
|
for (String version : VERSIONS) {
|
||||||
OpenJDK.Type[] types = OpenJDK.Type.values();
|
OpenJDK.Type[] types = OpenJDK.Type.values();
|
||||||
for (int j = 0; j < types.length; j++) {
|
for (OpenJDK.Type type : types) {
|
||||||
OS.Platform[] platforms = OS.Platform.values();
|
OS.Platform[] platforms = OS.Platform.values();
|
||||||
for (int k = 0; k < platforms.length; k++) {
|
for (OS.Platform platform : platforms) {
|
||||||
String url = PAGE_URL_TEMPLATE.formatted(VERSIONS[i], types[j].toString().toLowerCase(), platforms[k].toString().toLowerCase());
|
String url = PAGE_URL_TEMPLATE.formatted(version, type.toString().toLowerCase(), platform.toString().toLowerCase());
|
||||||
Document document = Jsoup.connect(url).get();
|
Document document = Jsoup.connect(url).get();
|
||||||
Element fileList = document.getElementById("list");
|
Element fileList = document.getElementById("list");
|
||||||
Elements linkTDList = fileList.getElementsByClass("link");
|
Elements linkTDList = fileList.getElementsByClass("link");
|
||||||
@@ -64,10 +64,10 @@ public class OpenJDKTunaMirror extends AbstractMirror {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
OpenJDK jdk = new OpenJDK();
|
OpenJDK jdk = new OpenJDK();
|
||||||
jdk.setPlatform(platforms[k]);
|
jdk.setPlatform(platform);
|
||||||
jdk.setType(types[j]);
|
jdk.setType(type);
|
||||||
jdk.setName(href);
|
jdk.setName(href);
|
||||||
jdk.setVersion(VERSIONS[i]);
|
jdk.setVersion(version);
|
||||||
jdk.setData(url + href);
|
jdk.setData(url + href);
|
||||||
|
|
||||||
result.add(jdk);
|
result.add(jdk);
|
||||||
@@ -77,7 +77,7 @@ public class OpenJDKTunaMirror extends AbstractMirror {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mirror.setData(gson.toJsonTree(result));
|
mirror.setData(jackson.valueToTree(result));
|
||||||
service.update(mirror);
|
service.update(mirror);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.mirror.controller;
|
package com.imyeyu.api.modules.mirror.controller;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.imyeyu.api.modules.mirror.entity.Mirror;
|
import com.imyeyu.api.modules.mirror.entity.Mirror;
|
||||||
import com.imyeyu.api.modules.mirror.service.MirrorService;
|
import com.imyeyu.api.modules.mirror.service.MirrorService;
|
||||||
import com.imyeyu.api.modules.mirror.vo.MirrorView;
|
import com.imyeyu.api.modules.mirror.vo.MirrorView;
|
||||||
@@ -38,7 +38,7 @@ public class MirrorController {
|
|||||||
*/
|
*/
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@GetMapping("/{mirrorName}")
|
@GetMapping("/{mirrorName}")
|
||||||
public JsonElement get(@PathVariable String mirrorName) {
|
public JsonNode get(@PathVariable String mirrorName) {
|
||||||
return service.getByName(mirrorName).getData();
|
return service.getByName(mirrorName).getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.imyeyu.api.modules.mirror.entity;
|
package com.imyeyu.api.modules.mirror.entity;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.imyeyu.spring.entity.Entity;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import com.imyeyu.spring.entity.Entity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 镜像
|
* 镜像
|
||||||
@@ -22,7 +22,7 @@ public class Mirror extends Entity {
|
|||||||
protected String name;
|
protected String name;
|
||||||
|
|
||||||
/** 同步数据 */
|
/** 同步数据 */
|
||||||
protected JsonElement data;
|
protected JsonNode data;
|
||||||
|
|
||||||
/** 周期(分钟) */
|
/** 周期(分钟) */
|
||||||
protected int period;
|
protected int period;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.music.core;
|
package com.imyeyu.api.modules.music.core;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@@ -36,7 +37,7 @@ public class Middleware implements SchedulingConfigurer {
|
|||||||
private static final String CACHE_CLEAR_CORN = "0 0/20 * * * ?";
|
private static final String CACHE_CLEAR_CORN = "0 0/20 * * * ?";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Gson gson;
|
private ObjectMapper jackson;
|
||||||
|
|
||||||
/** 缓存频道,Map<频道 ID, 关联频道> */
|
/** 缓存频道,Map<频道 ID, 关联频道> */
|
||||||
private final Map<String, ChannelBinding> channels = new HashMap<>();
|
private final Map<String, ChannelBinding> channels = new HashMap<>();
|
||||||
@@ -67,7 +68,7 @@ public class Middleware implements SchedulingConfigurer {
|
|||||||
channelBinding.setPlayerChannel(ctx);
|
channelBinding.setPlayerChannel(ctx);
|
||||||
channelBinding.setLastActiviedAt(Time.now());
|
channelBinding.setLastActiviedAt(Time.now());
|
||||||
if (channelBinding.getControllerChannel() != null) {
|
if (channelBinding.getControllerChannel() != null) {
|
||||||
channelBinding.getControllerChannel().writeAndFlush(new TextWebSocketFrame(gson.toJson(pkg)));
|
channelBinding.getControllerChannel().writeAndFlush(new TextWebSocketFrame(writeValueAsString(pkg)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,11 +91,19 @@ public class Middleware implements SchedulingConfigurer {
|
|||||||
channelBinding.setControllerChannel(ctx);
|
channelBinding.setControllerChannel(ctx);
|
||||||
channelBinding.setLastActiviedAt(Time.now());
|
channelBinding.setLastActiviedAt(Time.now());
|
||||||
if (pkg.getAction() != null && channelBinding.getPlayerChannel() != null) {
|
if (pkg.getAction() != null && channelBinding.getPlayerChannel() != null) {
|
||||||
byte[] bytes = gson.toJson(pkg).getBytes(StandardCharsets.UTF_8);
|
byte[] bytes = writeValueAsString(pkg).getBytes(StandardCharsets.UTF_8);
|
||||||
ByteBuf buffer = Unpooled.buffer();
|
ByteBuf buffer = Unpooled.buffer();
|
||||||
buffer.writeInt(bytes.length);
|
buffer.writeInt(bytes.length);
|
||||||
buffer.writeBytes(bytes);
|
buffer.writeBytes(bytes);
|
||||||
channelBinding.getPlayerChannel().writeAndFlush(buffer);
|
channelBinding.getPlayerChannel().writeAndFlush(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String writeValueAsString(Object value) {
|
||||||
|
try {
|
||||||
|
return jackson.writeValueAsString(value);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new IllegalStateException("write music websocket payload error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.music.handler;
|
package com.imyeyu.api.modules.music.handler;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@@ -26,7 +26,7 @@ import org.springframework.stereotype.Component;
|
|||||||
public class ControllerMessageHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
|
public class ControllerMessageHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Gson gson;
|
private ObjectMapper jackson;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Middleware middleware;
|
private Middleware middleware;
|
||||||
@@ -34,7 +34,11 @@ public class ControllerMessageHandler extends SimpleChannelInboundHandler<WebSoc
|
|||||||
@Override
|
@Override
|
||||||
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) {
|
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) {
|
||||||
if (msg instanceof TextWebSocketFrame textWebSocketFrame) {
|
if (msg instanceof TextWebSocketFrame textWebSocketFrame) {
|
||||||
middleware.pushControllerData(ctx, gson.fromJson(textWebSocketFrame.text(), ControllerPackage.class));
|
try {
|
||||||
|
middleware.pushControllerData(ctx, jackson.readValue(textWebSocketFrame.text(), ControllerPackage.class));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException("read controller websocket payload error", e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.channel().writeAndFlush(WebSocketCloseStatus.INVALID_MESSAGE_TYPE).addListener(ChannelFutureListener.CLOSE);
|
ctx.channel().writeAndFlush(WebSocketCloseStatus.INVALID_MESSAGE_TYPE).addListener(ChannelFutureListener.CLOSE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.music.handler;
|
package com.imyeyu.api.modules.music.handler;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
@@ -22,14 +22,18 @@ import org.springframework.stereotype.Component;
|
|||||||
public class PlayerMessageHandler extends SimpleChannelInboundHandler<String> {
|
public class PlayerMessageHandler extends SimpleChannelInboundHandler<String> {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Gson gson;
|
private ObjectMapper jackson;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Middleware middleware;
|
private Middleware middleware;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected synchronized void channelRead0(ChannelHandlerContext ctx, String result) {
|
protected synchronized void channelRead0(ChannelHandlerContext ctx, String result) {
|
||||||
middleware.pushPlayerData(ctx, gson.fromJson(result, PlayerPackage.class));
|
try {
|
||||||
|
middleware.pushPlayerData(ctx, jackson.readValue(result, PlayerPackage.class));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException("read player websocket payload error", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -475,7 +475,7 @@ public class FileController implements TimiJava, OS.FileSystem {
|
|||||||
resp.setHeader("Content-Disposition", Network.getFileDownloadHeader(file.getName()));
|
resp.setHeader("Content-Disposition", Network.getFileDownloadHeader(file.getName()));
|
||||||
resp.setHeader("Accept-Ranges", "bytes");
|
resp.setHeader("Accept-Ranges", "bytes");
|
||||||
|
|
||||||
RequestRange range = TimiSpring.requestRange(file.length());
|
RequestRange range = TimiSpring.getRequestRange(file.length());
|
||||||
if (range == null) {
|
if (range == null) {
|
||||||
// 完整文件
|
// 完整文件
|
||||||
resp.setContentLengthLong(file.length());
|
resp.setContentLengthLong(file.length());
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import com.imyeyu.api.modules.common.service.SettingService;
|
|||||||
import com.imyeyu.api.modules.system.service.TerminalService;
|
import com.imyeyu.api.modules.system.service.TerminalService;
|
||||||
import com.imyeyu.api.modules.system.vo.terminal.ExecCommand;
|
import com.imyeyu.api.modules.system.vo.terminal.ExecCommand;
|
||||||
import com.imyeyu.spring.annotation.AOPLog;
|
import com.imyeyu.spring.annotation.AOPLog;
|
||||||
import com.imyeyu.spring.annotation.RequestSingleParam;
|
|
||||||
import com.imyeyu.spring.annotation.RequiredToken;
|
import com.imyeyu.spring.annotation.RequiredToken;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
@@ -51,7 +50,7 @@ public class TerminalController {
|
|||||||
*/
|
*/
|
||||||
@RequiredToken
|
@RequiredToken
|
||||||
@PostMapping("/alive")
|
@PostMapping("/alive")
|
||||||
public boolean isAlive(@RequestSingleParam String sessionId) {
|
public boolean isAlive(@RequestBody String sessionId) {
|
||||||
return service.isAlive(sessionId);
|
return service.isAlive(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +63,7 @@ public class TerminalController {
|
|||||||
@AOPLog
|
@AOPLog
|
||||||
@RequiredToken
|
@RequiredToken
|
||||||
@PostMapping("/fill")
|
@PostMapping("/fill")
|
||||||
public synchronized String pathFill(@RequestSingleParam String path) {
|
public synchronized String pathFill(@RequestBody String path) {
|
||||||
return service.pathFill(path);
|
return service.pathFill(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +93,7 @@ public class TerminalController {
|
|||||||
@AOPLog
|
@AOPLog
|
||||||
@RequiredToken
|
@RequiredToken
|
||||||
@PostMapping("/close")
|
@PostMapping("/close")
|
||||||
public void close(@RequestSingleParam String sessionId) {
|
public void close(@RequestBody String sessionId) {
|
||||||
service.close(sessionId);
|
service.close(sessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.system.task;
|
package com.imyeyu.api.modules.system.task;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.imyeyu.api.modules.system.bean.DockerStatusStore;
|
import com.imyeyu.api.modules.system.bean.DockerStatusStore;
|
||||||
import com.imyeyu.api.modules.system.util.DockerEngineClient;
|
import com.imyeyu.api.modules.system.util.DockerEngineClient;
|
||||||
import com.imyeyu.utils.Time;
|
import com.imyeyu.utils.Time;
|
||||||
@@ -21,7 +20,7 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Docker 状态采集任务
|
* Docker 鐘舵€侀噰闆嗕换鍔?
|
||||||
*
|
*
|
||||||
* @author Codex
|
* @author Codex
|
||||||
* @since 2026-04-06
|
* @since 2026-04-06
|
||||||
@@ -34,7 +33,7 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|||||||
private final DockerEngineClient dockerEngineClient;
|
private final DockerEngineClient dockerEngineClient;
|
||||||
private final DockerStatusStore dockerStatusStore;
|
private final DockerStatusStore dockerStatusStore;
|
||||||
|
|
||||||
@Value("${docker.engine.collect-enabled:true}")
|
@Value("${docker.engine.collect-enabled:false}")
|
||||||
private boolean collectEnabled;
|
private boolean collectEnabled;
|
||||||
|
|
||||||
@Value("${docker.engine.collect-rate-ms:10000}")
|
@Value("${docker.engine.collect-rate-ms:10000}")
|
||||||
@@ -55,13 +54,12 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|||||||
|
|
||||||
private void collect() {
|
private void collect() {
|
||||||
try {
|
try {
|
||||||
JsonArray containers = dockerEngineClient.getJson("/containers/json", DockerEngineClient.query("all", "true")).getAsJsonArray();
|
ArrayNode containers = (ArrayNode) dockerEngineClient.getJson("/containers/json", DockerEngineClient.query("all", "true"));
|
||||||
long now = Time.now();
|
long now = Time.now();
|
||||||
synchronized (dockerStatusStore) {
|
synchronized (dockerStatusStore) {
|
||||||
Set<String> activeIds = new HashSet<>();
|
Set<String> activeIds = new HashSet<>();
|
||||||
for (JsonElement item : containers) {
|
for (JsonNode summary : containers) {
|
||||||
try {
|
try {
|
||||||
JsonObject summary = item.getAsJsonObject();
|
|
||||||
String containerId = getAsString(summary, "Id");
|
String containerId = getAsString(summary, "Id");
|
||||||
activeIds.add(containerId);
|
activeIds.add(containerId);
|
||||||
DockerStatusStore.Container container = dockerStatusStore.getContainers().computeIfAbsent(containerId, key -> new DockerStatusStore.Container());
|
DockerStatusStore.Container container = dockerStatusStore.getContainers().computeIfAbsent(containerId, key -> new DockerStatusStore.Container());
|
||||||
@@ -79,7 +77,7 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateContainerSummary(DockerStatusStore.Container container, JsonObject summary) {
|
private void updateContainerSummary(DockerStatusStore.Container container, JsonNode summary) {
|
||||||
container.setId(getAsString(summary, "Id"));
|
container.setId(getAsString(summary, "Id"));
|
||||||
container.setName(trimContainerName(readFirstArrayText(summary, "Names")));
|
container.setName(trimContainerName(readFirstArrayText(summary, "Names")));
|
||||||
container.setImage(getAsString(summary, "Image"));
|
container.setImage(getAsString(summary, "Image"));
|
||||||
@@ -90,19 +88,19 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateContainerInspect(String containerId, DockerStatusStore.Container container) {
|
private void updateContainerInspect(String containerId, DockerStatusStore.Container container) {
|
||||||
JsonObject inspect = dockerEngineClient.getJson("/containers/%s/json".formatted(containerId), Map.of()).getAsJsonObject();
|
JsonNode inspect = dockerEngineClient.getJson("/containers/%s/json".formatted(containerId), Map.of());
|
||||||
JsonObject state = getAsObject(inspect, "State");
|
JsonNode state = getAsObject(inspect, "State");
|
||||||
container.setStartedAt(getAsString(state, "StartedAt"));
|
container.setStartedAt(getAsString(state, "StartedAt"));
|
||||||
container.setFinishedAt(getAsString(state, "FinishedAt"));
|
container.setFinishedAt(getAsString(state, "FinishedAt"));
|
||||||
container.setExitCode(getAsInteger(state, "ExitCode"));
|
container.setExitCode(getAsInteger(state, "ExitCode"));
|
||||||
container.setRestartCount(getAsInteger(inspect, "RestartCount", 0));
|
container.setRestartCount(getAsInteger(inspect, "RestartCount", 0));
|
||||||
container.setOomKilled(getAsBoolean(state, "OOMKilled"));
|
container.setOomKilled(getAsBoolean(state, "OOMKilled"));
|
||||||
JsonObject health = getAsObject(state, "Health");
|
JsonNode health = getAsObject(state, "Health");
|
||||||
container.setHealthStatus(health == null ? null : getAsString(health, "Status"));
|
container.setHealthStatus(health == null ? null : getAsString(health, "Status"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateContainerStats(String containerId, DockerStatusStore.Container container, long now) {
|
private void updateContainerStats(String containerId, DockerStatusStore.Container container, long now) {
|
||||||
JsonObject stats = dockerEngineClient.getJson("/containers/%s/stats".formatted(containerId), DockerEngineClient.query("stream", "false")).getAsJsonObject();
|
JsonNode stats = dockerEngineClient.getJson("/containers/%s/stats".formatted(containerId), DockerEngineClient.query("stream", "false"));
|
||||||
Double cpuPercent = calculateCpuPercent(stats);
|
Double cpuPercent = calculateCpuPercent(stats);
|
||||||
Long memoryUsageBytes = getNestedLong(stats, "memory_stats", "usage");
|
Long memoryUsageBytes = getNestedLong(stats, "memory_stats", "usage");
|
||||||
Long memoryLimitBytes = getNestedLong(stats, "memory_stats", "limit");
|
Long memoryLimitBytes = getNestedLong(stats, "memory_stats", "limit");
|
||||||
@@ -112,21 +110,20 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|||||||
}
|
}
|
||||||
Long networkRxBytes = 0L;
|
Long networkRxBytes = 0L;
|
||||||
Long networkTxBytes = 0L;
|
Long networkTxBytes = 0L;
|
||||||
JsonObject networks = getAsObject(stats, "networks");
|
JsonNode networks = getAsObject(stats, "networks");
|
||||||
if (networks != null) {
|
if (networks != null) {
|
||||||
for (Map.Entry<String, JsonElement> item : networks.entrySet()) {
|
for (Map.Entry<String, JsonNode> item : (Iterable<Map.Entry<String, JsonNode>>) networks::fields) {
|
||||||
JsonObject network = item.getValue().getAsJsonObject();
|
JsonNode network = item.getValue();
|
||||||
networkRxBytes += getAsLong(network, "rx_bytes", 0L);
|
networkRxBytes += getAsLong(network, "rx_bytes", 0L);
|
||||||
networkTxBytes += getAsLong(network, "tx_bytes", 0L);
|
networkTxBytes += getAsLong(network, "tx_bytes", 0L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Long blockReadBytes = 0L;
|
Long blockReadBytes = 0L;
|
||||||
Long blockWriteBytes = 0L;
|
Long blockWriteBytes = 0L;
|
||||||
JsonObject blkioStats = getAsObject(stats, "blkio_stats");
|
JsonNode blkioStats = getAsObject(stats, "blkio_stats");
|
||||||
JsonArray ioServiceBytes = blkioStats == null ? null : blkioStats.getAsJsonArray("io_service_bytes_recursive");
|
ArrayNode ioServiceBytes = blkioStats == null ? null : getAsArray(blkioStats, "io_service_bytes_recursive");
|
||||||
if (ioServiceBytes != null) {
|
if (ioServiceBytes != null) {
|
||||||
for (JsonElement item : ioServiceBytes) {
|
for (JsonNode io : ioServiceBytes) {
|
||||||
JsonObject io = item.getAsJsonObject();
|
|
||||||
String op = getAsString(io, "op");
|
String op = getAsString(io, "op");
|
||||||
long value = getAsLong(io, "value", 0L);
|
long value = getAsLong(io, "value", 0L);
|
||||||
if ("Read".equalsIgnoreCase(op)) {
|
if ("Read".equalsIgnoreCase(op)) {
|
||||||
@@ -165,14 +162,14 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Double calculateCpuPercent(JsonObject stats) {
|
private Double calculateCpuPercent(JsonNode stats) {
|
||||||
Long cpuTotal = getNestedLong(stats, "cpu_stats", "cpu_usage", "total_usage");
|
Long cpuTotal = getNestedLong(stats, "cpu_stats", "cpu_usage", "total_usage");
|
||||||
Long preCpuTotal = getNestedLong(stats, "precpu_stats", "cpu_usage", "total_usage");
|
Long preCpuTotal = getNestedLong(stats, "precpu_stats", "cpu_usage", "total_usage");
|
||||||
Long systemTotal = getNestedLong(stats, "cpu_stats", "system_cpu_usage");
|
Long systemTotal = getNestedLong(stats, "cpu_stats", "system_cpu_usage");
|
||||||
Long preSystemTotal = getNestedLong(stats, "precpu_stats", "system_cpu_usage");
|
Long preSystemTotal = getNestedLong(stats, "precpu_stats", "system_cpu_usage");
|
||||||
Integer onlineCpus = getNestedInteger(stats, "cpu_stats", "online_cpus");
|
Integer onlineCpus = getNestedInteger(stats, "cpu_stats", "online_cpus");
|
||||||
if (onlineCpus == null || onlineCpus <= 0) {
|
if (onlineCpus == null || onlineCpus <= 0) {
|
||||||
JsonArray perCpuUsage = getNestedArray(stats, "cpu_stats", "cpu_usage", "percpu_usage");
|
ArrayNode perCpuUsage = getNestedArray(stats, "cpu_stats", "cpu_usage", "percpu_usage");
|
||||||
onlineCpus = perCpuUsage == null ? 1 : perCpuUsage.size();
|
onlineCpus = perCpuUsage == null ? 1 : perCpuUsage.size();
|
||||||
}
|
}
|
||||||
if (cpuTotal == null || preCpuTotal == null || systemTotal == null || preSystemTotal == null) {
|
if (cpuTotal == null || preCpuTotal == null || systemTotal == null || preSystemTotal == null) {
|
||||||
@@ -186,81 +183,89 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|||||||
return cpuDelta * 100D * onlineCpus / systemDelta;
|
return cpuDelta * 100D * onlineCpus / systemDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonObject getAsObject(JsonObject source, String key) {
|
private JsonNode getAsObject(JsonNode source, String key) {
|
||||||
if (source == null || !source.has(key) || source.get(key).isJsonNull()) {
|
if (source == null || !source.has(key) || source.get(key).isNull() || !source.get(key).isObject()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return source.getAsJsonObject(key);
|
return source.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonArray getNestedArray(JsonObject source, String... keys) {
|
private ArrayNode getAsArray(JsonNode source, String key) {
|
||||||
JsonElement current = source;
|
if (source == null || !source.has(key) || !source.get(key).isArray()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (ArrayNode) source.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayNode getNestedArray(JsonNode source, String... keys) {
|
||||||
|
JsonNode current = source;
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
if (current == null || !current.isJsonObject() || !current.getAsJsonObject().has(key)) {
|
if (current == null || !current.isObject() || !current.has(key)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
current = current.getAsJsonObject().get(key);
|
current = current.get(key);
|
||||||
}
|
}
|
||||||
return current != null && current.isJsonArray() ? current.getAsJsonArray() : null;
|
return current != null && current.isArray() ? (ArrayNode) current : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long getNestedLong(JsonObject source, String... keys) {
|
private Long getNestedLong(JsonNode source, String... keys) {
|
||||||
JsonElement current = source;
|
JsonNode current = source;
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
if (current == null || !current.isJsonObject() || !current.getAsJsonObject().has(key)) {
|
if (current == null || !current.isObject() || !current.has(key)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
current = current.getAsJsonObject().get(key);
|
current = current.get(key);
|
||||||
}
|
}
|
||||||
return current == null || current.isJsonNull() ? null : current.getAsLong();
|
return current == null || current.isNull() ? null : current.asLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer getNestedInteger(JsonObject source, String... keys) {
|
private Integer getNestedInteger(JsonNode source, String... keys) {
|
||||||
Long value = getNestedLong(source, keys);
|
Long value = getNestedLong(source, keys);
|
||||||
return value == null ? null : value.intValue();
|
return value == null ? null : value.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String readFirstArrayText(JsonObject source, String key) {
|
private String readFirstArrayText(JsonNode source, String key) {
|
||||||
if (source == null || !source.has(key) || !source.get(key).isJsonArray() || source.getAsJsonArray(key).isEmpty()) {
|
ArrayNode array = getAsArray(source, key);
|
||||||
|
if (array == null || array.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return source.getAsJsonArray(key).get(0).getAsString();
|
return array.get(0).asText();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getAsString(JsonObject source, String key) {
|
private String getAsString(JsonNode source, String key) {
|
||||||
if (source == null || !source.has(key) || source.get(key).isJsonNull()) {
|
if (source == null || !source.has(key) || source.get(key).isNull()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return source.get(key).getAsString();
|
return source.get(key).asText();
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getAsLong(JsonObject source, String key) {
|
private long getAsLong(JsonNode source, String key) {
|
||||||
return getAsLong(source, key, 0L);
|
return getAsLong(source, key, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getAsLong(JsonObject source, String key, long defaultValue) {
|
private long getAsLong(JsonNode source, String key, long defaultValue) {
|
||||||
if (source == null || !source.has(key) || source.get(key).isJsonNull()) {
|
if (source == null || !source.has(key) || source.get(key).isNull()) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return source.get(key).getAsLong();
|
return source.get(key).asLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer getAsInteger(JsonObject source, String key) {
|
private Integer getAsInteger(JsonNode source, String key) {
|
||||||
if (source == null || !source.has(key) || source.get(key).isJsonNull()) {
|
if (source == null || !source.has(key) || source.get(key).isNull()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return source.get(key).getAsInt();
|
return source.get(key).asInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getAsInteger(JsonObject source, String key, int defaultValue) {
|
private int getAsInteger(JsonNode source, String key, int defaultValue) {
|
||||||
if (source == null || !source.has(key) || source.get(key).isJsonNull()) {
|
if (source == null || !source.has(key) || source.get(key).isNull()) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return source.get(key).getAsInt();
|
return source.get(key).asInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getAsBoolean(JsonObject source, String key) {
|
private boolean getAsBoolean(JsonNode source, String key) {
|
||||||
return source != null && source.has(key) && !source.get(key).isJsonNull() && source.get(key).getAsBoolean();
|
return source != null && source.has(key) && !source.get(key).isNull() && source.get(key).asBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String trimContainerName(String name) {
|
private String trimContainerName(String name) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class UpsStatusTask implements SchedulingConfigurer {
|
|||||||
private final UpsStatusClient upsStatusClient;
|
private final UpsStatusClient upsStatusClient;
|
||||||
private final UpsStatusStore upsStatusStore;
|
private final UpsStatusStore upsStatusStore;
|
||||||
|
|
||||||
@Value("${ups.collect-enabled:true}")
|
@Value("${ups.collect-enabled:false}")
|
||||||
private boolean collectEnabled;
|
private boolean collectEnabled;
|
||||||
|
|
||||||
@Value("${ups.collect-rate-ms:60000}")
|
@Value("${ups.collect-rate-ms:60000}")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.system.util;
|
package com.imyeyu.api.modules.system.util;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonParser;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.java.bean.timi.TimiCode;
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -36,13 +36,16 @@ public class DockerEngineClient {
|
|||||||
private final String host;
|
private final String host;
|
||||||
private final String apiVersion;
|
private final String apiVersion;
|
||||||
private final Duration timeout;
|
private final Duration timeout;
|
||||||
|
private final ObjectMapper jackson;
|
||||||
private final HttpClient httpClient = HttpClient.newBuilder().build();
|
private final HttpClient httpClient = HttpClient.newBuilder().build();
|
||||||
|
|
||||||
public DockerEngineClient(
|
public DockerEngineClient(
|
||||||
|
ObjectMapper jackson,
|
||||||
@Value("${docker.engine.host:unix:///var/run/docker.sock}") String host,
|
@Value("${docker.engine.host:unix:///var/run/docker.sock}") String host,
|
||||||
@Value("${docker.engine.api-version:v1.41}") String apiVersion,
|
@Value("${docker.engine.api-version:v1.41}") String apiVersion,
|
||||||
@Value("${docker.engine.timeout-ms:5000}") long timeoutMs
|
@Value("${docker.engine.timeout-ms:5000}") long timeoutMs
|
||||||
) {
|
) {
|
||||||
|
this.jackson = jackson;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.apiVersion = apiVersion;
|
this.apiVersion = apiVersion;
|
||||||
this.timeout = Duration.ofMillis(timeoutMs);
|
this.timeout = Duration.ofMillis(timeoutMs);
|
||||||
@@ -55,13 +58,11 @@ public class DockerEngineClient {
|
|||||||
* @param queryParams 查询参数
|
* @param queryParams 查询参数
|
||||||
* @return JSON 数据
|
* @return JSON 数据
|
||||||
*/
|
*/
|
||||||
public JsonElement getJson(String path, Map<String, String> queryParams) {
|
public JsonNode getJson(String path, Map<String, String> queryParams) {
|
||||||
String requestPath = buildRequestPath(path, queryParams);
|
String requestPath = buildRequestPath(path, queryParams);
|
||||||
try {
|
try {
|
||||||
String body = host.startsWith("unix://")
|
String body = host.startsWith("unix://") ? executeUnixGet(requestPath) : executeHttpGet(requestPath);
|
||||||
? executeUnixGet(requestPath)
|
return jackson.readTree(body);
|
||||||
: executeHttpGet(requestPath);
|
|
||||||
return JsonParser.parseString(body);
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
log.error("docker engine request interrupted: {}", requestPath, e);
|
log.error("docker engine request interrupted: {}", requestPath, e);
|
||||||
@@ -72,13 +73,6 @@ public class DockerEngineClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建请求路径
|
|
||||||
*
|
|
||||||
* @param path 接口路径
|
|
||||||
* @param queryParams 查询参数
|
|
||||||
* @return 请求路径
|
|
||||||
*/
|
|
||||||
private String buildRequestPath(String path, Map<String, String> queryParams) {
|
private String buildRequestPath(String path, Map<String, String> queryParams) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("/");
|
builder.append("/");
|
||||||
@@ -101,14 +95,6 @@ public class DockerEngineClient {
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过 HTTP/TCP 执行 GET
|
|
||||||
*
|
|
||||||
* @param requestPath 请求路径
|
|
||||||
* @return 响应体
|
|
||||||
* @throws IOException IO 异常
|
|
||||||
* @throws InterruptedException 中断异常
|
|
||||||
*/
|
|
||||||
private String executeHttpGet(String requestPath) throws IOException, InterruptedException {
|
private String executeHttpGet(String requestPath) throws IOException, InterruptedException {
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
.uri(URI.create(host + requestPath))
|
.uri(URI.create(host + requestPath))
|
||||||
@@ -122,13 +108,6 @@ public class DockerEngineClient {
|
|||||||
return response.body();
|
return response.body();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过 Unix Socket 执行 GET
|
|
||||||
*
|
|
||||||
* @param requestPath 请求路径
|
|
||||||
* @return 响应体
|
|
||||||
* @throws IOException IO 异常
|
|
||||||
*/
|
|
||||||
private String executeUnixGet(String requestPath) throws IOException {
|
private String executeUnixGet(String requestPath) throws IOException {
|
||||||
String socketPath = host.substring("unix://".length());
|
String socketPath = host.substring("unix://".length());
|
||||||
UnixDomainSocketAddress address = UnixDomainSocketAddress.of(Path.of(socketPath));
|
UnixDomainSocketAddress address = UnixDomainSocketAddress.of(Path.of(socketPath));
|
||||||
@@ -147,13 +126,6 @@ public class DockerEngineClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取全部响应字节
|
|
||||||
*
|
|
||||||
* @param channel 通道
|
|
||||||
* @return 字节数组
|
|
||||||
* @throws IOException IO 异常
|
|
||||||
*/
|
|
||||||
private byte[] readAll(SocketChannel channel) throws IOException {
|
private byte[] readAll(SocketChannel channel) throws IOException {
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(8192);
|
ByteBuffer buffer = ByteBuffer.allocate(8192);
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
@@ -172,13 +144,6 @@ public class DockerEngineClient {
|
|||||||
return output.toByteArray();
|
return output.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析 HTTP 响应体
|
|
||||||
*
|
|
||||||
* @param responseBytes 响应字节
|
|
||||||
* @return 响应体
|
|
||||||
* @throws IOException IO 异常
|
|
||||||
*/
|
|
||||||
private String parseHttpBody(byte[] responseBytes) throws IOException {
|
private String parseHttpBody(byte[] responseBytes) throws IOException {
|
||||||
int splitIndex = indexOf(responseBytes, new byte[] {'\r', '\n', '\r', '\n'});
|
int splitIndex = indexOf(responseBytes, new byte[] {'\r', '\n', '\r', '\n'});
|
||||||
if (splitIndex < 0) {
|
if (splitIndex < 0) {
|
||||||
@@ -196,13 +161,6 @@ public class DockerEngineClient {
|
|||||||
return new String(bodyBytes, StandardCharsets.UTF_8);
|
return new String(bodyBytes, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 解码 Chunked 响应体
|
|
||||||
*
|
|
||||||
* @param bodyBytes 原始响应体
|
|
||||||
* @return 解码后的响应体
|
|
||||||
* @throws IOException IO 异常
|
|
||||||
*/
|
|
||||||
private byte[] decodeChunkedBody(byte[] bodyBytes) throws IOException {
|
private byte[] decodeChunkedBody(byte[] bodyBytes) throws IOException {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
@@ -223,25 +181,10 @@ public class DockerEngineClient {
|
|||||||
return output.toByteArray();
|
return output.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查找字节序列
|
|
||||||
*
|
|
||||||
* @param source 原数组
|
|
||||||
* @param pattern 目标数组
|
|
||||||
* @return 下标
|
|
||||||
*/
|
|
||||||
private int indexOf(byte[] source, byte[] pattern) {
|
private int indexOf(byte[] source, byte[] pattern) {
|
||||||
return indexOf(source, 0, pattern);
|
return indexOf(source, 0, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 从指定位置查找字节序列
|
|
||||||
*
|
|
||||||
* @param source 原数组
|
|
||||||
* @param start 起始位置
|
|
||||||
* @param pattern 目标数组
|
|
||||||
* @return 下标
|
|
||||||
*/
|
|
||||||
private int indexOf(byte[] source, int start, byte[] pattern) {
|
private int indexOf(byte[] source, int start, byte[] pattern) {
|
||||||
for (int i = start; i <= source.length - pattern.length; i++) {
|
for (int i = start; i <= source.length - pattern.length; i++) {
|
||||||
boolean matched = true;
|
boolean matched = true;
|
||||||
@@ -258,12 +201,6 @@ public class DockerEngineClient {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建查询参数映射
|
|
||||||
*
|
|
||||||
* @param entries 键值对
|
|
||||||
* @return 映射
|
|
||||||
*/
|
|
||||||
public static Map<String, String> query(String... entries) {
|
public static Map<String, String> query(String... entries) {
|
||||||
LinkedHashMap<String, String> result = new LinkedHashMap<>();
|
LinkedHashMap<String, String> result = new LinkedHashMap<>();
|
||||||
for (int i = 0; i + 1 < entries.length; i += 2) {
|
for (int i = 0; i + 1 < entries.length; i += 2) {
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
package com.imyeyu.api.modules.system.util;
|
package com.imyeyu.api.modules.system.util;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.JsonObject;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.imyeyu.api.modules.system.bean.UpsStatusStore;
|
import com.imyeyu.api.modules.system.bean.UpsStatusStore;
|
||||||
import com.imyeyu.java.bean.timi.TimiCode;
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
|
import com.imyeyu.network.ArgMap;
|
||||||
|
import com.imyeyu.network.CommonRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,55 +28,35 @@ public class UpsStatusClient {
|
|||||||
|
|
||||||
private final String statusUrl;
|
private final String statusUrl;
|
||||||
private final Duration timeout;
|
private final Duration timeout;
|
||||||
|
private final ObjectMapper jackson;
|
||||||
private final HttpClient httpClient = HttpClient.newBuilder().build();
|
private final HttpClient httpClient = HttpClient.newBuilder().build();
|
||||||
|
|
||||||
public UpsStatusClient(
|
public UpsStatusClient(
|
||||||
@Value("${ups.status-url:}") String statusUrl,
|
ObjectMapper jackson,
|
||||||
|
@Value("${ups.status-url:http://192.168.3.24:15178/ViewPower/workstatus/reqMonitorData?0.9053892723012932}") String statusUrl,
|
||||||
@Value("${ups.timeout-ms:5000}") long timeoutMs
|
@Value("${ups.timeout-ms:5000}") long timeoutMs
|
||||||
) {
|
) {
|
||||||
|
this.jackson = jackson;
|
||||||
this.statusUrl = statusUrl;
|
this.statusUrl = statusUrl;
|
||||||
this.timeout = Duration.ofMillis(timeoutMs);
|
this.timeout = Duration.ofMillis(timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public JsonNode getStatusJson() {
|
||||||
* 获取 UPS 状态 JSON
|
|
||||||
*
|
|
||||||
* @return JSON 数据
|
|
||||||
*/
|
|
||||||
public JsonElement getStatusJson() {
|
|
||||||
if (statusUrl == null || statusUrl.isBlank()) {
|
if (statusUrl == null || statusUrl.isBlank()) {
|
||||||
throw new TimiException(TimiCode.ARG_MISS).msgKey("缺少配置:ups.status-url");
|
throw new TimiException(TimiCode.ARG_MISS).msgKey("缺少配置:ups.status-url");
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(statusUrl))
|
|
||||||
.timeout(timeout)
|
|
||||||
.GET()
|
|
||||||
.build();
|
|
||||||
try {
|
try {
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
|
String response = CommonRequest.post(statusUrl).bodyEntity(ArgMap.of("portName", "USBusbdev3").toEntity()).asString();
|
||||||
if (400 <= response.statusCode()) {
|
return jackson.readTree(response);
|
||||||
throw new IOException("ups http error: " + response.statusCode());
|
|
||||||
}
|
|
||||||
return JsonParser.parseString(response.body());
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
log.error("request ups status interrupted: {}", statusUrl, e);
|
|
||||||
throw new TimiException(TimiCode.ERROR).msgKey("UPS 状态请求被中断");
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("request ups status error: {}", statusUrl, e);
|
log.error("request ups status error: {}", statusUrl, e);
|
||||||
throw new TimiException(TimiCode.ERROR).msgKey("UPS 状态请求失败");
|
throw new TimiException(TimiCode.ERROR).msgKey("UPS 状态请求失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 拉取并解析 UPS 当前快照
|
|
||||||
*
|
|
||||||
* @return UPS 当前快照
|
|
||||||
*/
|
|
||||||
public UpsStatusStore.Snapshot fetchSnapshot() {
|
public UpsStatusStore.Snapshot fetchSnapshot() {
|
||||||
JsonObject root = getStatusJson().getAsJsonObject();
|
JsonNode root = getStatusJson();
|
||||||
JsonObject workInfo = getAsObject(root, "workInfo");
|
JsonNode workInfo = getAsObject(root, "workInfo");
|
||||||
|
|
||||||
UpsStatusStore.Snapshot snapshot = new UpsStatusStore.Snapshot();
|
UpsStatusStore.Snapshot snapshot = new UpsStatusStore.Snapshot();
|
||||||
snapshot.setUpsTime(readUpsTime(workInfo));
|
snapshot.setUpsTime(readUpsTime(workInfo));
|
||||||
@@ -110,37 +87,25 @@ public class UpsStatusClient {
|
|||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private Long readUpsTime(JsonNode workInfo) {
|
||||||
* 读取 UPS 时间戳
|
JsonNode currentTime = getAsObject(workInfo, "currentTime");
|
||||||
*
|
if (currentTime == null || !currentTime.has("time") || currentTime.get("time").isNull()) {
|
||||||
* @param workInfo 工作信息
|
|
||||||
* @return 时间戳
|
|
||||||
*/
|
|
||||||
private Long readUpsTime(JsonObject workInfo) {
|
|
||||||
JsonObject currentTime = getAsObject(workInfo, "currentTime");
|
|
||||||
if (currentTime == null || !currentTime.has("time") || currentTime.get("time").isJsonNull()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return currentTime.get("time").getAsLong();
|
return currentTime.get("time").asLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private java.util.List<String> readWarnings(JsonNode workInfo) {
|
||||||
* 读取告警列表
|
|
||||||
*
|
|
||||||
* @param workInfo 工作信息
|
|
||||||
* @return 告警列表
|
|
||||||
*/
|
|
||||||
private java.util.List<String> readWarnings(JsonObject workInfo) {
|
|
||||||
java.util.List<String> warnings = new java.util.ArrayList<>();
|
java.util.List<String> warnings = new java.util.ArrayList<>();
|
||||||
if (workInfo == null || !workInfo.has("warnings") || !workInfo.get("warnings").isJsonArray()) {
|
if (workInfo == null || !workInfo.has("warnings") || !workInfo.get("warnings").isArray()) {
|
||||||
return warnings;
|
return warnings;
|
||||||
}
|
}
|
||||||
JsonArray array = workInfo.getAsJsonArray("warnings");
|
ArrayNode array = (ArrayNode) workInfo.get("warnings");
|
||||||
for (JsonElement item : array) {
|
for (JsonNode item : array) {
|
||||||
if (!item.isJsonPrimitive()) {
|
if (!item.isValueNode()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String warning = normalizeText(item.getAsString());
|
String warning = normalizeText(item.asText());
|
||||||
if (warning != null) {
|
if (warning != null) {
|
||||||
warnings.add(warning);
|
warnings.add(warning);
|
||||||
}
|
}
|
||||||
@@ -148,50 +113,29 @@ public class UpsStatusClient {
|
|||||||
return warnings;
|
return warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private JsonNode getAsObject(JsonNode source, String key) {
|
||||||
* 读取对象字段
|
if (source == null || !source.has(key) || source.get(key).isNull() || !source.get(key).isObject()) {
|
||||||
*
|
|
||||||
* @param source 源对象
|
|
||||||
* @param key 键
|
|
||||||
* @return 子对象
|
|
||||||
*/
|
|
||||||
private JsonObject getAsObject(JsonObject source, String key) {
|
|
||||||
if (source == null || !source.has(key) || source.get(key).isJsonNull() || !source.get(key).isJsonObject()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return source.getAsJsonObject(key);
|
return source.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private String readMeaningfulText(JsonNode source, String key) {
|
||||||
* 读取有效文本
|
if (source == null || !source.has(key) || source.get(key).isNull()) {
|
||||||
*
|
|
||||||
* @param source 源对象
|
|
||||||
* @param key 键
|
|
||||||
* @return 文本
|
|
||||||
*/
|
|
||||||
private String readMeaningfulText(JsonObject source, String key) {
|
|
||||||
if (source == null || !source.has(key) || source.get(key).isJsonNull()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return normalizeText(source.get(key).getAsString());
|
return normalizeText(source.get(key).asText());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private Integer readMeaningfulInteger(JsonNode source, String key) {
|
||||||
* 读取有效整数
|
if (source == null || !source.has(key) || source.get(key).isNull()) {
|
||||||
*
|
|
||||||
* @param source 源对象
|
|
||||||
* @param key 键
|
|
||||||
* @return 整数
|
|
||||||
*/
|
|
||||||
private Integer readMeaningfulInteger(JsonObject source, String key) {
|
|
||||||
if (source == null || !source.has(key) || source.get(key).isJsonNull()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JsonElement element = source.get(key);
|
JsonNode element = source.get(key);
|
||||||
if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber()) {
|
if (element.isNumber()) {
|
||||||
return element.getAsInt();
|
return element.asInt();
|
||||||
}
|
}
|
||||||
String text = normalizeText(element.getAsString());
|
String text = normalizeText(element.asText());
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -202,22 +146,15 @@ public class UpsStatusClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private Double readMeaningfulDouble(JsonNode source, String key) {
|
||||||
* 读取有效小数
|
if (source == null || !source.has(key) || source.get(key).isNull()) {
|
||||||
*
|
|
||||||
* @param source 源对象
|
|
||||||
* @param key 键
|
|
||||||
* @return 小数
|
|
||||||
*/
|
|
||||||
private Double readMeaningfulDouble(JsonObject source, String key) {
|
|
||||||
if (source == null || !source.has(key) || source.get(key).isJsonNull()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JsonElement element = source.get(key);
|
JsonNode element = source.get(key);
|
||||||
if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber()) {
|
if (element.isNumber()) {
|
||||||
return element.getAsDouble();
|
return element.asDouble();
|
||||||
}
|
}
|
||||||
String text = normalizeText(element.getAsString());
|
String text = normalizeText(element.asText());
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -228,23 +165,10 @@ public class UpsStatusClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private boolean readAsBoolean(JsonNode source, String key) {
|
||||||
* 读取布尔值
|
return source != null && source.has(key) && !source.get(key).isNull() && source.get(key).asBoolean();
|
||||||
*
|
|
||||||
* @param source 源对象
|
|
||||||
* @param key 键
|
|
||||||
* @return 布尔值
|
|
||||||
*/
|
|
||||||
private boolean readAsBoolean(JsonObject source, String key) {
|
|
||||||
return source != null && source.has(key) && !source.get(key).isJsonNull() && source.get(key).getAsBoolean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 规范化文本
|
|
||||||
*
|
|
||||||
* @param text 原始文本
|
|
||||||
* @return 规范化后的文本
|
|
||||||
*/
|
|
||||||
private String normalizeText(String text) {
|
private String normalizeText(String text) {
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
package com.imyeyu.api.util;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.google.gson.JsonSerializer;
|
|
||||||
import com.imyeyu.java.TimiJava;
|
|
||||||
import com.imyeyu.java.ref.Ref;
|
|
||||||
import com.imyeyu.api.TimiServerAPI;
|
|
||||||
import com.imyeyu.api.bean.MultilingualHandler;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author 夜雨
|
|
||||||
* @version 2023-10-26 10:16
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class GsonSerializerAdapter implements JsonSerializer<Object> {
|
|
||||||
|
|
||||||
private final Gson gson;
|
|
||||||
private final RedisMultilingual redisMultilingual;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(Object value, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
if (value instanceof MultilingualHandler _value) {
|
|
||||||
fillMultilingual(_value);
|
|
||||||
}
|
|
||||||
return gson.toJsonTree(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <K extends MultilingualHandler> void fillMultilingual(K value) {
|
|
||||||
try {
|
|
||||||
List<Field> fields = Ref.listFields(value.getClass());
|
|
||||||
for (int i = 0; i < fields.size(); i++) {
|
|
||||||
Field field = fields.get(i);
|
|
||||||
MultilingualHandler.MultilingualField multiField = field.getAnnotation(MultilingualHandler.MultilingualField.class);
|
|
||||||
if (multiField != null) {
|
|
||||||
String multiLangId = Ref.getFieldValue(value, field, String.class);
|
|
||||||
if (TimiJava.isNotEmpty(multiLangId)) {
|
|
||||||
Long langId = Long.parseLong(multiLangId);
|
|
||||||
if (redisMultilingual.map(TimiServerAPI.getUserLanguage()) instanceof RedisLanguage rl) {
|
|
||||||
// TODO 支持插值参数
|
|
||||||
Ref.setFieldValue(value, field, rl.text(langId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.imyeyu.api.util;
|
package com.imyeyu.api.util;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonElement;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.google.gson.JsonObject;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.imyeyu.api.TimiServerAPI;
|
import com.imyeyu.api.TimiServerAPI;
|
||||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||||
import com.imyeyu.api.modules.common.entity.Multilingual;
|
import com.imyeyu.api.modules.common.entity.Multilingual;
|
||||||
@@ -88,22 +88,22 @@ public class InitApplication implements ApplicationRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initFileType() {
|
private void initFileType() {
|
||||||
JsonObject items = settingService.getAsJsonObject(SettingKey.SYSTEM_FILE_TYPE);
|
ObjectNode items = settingService.getAsJsonObject(SettingKey.SYSTEM_FILE_TYPE);
|
||||||
|
|
||||||
String[] extensions;
|
String[] extensions;
|
||||||
JsonArray extensionsArray;
|
ArrayNode extensionsArray;
|
||||||
JsonObject itemObject;
|
JsonNode itemObject;
|
||||||
List<String> extensionsList;
|
List<String> extensionsList;
|
||||||
for (Map.Entry<String, JsonElement> item : items.entrySet()) {
|
for (Map.Entry<String, JsonNode> item : (Iterable<Map.Entry<String, JsonNode>>) items::fields) {
|
||||||
ServerFile.FileType fileType = Ref.toType(ServerFile.FileType.class, item.getKey());
|
ServerFile.FileType fileType = Ref.toType(ServerFile.FileType.class, item.getKey());
|
||||||
itemObject = item.getValue().getAsJsonObject();
|
itemObject = item.getValue();
|
||||||
extensionsList = new ArrayList<>();
|
extensionsList = new ArrayList<>();
|
||||||
extensionsArray = itemObject.get("extensions").getAsJsonArray();
|
extensionsArray = (ArrayNode) itemObject.get("extensions");
|
||||||
for (int i = 0; i < extensionsArray.size(); i++) {
|
for (JsonNode extensionNode : extensionsArray) {
|
||||||
if (extensionsArray.get(i).isJsonObject()) {
|
if (extensionNode.isObject()) {
|
||||||
extensionsList.add(extensionsArray.get(i).getAsJsonObject().get("value").getAsString());
|
extensionsList.add(extensionNode.path("value").asText());
|
||||||
} else {
|
} else {
|
||||||
extensionsList.add(extensionsArray.get(i).getAsString());
|
extensionsList.add(extensionNode.asText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extensions = new String[extensionsList.size()];
|
extensions = new String[extensionsList.size()];
|
||||||
|
|||||||
@@ -40,9 +40,6 @@ spring:
|
|||||||
enable: true
|
enable: true
|
||||||
required: true
|
required: true
|
||||||
default-encoding: UTF-8
|
default-encoding: UTF-8
|
||||||
mvc: # JSON 序列化
|
|
||||||
converters:
|
|
||||||
preferred-json-mapper: gson # 返回 JSON 序列化使用 GSON
|
|
||||||
redis: # Redis 数据库
|
redis: # Redis 数据库
|
||||||
host: dev.vm.imyeyu.test
|
host: dev.vm.imyeyu.test
|
||||||
port: 6379
|
port: 6379
|
||||||
|
|||||||
Reference in New Issue
Block a user