Compare commits

...

10 Commits

53 changed files with 1009 additions and 327 deletions

53
pom.xml
View File

@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.1</version>
<version>3.1.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lion</groupId>
@ -14,13 +14,9 @@
<name>LionWebsite</name>
<description>LionWebsite</description>
<properties>
<java.version>17</java.version>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -28,12 +24,13 @@
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.2</version>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<optional>true</optional>
</dependency>
<dependency>
@ -44,7 +41,7 @@
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>3.0.2</version>
<version>3.0.3</version>
<scope>test</scope>
</dependency>
@ -57,7 +54,7 @@
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
<version>5.8.20</version>
</dependency>
<dependency>
@ -104,12 +101,40 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.86.Final</version>
<version>4.1.101.Final</version>
</dependency>
<dependency>
<groupId>com.github.pengrad</groupId>
<artifactId>java-telegram-bot-api</artifactId>
<version>6.9.1</version>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.7.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<imageName>lionwebsite</imageName>
<buildArgs>
<arg>--gc=G1</arg>
<arg>-Ob</arg>
<arg>-H:+ReportExceptionStackTraces</arg>
<arg>--initialize-at-build-time=org.apache.commons.logging.LogFactory,org.apache.commons.logging.LogFactoryService</arg>
</buildArgs>
<metadataRepository>
<enabled>true</enabled>
</metadataRepository>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
@ -122,14 +147,6 @@
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>

View File

@ -0,0 +1,30 @@
package com.lion.lionwebsite.Configuration;
import com.lion.lionwebsite.Domain.*;
import com.lion.lionwebsite.Message.*;
import com.pengrad.telegrambot.TelegramBot;
import com.pengrad.telegrambot.model.Chat;
import com.pengrad.telegrambot.model.Message;
import com.pengrad.telegrambot.model.MessageEntity;
import com.pengrad.telegrambot.response.SendResponse;
import com.sun.tools.javac.Main;
import org.springframework.aot.hint.annotation.RegisterReflectionForBinding;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.pengrad.telegrambot.model.User;
@Configuration
@RegisterReflectionForBinding(classes = {CRC32Cache.class, CustomConfiguration.class,
GalleryForQuery.class, Gallery.class, GalleryTask.class, MaskDomain.class,
PageNameCache.class, ShareFile.class, Tag.class, TagMark.class, User.class,
SendResponse.class, Message.class, com.pengrad.telegrambot.model.User.class,
Chat.class, MessageEntity.class,
AbstractMethodError.class, DeleteGalleryMessage.class, DownloadPostMessage.class, DownloadStatusMessage.class,
GalleryPageQueryMessage.class, GalleryRequestMessage.class, IdentityMessage.class, MaintainMessage.class, ResponseMessage.class, UpdateGalleryMessage.class})
public class CustomBean {
@Bean
public TelegramBot getTelegramBot(){
return new TelegramBot("5222939329:AAHa6l9ZuVVdNSDLPI_H-c8O_VgeOEw5plA");
}
}

View File

@ -14,9 +14,12 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptorConfiguration implements WebMvcConfigurer {
@Resource
TaskHandlerInterceptor taskHandlerInterceptor;
public InterceptorConfiguration(TaskHandlerInterceptor taskHandlerInterceptor) {
this.taskHandlerInterceptor = taskHandlerInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getPersonalInterceptor()).addPathPatterns("/personal/**", "/remote/**");

View File

@ -0,0 +1,266 @@
package com.lion.lionwebsite.Configuration;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;
import org.apache.ibatis.cache.decorators.FifoCache;
import org.apache.ibatis.cache.decorators.LruCache;
import org.apache.ibatis.cache.decorators.SoftCache;
import org.apache.ibatis.cache.decorators.WeakCache;
import org.apache.ibatis.cache.impl.PerpetualCache;
import org.apache.ibatis.javassist.util.proxy.ProxyFactory;
import org.apache.ibatis.javassist.util.proxy.RuntimeSupport;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl;
import org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl;
import org.apache.ibatis.logging.log4j2.Log4j2Impl;
import org.apache.ibatis.logging.nologging.NoLoggingImpl;
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.reflection.TypeParameterResolver;
import org.apache.ibatis.scripting.defaults.RawLanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution;
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
import org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.core.ResolvableType;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Configuration(proxyBeanMethods = false)
@ImportRuntimeHints(MyBatisNativeConfiguration.MyBaitsRuntimeHintsRegistrar.class)
public class MyBatisNativeConfiguration {
@Bean
MyBatisBeanFactoryInitializationAotProcessor myBatisBeanFactoryInitializationAotProcessor() {
return new MyBatisBeanFactoryInitializationAotProcessor();
}
@Bean
static MyBatisMapperFactoryBeanPostProcessor myBatisMapperFactoryBeanPostProcessor() {
return new MyBatisMapperFactoryBeanPostProcessor();
}
static class MyBaitsRuntimeHintsRegistrar implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
Stream.of(RawLanguageDriver.class,
XMLLanguageDriver.class,
RuntimeSupport.class,
ProxyFactory.class,
Slf4jImpl.class,
Log.class,
JakartaCommonsLoggingImpl.class,
Log4j2Impl.class,
Jdk14LoggingImpl.class,
StdOutImpl.class,
NoLoggingImpl.class,
SqlSessionFactory.class,
PerpetualCache.class,
FifoCache.class,
LruCache.class,
SoftCache.class,
WeakCache.class,
SqlSessionFactoryBean.class,
ArrayList.class,
HashMap.class,
TreeSet.class,
HashSet.class
).forEach(x -> hints.reflection().registerType(x, MemberCategory.values()));
Stream.of(
"org/apache/ibatis/builder/xml/*.dtd",
"org/apache/ibatis/builder/xml/*.xsd"
).forEach(hints.resources()::registerPattern);
}
}
static class MyBatisBeanFactoryInitializationAotProcessor
implements BeanFactoryInitializationAotProcessor, BeanRegistrationExcludeFilter {
private final Set<Class<?>> excludeClasses = new HashSet<>();
MyBatisBeanFactoryInitializationAotProcessor() {
excludeClasses.add(MapperScannerConfigurer.class);
}
@Override public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) {
return excludeClasses.contains(registeredBean.getBeanClass());
}
@Override
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
String[] beanNames = beanFactory.getBeanNamesForType(MapperFactoryBean.class);
if (beanNames.length == 0) {
return null;
}
return (context, code) -> {
RuntimeHints hints = context.getRuntimeHints();
for (String beanName : beanNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName.substring(1));
PropertyValue mapperInterface = beanDefinition.getPropertyValues().getPropertyValue("mapperInterface");
if (mapperInterface != null && mapperInterface.getValue() != null) {
Class<?> mapperInterfaceType = (Class<?>) mapperInterface.getValue();
if (mapperInterfaceType != null) {
registerReflectionTypeIfNecessary(mapperInterfaceType, hints);
hints.proxies().registerJdkProxy(mapperInterfaceType);
hints.resources()
.registerPattern(mapperInterfaceType.getName().replace('.', '/').concat(".xml"));
registerMapperRelationships(mapperInterfaceType, hints);
}
}
}
};
}
private void registerMapperRelationships(Class<?> mapperInterfaceType, RuntimeHints hints) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(mapperInterfaceType);
for (Method method : methods) {
if (method.getDeclaringClass() != Object.class) {
ReflectionUtils.makeAccessible(method);
registerSqlProviderTypes(method, hints, SelectProvider.class, SelectProvider::value, SelectProvider::type);
registerSqlProviderTypes(method, hints, InsertProvider.class, InsertProvider::value, InsertProvider::type);
registerSqlProviderTypes(method, hints, UpdateProvider.class, UpdateProvider::value, UpdateProvider::type);
registerSqlProviderTypes(method, hints, DeleteProvider.class, DeleteProvider::value, DeleteProvider::type);
Class<?> returnType = MyBatisMapperTypeUtils.resolveReturnClass(mapperInterfaceType, method);
registerReflectionTypeIfNecessary(returnType, hints);
MyBatisMapperTypeUtils.resolveParameterClasses(mapperInterfaceType, method)
.forEach(x -> registerReflectionTypeIfNecessary(x, hints));
}
}
}
@SafeVarargs
private <T extends Annotation> void registerSqlProviderTypes(
Method method, RuntimeHints hints, Class<T> annotationType, Function<T, Class<?>>... providerTypeResolvers) {
for (T annotation : method.getAnnotationsByType(annotationType)) {
for (Function<T, Class<?>> providerTypeResolver : providerTypeResolvers) {
registerReflectionTypeIfNecessary(providerTypeResolver.apply(annotation), hints);
}
}
}
private void registerReflectionTypeIfNecessary(Class<?> type, RuntimeHints hints) {
if (!type.isPrimitive() && !type.getName().startsWith("java")) {
hints.reflection().registerType(type, MemberCategory.values());
}
}
}
static class MyBatisMapperTypeUtils {
private MyBatisMapperTypeUtils() {
// NOP
}
static Class<?> resolveReturnClass(Class<?> mapperInterface, Method method) {
Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, mapperInterface);
return typeToClass(resolvedReturnType, method.getReturnType());
}
static Set<Class<?>> resolveParameterClasses(Class<?> mapperInterface, Method method) {
return Stream.of(TypeParameterResolver.resolveParamTypes(method, mapperInterface))
.map(x -> typeToClass(x, x instanceof Class ? (Class<?>) x : Object.class)).collect(Collectors.toSet());
}
private static Class<?> typeToClass(Type src, Class<?> fallback) {
Class<?> result = null;
if (src instanceof Class<?>) {
if (((Class<?>) src).isArray()) {
result = ((Class<?>) src).getComponentType();
} else {
result = (Class<?>) src;
}
} else if (src instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) src;
int index = (parameterizedType.getRawType() instanceof Class
&& Map.class.isAssignableFrom((Class<?>) parameterizedType.getRawType())
&& parameterizedType.getActualTypeArguments().length > 1) ? 1 : 0;
Type actualType = parameterizedType.getActualTypeArguments()[index];
result = typeToClass(actualType, fallback);
}
if (result == null) {
result = fallback;
}
return result;
}
}
static class MyBatisMapperFactoryBeanPostProcessor implements MergedBeanDefinitionPostProcessor, BeanFactoryAware {
private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(
MyBatisMapperFactoryBeanPostProcessor.class);
private static final String MAPPER_FACTORY_BEAN = "org.mybatis.spring.mapper.MapperFactoryBean";
private ConfigurableBeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = (ConfigurableBeanFactory) beanFactory;
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (ClassUtils.isPresent(MAPPER_FACTORY_BEAN, this.beanFactory.getBeanClassLoader())) {
resolveMapperFactoryBeanTypeIfNecessary(beanDefinition);
}
}
private void resolveMapperFactoryBeanTypeIfNecessary(RootBeanDefinition beanDefinition) {
if (!beanDefinition.hasBeanClass() || !MapperFactoryBean.class.isAssignableFrom(beanDefinition.getBeanClass())) {
return;
}
if (beanDefinition.getResolvableType().hasUnresolvableGenerics()) {
Class<?> mapperInterface = getMapperInterface(beanDefinition);
if (mapperInterface != null) {
// Exposes a generic type information to context for prevent early initializing
beanDefinition
.setTargetType(ResolvableType.forClassWithGenerics(beanDefinition.getBeanClass(), mapperInterface));
}
}
}
private Class<?> getMapperInterface(RootBeanDefinition beanDefinition) {
try {
return (Class<?>) beanDefinition.getPropertyValues().get("mapperInterface");
}
catch (Exception e) {
LOG.debug("Fail getting mapper interface type.", e);
return null;
}
}
}
}

View File

@ -18,18 +18,21 @@ import java.util.List;
@RequestMapping("/GalleryManage")
@Slf4j
public class GalleryManageController {
@Resource
GalleryManageService galleryManageService;
@Resource
CollectService collectService;
@Resource
CustomUtil customUtil;
@Resource
UserServiceImpl userService;
public GalleryManageController(GalleryManageService galleryManageService, CollectService collectService, CustomUtil customUtil, UserServiceImpl userService) {
this.galleryManageService = galleryManageService;
this.collectService = collectService;
this.customUtil = customUtil;
this.userService = userService;
}
@PostMapping("")
public String create_task(String link, String targetResolution, String AuthCode,
@RequestParam(value = "tags", required = false) List<Integer> tags,

View File

@ -1,28 +0,0 @@
package com.lion.lionwebsite.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class NavigationController {
@GetMapping("/personal/")
public String personal_index(){
return "self";
}
@GetMapping("/personal/mobile")
public String personal_mobile(){
return "selfMobile";
}
@GetMapping("/")
public String index(){
return "index";
}
@GetMapping("/mobile")
public String mobile(){
return "mobile";
}
}

View File

@ -23,12 +23,15 @@ import java.io.IOException;
@RequestMapping("/personal")
public class PersonalController {
@Resource
PersonalServiceImpl personalService;
@Resource
LocalServiceImpl localService;
public PersonalController(PersonalServiceImpl personalService, LocalServiceImpl localService) {
this.personalService = personalService;
this.localService = localService;
}
@GetMapping("/sub/self")
public void sub(HttpServletResponse response, HttpServletRequest request){
FileDownload.export(request, response, "sub/sub.txt");

View File

@ -4,9 +4,8 @@ package com.lion.lionwebsite.Controller;
import com.lion.lionwebsite.Domain.User;
import com.lion.lionwebsite.Service.PublicServiceImpl;
import com.lion.lionwebsite.Service.RemoteService;
import com.lion.lionwebsite.Util.FileDownload;
import com.lion.lionwebsite.Service.SubService;
import com.lion.lionwebsite.Util.Response;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@ -23,12 +22,18 @@ public class PublicController {
final List<String> black_share_codes = new LinkedList<>();
@Resource
PublicServiceImpl publicService;
@Resource
RemoteService remoteService;
SubService subService;
public PublicController(PublicServiceImpl publicService, RemoteService remoteService, SubService subService) {
this.publicService = publicService;
this.remoteService = remoteService;
this.subService = subService;
}
@GetMapping("/ip")
public void ip(HttpServletRequest request, String auth, HttpServletResponse response) throws IOException {
String ip = request.getHeader("X-Forwarded-For");
@ -42,32 +47,20 @@ public class PublicController {
response.getOutputStream().write(ip.getBytes(StandardCharsets.UTF_8));
}
@GetMapping("/sub/{client}/{AuthCode}")
public void publicSub(@PathVariable("AuthCode") String AuthCode,
@GetMapping("/sub/{client}/{key}")
public void publicSub(@PathVariable("key") String key,
@PathVariable("client") String client,
HttpServletResponse response,
HttpServletRequest request) throws IOException {
if(AuthCode == null || client == null || !AuthCode.equals("covid"))
return;
switch (client){
case "v2ray" -> FileDownload.export(request, response, "sub/DouNaiV2ray.txt");
case "clash" -> FileDownload.export(request, response, "sub/DouNaiClash.txt");
default -> response.getOutputStream().write("client error".getBytes(StandardCharsets.UTF_8));
}
HttpServletRequest request) {
subService.updateSub(response, request, client, key);
}
@GetMapping("/GetFile/{path}")
public void getFile(HttpServletRequest request, HttpServletResponse response, String ShareCode, @PathVariable("path") String path) throws IOException {
synchronized (black_share_codes) {
if (black_share_codes.contains(ShareCode)) {
String ip = request.getHeader("X-Forwarded-For") == null ? request.getRemoteAddr() : request.getHeader("X-Forwarded-For");
log.info("dispatch request ip:{} file:{}", ip, path);
if (black_share_codes.contains(ShareCode))
return;
}
}
log.info("ShareCode:{}", ShareCode);
log.info("Path:{}", path);

View File

@ -12,9 +12,11 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/query")
public class QueryController {
@Resource
QueryService queryService;
public QueryController(QueryService queryService) {
this.queryService = queryService;
}
@GetMapping("")
public String query(String keyword, String prev, String next){

View File

@ -0,0 +1,39 @@
package com.lion.lionwebsite.Controller;
import com.lion.lionwebsite.Service.SubService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/personal/subBind/")
public class SubController {
SubService subService;
public SubController(SubService subService) {
this.subService = subService;
}
@PostMapping("")
public String addSubBind(String user){
return subService.insertSubBind(user);
}
@PutMapping("")
public String resetKey(String user){
return subService.resetKey(user);
}
@GetMapping("all")
public String getAllSubBind(){
return subService.selectAllSubBind();
}
@GetMapping("allRecord")
public String getAllSubUpdateRecord(){
return subService.SelectAllSubUpdateRecord();
}
@DeleteMapping("")
public String deleteSubBind(String user){
return subService.deleteSubBind(user);
}
}

View File

@ -9,9 +9,12 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/GalleryManage")
public class TagController {
@Resource
TagService tagService;
public TagController(TagService tagService) {
this.tagService = tagService;
}
@PostMapping("/tag")
public String createTag(String tag){
return tagService.createTag(tag);

View File

@ -8,9 +8,12 @@ import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/personal/user")
public class UserController {
@Resource
UserServiceImpl userService;
public UserController(UserServiceImpl userService) {
this.userService = userService;
}
@GetMapping("")
public String getAllUser(){
return userService.getAllUser();

View File

@ -28,7 +28,7 @@ public interface GalleryMapper {
@Select("select * from gallery where status in ('已提交', '下载中')")
Gallery[] selectUnDoneGalleries();
@Select("select * from gallery")
@Select("select * from gallery order by createTime")
Gallery[] selectAllGallery();
@Select("select * from gallery where name like #{name} limit 1")

View File

@ -0,0 +1,43 @@
package com.lion.lionwebsite.Dao;
import com.lion.lionwebsite.Domain.SubBind;
import com.lion.lionwebsite.Domain.SubUpdateRecord;
import org.apache.ibatis.annotations.*;
import java.util.ArrayList;
@Mapper
public interface SubMapper {
@Insert("insert into sub_bind values (#{key}, #{user})")
void insertSubBind(SubBind subBind);
@Select("select * from sub_bind")
ArrayList<SubBind> selectAllSubBind();
@Select("select * from sub_bind where key=#{key}")
SubBind selectSubBind(String key);
@Select("select count(key) from sub_bind where key=#{key}")
boolean selectSubBindExist(String key);
@Select("select count(user) from sub_update_record where user=#{user}")
Integer selectUpdateRecordCount(String user);
@Select("select min(id) from sub_update_record where user=#{user}")
Integer selectMinUpdateRecordId(String user);
@Delete("delete from sub_bind where user=#{user}")
void deleteSubBind(String user);
@Insert("insert into sub_update_record (user, ip, UA, time, location) values (#{user}, #{ip}, #{UA}, #{time}, #{location})")
void insertSubUpdateRecord(SubUpdateRecord subUpdateRecord);
@Select("select * from sub_update_record")
ArrayList<SubUpdateRecord> selectAllSubUpdateRecord();
@Delete("delete from sub_update_record where user=#{user}")
void deleteSubUpdateRecord(String user);
@Delete("delete from sub_update_record where id=#{id}")
void deleteSubUpdateRecordById(int id);
}

View File

@ -15,6 +15,8 @@ public class GalleryTask {
public static byte COMPRESS_COMPLETE = 4;
public static byte COMPRESSING = 5;
public static byte DOWNLOAD_ALL = 3;
public static byte DOWNLOAD_PREVIEW = 2;

View File

@ -0,0 +1,13 @@
package com.lion.lionwebsite.Domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SubBind {
String key;
String user;
}

View File

@ -0,0 +1,19 @@
package com.lion.lionwebsite.Domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SubUpdateRecord {
int id;
String user;
String ip;
String UA;
Date time;
String location;
}

View File

@ -2,7 +2,6 @@ package com.lion.lionwebsite.Filter;
import com.lion.lionwebsite.Dao.UserMapper;
import com.lion.lionwebsite.Util.CustomUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
@ -11,9 +10,11 @@ import java.io.IOException;
@WebFilter(filterName = "AccessFilter", urlPatterns = {"/validate"})
public class AccessFilter implements Filter {
@Resource
UserMapper userMapper;
public AccessFilter(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

View File

@ -15,11 +15,14 @@ public class TaskHandlerInterceptor implements HandlerInterceptor {
UserMapper userMapper;
String[] AuthCodes = null;
public TaskHandlerInterceptor(UserMapper userMapper) {
this.userMapper = userMapper;
AuthCodes = userMapper.selectAllAuthCode();
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
if(AuthCodes == null)
AuthCodes = userMapper.selectAllAuthCode();
String auth = request.getParameter("AuthCode");
if(auth != null)

View File

@ -1,5 +1,8 @@
package com.lion.lionwebsite.Message;
import lombok.Data;
@Data
public class AbstractMessage {
public static final byte DOWNLOAD_POST_MESSAGE = 1;
@ -15,6 +18,9 @@ public class AbstractMessage {
public static final byte GALLERY_PAGE_QUERY_MESSAGE = 5;
public static final byte IDENTITY_MESSAGE = 6;
public static final byte MAINTAIN_MESSAGE = 7;
public static final byte GALLERY_REQUEST_MESSAGE = 101;
public byte messageType;

View File

@ -1,10 +1,15 @@
package com.lion.lionwebsite.Message;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class IdentityMessage extends AbstractMessage{
{
messageType = IDENTITY_MESSAGE;
}
String identity;
}

View File

@ -0,0 +1,7 @@
package com.lion.lionwebsite.Message;
public class MaintainMessage extends AbstractMessage{
{
messageType = MAINTAIN_MESSAGE;
}
}

View File

@ -45,6 +45,7 @@ public class MessageCodec extends ByteToMessageCodec<AbstractMessage> {
case AbstractMessage.DELETE_GALLERY_MESSAGE -> objectMapper.readValue(metadata, DeleteGalleryMessage.class);
case AbstractMessage.GALLERY_PAGE_QUERY_MESSAGE -> objectMapper.readValue(metadata, GalleryPageQueryMessage.class);
case AbstractMessage.IDENTITY_MESSAGE -> objectMapper.readValue(metadata, IdentityMessage.class);
case AbstractMessage.MAINTAIN_MESSAGE -> objectMapper.readValue(metadata, MaintainMessage.class);
default -> null;
};

View File

@ -2,16 +2,18 @@ package com.lion.lionwebsite.Service;
import com.lion.lionwebsite.Dao.CollectMapper;
import com.lion.lionwebsite.Util.Response;
import jakarta.annotation.Resource;
import lombok.Data;
import org.springframework.stereotype.Service;
@Service
@Data
public class CollectService {
@Resource
CollectMapper collectMapper;
public CollectService(CollectMapper collectMapper){
this.collectMapper = collectMapper;
}
public String collectGallery(int gid, int collector){
Response response = Response.generateResponse();
if(collectMapper.isCollect(gid, collector) == 0) { //没有收藏

View File

@ -11,12 +11,10 @@ import com.lion.lionwebsite.Util.FileDownload;
import com.lion.lionwebsite.Util.GalleryUtil;
import com.lion.lionwebsite.Util.Response;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
import java.io.*;
@ -30,11 +28,10 @@ import static com.lion.lionwebsite.Util.CustomUtil.fourZeroFour;
@Service
@Data
@Slf4j
@ConfigurationProperties(prefix = "gallery-manage-service")
public class GalleryManageService {
String TargetPath;
String TargetPath = "/root/gallery/";
int cacheSize;
int cacheSize = 100;
Map<Integer, String> gid2name_cache = new HashMap<>();
@ -42,30 +39,37 @@ public class GalleryManageService {
Map<String, String> page2pageNameCache = new HashMap<>();
@Resource
GalleryMapper galleryMapper;
@Resource
CollectMapper collectMapper;
@Resource
CustomConfigurationMapper configurationMapper;
@Resource
UserMapper userMapper;
@Resource
ShareFileMapper shareFileMapper;
@Resource
TagMapper tagMapper;
@Resource
PageNameCacheMapper pageNameCacheMapper;
@Resource
RemoteService remoteService;
PushService pushService;
public GalleryManageService(GalleryMapper galleryMapper, CollectMapper collectMapper, CustomConfigurationMapper configurationMapper, UserMapper userMapper, ShareFileMapper shareFileMapper,
TagMapper tagMapper, PageNameCacheMapper pageNameCacheMapper, RemoteService remoteService, PushService pushService){
this.galleryMapper = galleryMapper;
this.collectMapper = collectMapper;
this.configurationMapper = configurationMapper;
this.userMapper = userMapper;
this.shareFileMapper = shareFileMapper;
this.tagMapper = tagMapper;
this.pageNameCacheMapper = pageNameCacheMapper;
this.remoteService = remoteService;
this.pushService = pushService;
}
/**
* 创建任务
* @param link 任务链接
@ -75,15 +79,20 @@ public class GalleryManageService {
*/
public String createTask(String link, String targetResolution, String AuthCode, List<Integer> tidS, byte mode){
Response response = Response.generateResponse();
User user = userMapper.selectUserByAuthCode(AuthCode);
// return Response._failure("调试中,请勿提交任务");
if(remoteService.isDead())
return Response._failure("节点挂了,找狮子处理");
if(remoteService.isDead()) {
response.failure("节点挂了,找狮子处理");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}
int gid;
try {
gid = Integer.parseInt(link.split("/")[4]);
}catch (NumberFormatException e){
response.failure("链接错误");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}
Gallery gallery;
@ -91,6 +100,7 @@ public class GalleryManageService {
//判断数据库中是否有这个任务有则返回状态
if((gallery = galleryMapper.selectGalleryByGid(gid)) != null){
response.failure("任务队列已有此任务,任务状态: " + gallery.getStatus() + " 请点击查找任务");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}
@ -99,28 +109,34 @@ public class GalleryManageService {
gallery = GalleryUtil.parse(link, true, targetResolution);
if(gallery == null){
log.error("创建任务: {},解析失败", link);
return Response._failure("任务解析失败,未知原因,请检查链接是否正常");
response.failure("任务解析失败,未知原因,请检查链接是否正常");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}else{
log.info("创建任务: {} 目标分辨率:{}", link, targetResolution);
if(remoteService.addGalleryToQueue(gallery, mode) != 0){
log.error("传送任务{}失败, 未知原因", gallery.getName());
return Response._failure("任务传送失败,未知原因");
response.failure("任务传送失败,未知原因");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}
}
}catch (ResolutionNotMatchException e){
e.printStackTrace();
response.failure("提交失败,分辨率不存在");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}catch (IOException e){
e.printStackTrace();
response.failure("IO错误可能是网络波动");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}
//处理下载结果将任务插入数据库并且更新每周用量
if(gallery.getStatus().equals("已提交")) {
response.success(gallery.toString());
gallery.setDownloader(userMapper.selectUserByAuthCode(AuthCode).getId());
gallery.setDownloader(user.getId());
gallery.setMode(mode);
galleryMapper.insertGallery(gallery);
@ -136,6 +152,7 @@ public class GalleryManageService {
response.failure("提交失败,未知原因");
galleryMapper.deleteGalleryByGid(gallery.getGid());
}
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}

View File

@ -6,14 +6,12 @@ import com.lion.lionwebsite.Dao.ShareFileMapper;
import com.lion.lionwebsite.Domain.CustomConfiguration;
import com.lion.lionwebsite.Domain.ShareFile;
import com.lion.lionwebsite.Util.CustomUtil;
import jakarta.annotation.Resource;
import lombok.Data;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@ -29,22 +27,26 @@ import java.util.*;
import static java.nio.file.FileVisitResult.CONTINUE;
@Service
@ConfigurationProperties(prefix = "local-service")
@Data
public class LocalServiceImpl{
String fires;
String DouNaiClash;
String DouNaiV2ray;
String fires = "https://api.dler.io/sub?target=clash&new_name=true&url=https%3A%2F%2Ffast.losadhwselfff2332dasd.xyz%2Flink%2Fz0pfwyTvC5naXkbb%3Fclash%3D1&insert=false&config=https%3A%2F%2Fraw.githubusercontent.com%2FACL4SSR%2FACL4SSR%2Fmaster%2FClash%2Fconfig%2FACL4SSR_Online.ini";
String DouNaiClash = "https://aaaa.gay/link/X7zEqkIx5gtIGugO?client=clashmeta";
String DouNaiV2ray = "https://aaaa.gay/link/X7zEqkIx5gtIGugO?client=v2";
@Resource
CustomConfigurationMapper configurationMapper;
@Resource
ShareFileMapper shareFIleMapper;
@Resource
GalleryMapper galleryMapper;
public LocalServiceImpl(CustomConfigurationMapper configurationMapper, ShareFileMapper shareFileMapper, GalleryMapper galleryMapper){
this.shareFIleMapper = shareFileMapper;
this.configurationMapper = configurationMapper;
this.galleryMapper = galleryMapper;
}
/**
* 每周周一四点重置额度
*/

View File

@ -43,7 +43,6 @@ import java.util.concurrent.Executors;
@Service
@Data
@ConfigurationProperties(prefix = "personal-service")
@Slf4j
public class PersonalServiceImpl{
@Resource
@ -58,13 +57,17 @@ public class PersonalServiceImpl{
@Resource
TaskHandlerInterceptor taskHandlerInterceptor;
String StoragePath;
String StoragePath = "/storage/";
DateTimeFormatter dateTimeFormatter = CustomUtil.dateTimeFormatter();
ExecutorService compressThreadPool;
PersonalServiceImpl(){
public PersonalServiceImpl(CustomConfigurationMapper configurationMapper, UserMapper userMapper, ShareFileMapper shareFileMapper, TaskHandlerInterceptor taskHandlerInterceptor){
this.configurationMapper = configurationMapper;
this.userMapper = userMapper;
this.shareFileMapper = shareFileMapper;
this.taskHandlerInterceptor = taskHandlerInterceptor;
compressThreadPool = Executors.newFixedThreadPool(1);
}

View File

@ -37,7 +37,7 @@ public class PublicServiceImpl {
CustomConfigurationMapper configurationMapper;
@Resource
ShareFileMapper shareFIleMapper;
ShareFileMapper shareFileMapper;
@Resource
UserMapper userMapper;
@ -45,6 +45,13 @@ public class PublicServiceImpl {
@Resource
TaskHandlerInterceptor taskHandlerInterceptor;
public PublicServiceImpl(CustomConfigurationMapper configurationMapper, ShareFileMapper shareFileMapper, UserMapper userMapper, TaskHandlerInterceptor taskHandlerInterceptor) {
this.configurationMapper = configurationMapper;
this.shareFileMapper = shareFileMapper;
this.userMapper = userMapper;
this.taskHandlerInterceptor = taskHandlerInterceptor;
}
/**
* 记录家里ip地址
* @param ip ip地址
@ -68,7 +75,7 @@ public class PublicServiceImpl {
if(ShareCode == null) {
response.failure("ShareCode invalid");
} else {
ShareFile shareFile = shareFIleMapper.selectShareFileByShareCode(ShareCode);
ShareFile shareFile = shareFileMapper.selectShareFileByShareCode(ShareCode);
Calendar ExpireTime = Calendar.getInstance();
Calendar now = Calendar.getInstance();
@ -78,7 +85,7 @@ public class PublicServiceImpl {
FileDownload.export(httpRequest, httpResponse, shareFile.getFilePath());
return true;
} else {
shareFIleMapper.deleteShareFile(shareFile.getShareCode());
shareFileMapper.deleteShareFile(shareFile.getShareCode());
response.failure("ShareCode is expired or File is not exist");
}
} else

View File

@ -0,0 +1,51 @@
package com.lion.lionwebsite.Service;
import com.lion.lionwebsite.Domain.Gallery;
import com.lion.lionwebsite.Util.Response;
import com.pengrad.telegrambot.TelegramBot;
import com.pengrad.telegrambot.UpdatesListener;
import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.request.SendMessage;
import jakarta.annotation.Resource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class PushService {
long self = 686839482;
@Resource
TelegramBot bot;
public PushService(TelegramBot bot) {
this.bot = bot;
}
public void taskCreateReport(String username, String link, Response response){
if(response.isSuccess())
sendToMe(String.format("用户%s提交下载%s", username, link));
else
sendToMe(String.format("用户%s提交下载%s , 下载失败:%s", username, link, response.get("data")));
}
public void downloadComplete(Gallery gallery){
sendToMe(gallery.getLink() + " 下载完成");
}
public void storageNodeOnline(){
sendToMe("存储节点上线");
}
public void storageNodeOffline(){
sendToMe("存储节点掉线");
}
public void sendToMe(String text){
System.out.println(text);
SendMessage sendMessage = new SendMessage(self, text);
bot.execute(sendMessage);
}
}

View File

@ -14,10 +14,8 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.Promise;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
import java.io.File;
@ -37,7 +35,6 @@ import java.util.concurrent.atomic.AtomicInteger;
@Service
@Data
@Slf4j
@ConfigurationProperties(prefix = "remote-service")
public class RemoteService {
ChannelFuture channelFuture;
@ -48,11 +45,10 @@ public class RemoteService {
short port = 26321;
String storagePath;
@Resource
GalleryMapper galleryMapper;
PushService pushService;
HashMap<Integer, Promise<AbstractMessage>> promiseHashMap;
EventLoop eventLoopGroup;
@ -63,7 +59,9 @@ public class RemoteService {
AtomicInteger atomicInteger;
public RemoteService(){
public RemoteService(GalleryMapper galleryMapper, PushService pushService){
this.galleryMapper = galleryMapper;
this.pushService = pushService;
atomicInteger = new AtomicInteger(0);
eventLoopGroup = new DefaultEventLoop();
downloadThread = Executors.newCachedThreadPool();
@ -83,17 +81,21 @@ public class RemoteService {
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel channel){
channel.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 1, 4));
channel.pipeline().addLast(new LengthFieldBasedFrameDecoder(100000000, 1, 4));
channel.pipeline().addLast(new MessageCodec());
channel.pipeline().addLast(new LoggingHandler());
channel.pipeline().addLast(new MyChannelInboundHandlerAdapter());
}
}).connect(new InetSocketAddress(ip, port)).sync();
log.info("connect success");
if(pushService != null)
pushService.storageNodeOnline();
channel = channelFuture.channel();
channel.writeAndFlush(new IdentityMessage());
channel.writeAndFlush(new IdentityMessage("lionwebsite"));
return true;
}catch (Exception e){
e.printStackTrace();
log.info("connect node failed, wait for node back online");
return false;
}
@ -149,7 +151,6 @@ public class RemoteService {
}
public byte cachePreview(String galleryName, short page, File file){
File parentFile = file.getParentFile();
if(!parentFile.isDirectory())
if(parentFile.mkdirs())
@ -289,6 +290,7 @@ public class RemoteService {
public void channelRead(ChannelHandlerContext ctx, Object msg) {
//如果不是响应信息或者响应信息为失败则打印
if(!(msg instanceof ResponseMessage rm) || rm.getResult() != 0)
if(! (msg instanceof MaintainMessage))
System.out.println(msg);
//下载状态
@ -296,18 +298,23 @@ public class RemoteService {
GalleryTask[] galleryTasks = dsm.getGalleryTasks();
for (GalleryTask galleryTask : galleryTasks) {
Gallery gallery = galleryMapper.selectGalleryByGid(galleryTask.getGid());
if(galleryTask.getStatus() == GalleryTask.DOWNLOAD_COMPLETE){
gallery.setStatus("下载完成");
gallery.setProceeding(galleryTask.getProceeding());
galleryMapper.updateGallery(gallery);
}else if(galleryTask.getProceeding() != 0){
gallery.setStatus("下载中");
gallery.setProceeding(galleryTask.getProceeding());
if(!gallery.getName().equals(galleryTask.getName()))
if(!gallery.getName().equals(galleryTask.getName()) && galleryTask.getName() != null)
gallery.setName(galleryTask.getName());
galleryMapper.updateGallery(gallery);
log.info(gallery.getName() + "下载进度:" + gallery.getProceeding() + "/" + gallery.getPages());
if(galleryTask.getStatus() == GalleryTask.COMPRESS_COMPLETE) {
gallery.setStatus("下载完成");
pushService.downloadComplete(gallery);
}
else if(galleryTask.getStatus() == GalleryTask.COMPRESSING)
gallery.setStatus("压缩中");
else if(galleryTask.getProceeding() != 0)
gallery.setStatus("下载中");
log.info(gallery.getName() + "下载进度:" + gallery.getProceeding() + "/" + gallery.getPages());
galleryMapper.updateGallery(gallery);
}
}
else if(msg instanceof ResponseMessage rsm)
@ -318,8 +325,11 @@ public class RemoteService {
@Override
public void channelUnregistered(ChannelHandlerContext ctx) {
System.out.println(ctx.channel());
System.out.println(channel);
if(ctx.channel() != null && ctx.channel().remoteAddress().toString().equals(channel.remoteAddress().toString())){
System.out.println("activate monitor thread, waiting for node back online");
pushService.storageNodeOffline();
monitor = new Thread(RemoteService.this::monitorFunc);
monitor.start();
}

View File

@ -0,0 +1,132 @@
package com.lion.lionwebsite.Service;
import cn.hutool.core.util.RandomUtil;
import com.lion.lionwebsite.Dao.SubMapper;
import com.lion.lionwebsite.Domain.SubBind;
import com.lion.lionwebsite.Domain.SubUpdateRecord;
import com.lion.lionwebsite.Util.CustomUtil;
import com.lion.lionwebsite.Util.FileDownload;
import com.lion.lionwebsite.Util.Response;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
@Service
public class SubService {
SubMapper subMapper;
byte[] vIndex;
String dbPath = "ip2region.xdb";
public SubService(SubMapper subMapper) {
this.subMapper = subMapper;
try {
vIndex = Searcher.loadVectorIndexFromFile(dbPath);
}catch (Exception e){
System.out.printf("failed to load vector index from `%s`: %s\n", dbPath, e);
}
}
public String insertSubBind(String user){
Response response = Response.generateResponse();
String key = RandomUtil.randomString(8);
while (subMapper.selectSubBindExist(key))
key = RandomUtil.randomString(8);
SubBind subBind = new SubBind(key, user);
subMapper.insertSubBind(subBind);
return response.success("添加成功").toJSONString();
}
public String resetKey(String user){
Response response = Response.generateResponse();
subMapper.deleteSubBind(user);
subMapper.deleteSubUpdateRecord(user);
String key = RandomUtil.randomString(8);
while (subMapper.selectSubBindExist(key))
key = RandomUtil.randomString(8);
SubBind subBind = new SubBind(key, user);
subMapper.insertSubBind(subBind);
return response.success().toJSONString();
}
public String selectAllSubBind(){
Response response = Response.generateResponse();
ArrayList<SubBind> subBinds = subMapper.selectAllSubBind();
return response.success(CustomUtil.objectMapper.valueToTree(subBinds)).toJSONString();
}
public String SelectAllSubUpdateRecord(){
Response response = Response.generateResponse();
ArrayList<SubUpdateRecord> subUpdateRecords = subMapper.selectAllSubUpdateRecord();
return response.success(CustomUtil.objectMapper.valueToTree(subUpdateRecords)).toJSONString();
}
public void updateSub(HttpServletResponse response, HttpServletRequest request, String client, String key){
if(key == null || client == null)
return;
SubBind subBind = subMapper.selectSubBind(key);
if(subBind == null)
return;
String ip;
if(request.getRemoteAddr().equals("127.0.0.1")){
ip = request.getHeader("X-Forwarded-For");
if(ip.contains(","))
ip = ip.split(",")[0].trim();
if(ip.contains(":"))
ip = ip.split(":")[0].trim();
} else
ip = request.getRemoteAddr();
String UA = request.getHeader("User-Agent");
if(UA == null)
return;
StringBuilder location = new StringBuilder();
Searcher searcher;
try {
searcher = Searcher.newWithVectorIndex(dbPath, vIndex);
String region = searcher.search(ip);
String[] temp = region.split("\\|");
for (int i = 2; i < temp.length; i++)
if(!temp[i].equals("0"))
location.append(temp[i]).append(" ");
} catch (Exception e) {
System.out.printf("failed to create vectorIndex cached searcher with `%s`: %s\n", dbPath, e);
return;
}
SubUpdateRecord subUpdateRecord = new SubUpdateRecord(0, subBind.getUser(), ip, UA, new Date(), location.toString().trim());
subMapper.insertSubUpdateRecord(subUpdateRecord);
if(subMapper.selectUpdateRecordCount(subBind.getUser()) > 10)
subMapper.deleteSubUpdateRecordById(subMapper.selectMinUpdateRecordId(subBind.getUser()));
switch (client){
case "v2" -> FileDownload.export(request, response, "sub/DouNaiV2ray.txt");
case "cat" -> FileDownload.export(request, response, "sub/DouNaiClash.txt");
default -> {
try{
response.getOutputStream().write("client error".getBytes(StandardCharsets.UTF_8));
} catch (IOException ignored){}
}
}
}
public String deleteSubBind(String user){
Response response = Response.generateResponse();
subMapper.deleteSubBind(user);
subMapper.deleteSubUpdateRecord(user);
return response.success("删除成功").toJSONString();
}
}

View File

@ -14,12 +14,14 @@ import java.util.HashMap;
@Service
public class TagService {
@Resource
TagMapper tagMapper;
@Resource
GalleryMapper galleryMapper;
public TagService(TagMapper tagMapper, GalleryMapper galleryMapper) {
this.tagMapper = tagMapper;
this.galleryMapper = galleryMapper;
}
public String createTag(String tagStr){
Response response = Response.generateResponse();

View File

@ -28,6 +28,13 @@ public class UserServiceImpl{
@Resource
TaskHandlerInterceptor taskHandlerInterceptor;
public UserServiceImpl(UserMapper userMapper, GalleryMapper galleryMapper, CollectMapper collectMapper, TaskHandlerInterceptor taskHandlerInterceptor) {
this.userMapper = userMapper;
this.galleryMapper = galleryMapper;
this.collectMapper = collectMapper;
this.taskHandlerInterceptor = taskHandlerInterceptor;
}
public String addAuthCode(String targetAuthCode, String people) {
Response response = Response.generateResponse();

View File

@ -1,5 +1,6 @@
package com.lion.lionwebsite.Util;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lion.lionwebsite.Domain.MaskDomain;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
@ -25,6 +26,7 @@ public class CustomUtil {
public static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static ObjectMapper objectMapper = new ObjectMapper();
private MaskDomain[] maskDomains;
public String restoreUrl(String link){
@ -63,14 +65,14 @@ public class CustomUtil {
String preNum = "";
String unit = "";
Pattern patternWithDot = Pattern.compile("(\\d+.\\d+)([A-Z]+)");
Pattern patternWithDot = Pattern.compile("(\\d+.\\d+)(([A-Z]|[a-z])+)");
Matcher matcherWithDot = patternWithDot.matcher(fileSizeString);
if(matcherWithDot.find()){
preNum = matcherWithDot.group(1);
unit = matcherWithDot.group(2);
}
else {
Pattern patternWithoutDot = Pattern.compile("(\\d+)([A-Z]+)");
Pattern patternWithoutDot = Pattern.compile("(\\d+)(([A-Z]|[a-z])+)");
Matcher matcherWithoutDot = patternWithoutDot.matcher(fileSizeString);
if (matcherWithoutDot.find()) {
preNum = matcherWithoutDot.group(1);
@ -82,9 +84,9 @@ public class CustomUtil {
return switch (unit) {
case "B" -> (long) num;
case "KB" -> (long) (ONE_KB * num);
case "MB" -> (long) (ONE_MB * num);
case "GB" -> (long) (ONE_GB * num);
case "KB", "KiB" -> (long) (ONE_KB * num);
case "MB", "MiB" -> (long) (ONE_MB * num);
case "GB", "GiB" -> (long) (ONE_GB * num);
default -> 0;
};
}
@ -105,6 +107,7 @@ public class CustomUtil {
public static short _findIdlePort(){
for(int i=20000; i<65535; i++){
try(ServerSocket ignored = new ServerSocket(i)){
ignored.close();
return (short) i;
}catch (IOException ignored) {
}

View File

@ -1,14 +1,13 @@
package com.lion.lionwebsite.Util;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
public class Response {
HashMap<String, String> result;
ObjectNode result;
public Response(){
result = new HashMap<>();
result = CustomUtil.objectMapper.createObjectNode();
}
public static Response generateResponse(){
@ -20,7 +19,7 @@ public class Response {
}
public String get(String key){
return result.get(key);
return result.get(key).asText();
}
public void setData(String data){
@ -31,13 +30,20 @@ public class Response {
this.result.put("result", result);
}
public void success(){
public Response success(){
setResult("success");
return this;
}
public void success(String result){
public Response success(String result){
success();
setData(result);
return this;
}
public Response success(JsonNode jsonNode){
success();
this.result.set("data", jsonNode);
return this;
}
public void failure(){
@ -50,7 +56,11 @@ public class Response {
}
public String getResult(){
return result.get("data");
return result.get("data").asText();
}
public boolean isSuccess(){
return result.get("result").asText().equals("success");
}
@ -80,7 +90,6 @@ public class Response {
}
public String toJSONString(){
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.valueToTree(result).toString();
return result.toString();
}
}

Binary file not shown.

View File

@ -2,6 +2,8 @@ server:
port: 8888
tomcat:
max-swallow-size: 10000MB
http2:
enabled: true
spring:
datasource:
@ -26,15 +28,16 @@ personal-service:
StoragePath: /storage/
gallery-manage-service:
target-path: /storage/gallery/
target-path: /root/gallery/
cache-size: 100
remote-service:
ip: 5.255.110.45
local-service:
fires: https://api.dler.io/sub?target=clash&new_name=true&url=https%3A%2F%2Ffast.losadhwselfff2332dasd.xyz%2Flink%2Fz0pfwyTvC5naXkbb%3Fclash%3D1&insert=false&config=https%3A%2F%2Fraw.githubusercontent.com%2FACL4SSR%2FACL4SSR%2Fmaster%2FClash%2Fconfig%2FACL4SSR_Online.ini
DouNaiClash: https://aaaa.gay/link/A5CXg2cJATerEEoe?client=clashv2
DouNaiV2ray: https://aaaa.gay/link/A5CXg2cJATerEEoe?client=v2
DouNaiClash: https://aaaa.gay/link/X7zEqkIx5gtIGugO?client=clashmeta
DouNaiV2ray: https://aaaa.gay/link/X7zEqkIx5gtIGugO?client=v2
bot:
token: 5222939329:AAHa6l9ZuVVdNSDLPI_H-c8O_VgeOEw5plA

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,8 +6,8 @@
<link href="/reset.css" type="text/css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lion</title>
<script type="module" src="/index/index.js"></script>
<link rel="stylesheet" href="/index/index.css">
<script type="module" src="/asserts/index/index.js"></script>
<link rel="stylesheet" href="/asserts/index/index.css">
</head>
<body>
<div id="app"></div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,10 +4,10 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Vite + Vue</title>
<title>Lion</title>
<meta name="apple-mobile-web-app-capable" content="yes">
<script type="module" crossorigin src="/mobile/index.js"></script>
<link rel="stylesheet" href="/mobile/index.css">
<script type="module" crossorigin src="/asserts/mobile/index.js"></script>
<link rel="stylesheet" href="/asserts/mobile/index.css">
</head>
<body>
<div id="app"></div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,8 +5,8 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lion</title>
<script type="module" crossorigin src="/self/index.js"></script>
<link rel="stylesheet" href="/self/index.css">
<script type="module" crossorigin src="/asserts/self/index.js"></script>
<link rel="stylesheet" href="/asserts/self/index.css">
</head>
<body>
<div id="app"></div>

View File

@ -5,8 +5,8 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Personal</title>
<script type="module" crossorigin src="/self/mobile.js"></script>
<link rel="stylesheet" href="/self/mobile.css">
<script type="module" crossorigin src="/asserts/self/mobile.js"></script>
<link rel="stylesheet" href="/asserts/self/mobile.css">
</head>
<body>
<div id="app"></div>