This commit is contained in:
wangli 2026-01-21 00:43:35 +08:00
commit 97d15b395c
13 changed files with 546 additions and 0 deletions

53
.gitignore Normal file
View File

@ -0,0 +1,53 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
WorkflowCoreService.java
WorkflowManageService.java
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
application-local.yml
*.log
rebel.xml
.flattened-pom.xml
.DS_Store
/.idea/.gitignore
/logs/backend-java.log
/.idea/compiler.xml
/.idea/encodings.xml
/.idea/jarRepositories.xml
/.idea/misc.xml
/.idea/modules.xml
/.idea/inspectionProfiles/Project_Default.xml
/.idea/vcs.xml
/xianyu-core/xianyu-core.iml
/xianyu-server/xianyu-server.iml

15
ProjectStructure.md Normal file
View File

@ -0,0 +1,15 @@
## xianyu-api
> 本系统对外开放的 API 接口,不是将前端的接口暴露在这里面,而是对三方系统的。
> 可以认为是 spring-boot-starter 模块,第三对接本系统的。
## xianyu-core
> 本系统的核心,包含数据库
> 部分业务逻辑
## xianyu-goofish
> 包含调用闲鱼网页版的 API。
> 与闲鱼的 websocket 连接处理。
## xianyu-server
> 启动入口,前端项目的 web 接口。

150
pom.xml Normal file
View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.1</version>
</parent>
<groupId>top.biwin</groupId>
<artifactId>xianyu-freedom</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<name>Xianyu Freedom</name>
<description>Xianyu Management System</description>
<modules>
<module>xianyu-api</module>
<module>xianyu-core</module>
<module>xianyu-server</module>
<module>xianyu-goofish</module>
</modules>
<properties>
<revision>0.0.1-SNAPSHOT</revision>
<lombok.version>1.18.30</lombok.version>
<hutool.version>5.8.25</hutool.version>
<fastjson.version>2.0.43</fastjson.version>
<guava.version>33.0.0-jre</guava.version>
<jackson.version>0.9.6</jackson.version>
<okhttp.version>4.12.0</okhttp.version>
<zxing.version>3.5.3</zxing.version>
<playwright.version>1.49.0</playwright.version>
<sqlite-jdbc.version>3.44.1.0</sqlite-jdbc.version>
<hibernate.version>6.4.1.Final</hibernate.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>${sqlite-jdbc.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-community-dialects</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>${playwright.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>jackson-dataformat-msgpack</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- OkHttp for robust HTTP requests -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<!-- ZXing for QR Code generation -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing.version}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>${zxing.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
<updatePomFile>true</updatePomFile>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

20
xianyu-api/pom.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.biwin</groupId>
<artifactId>xianyu-freedom</artifactId>
<version>${revision}</version>
</parent>
<artifactId>xianyu-api</artifactId>
<properties>
<maven.compiler.source>25</maven.compiler.source>
<maven.compiler.target>25</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

36
xianyu-core/pom.xml Normal file
View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.biwin</groupId>
<artifactId>xianyu-freedom</artifactId>
<version>${revision}</version>
</parent>
<artifactId>xianyu-core</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-community-dialects</artifactId>
</dependency>
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>jackson-dataformat-msgpack</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,50 @@
package top.biwin.xianyu.core.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
/**
* TODO
*
* @author wangli
* @since 2026-01-21 00:00
*/
@Data
@Entity
@Table(name = "admin_user")
public class AdminUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false, unique = true)
private String email;
@Column(name = "password_hash", nullable = false)
private String passwordHash;
@Column(name = "is_active")
@ColumnDefault("true")
private Boolean isActive = true;
@CreationTimestamp
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}

View File

@ -0,0 +1,71 @@
package top.biwin.xianyu.core.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
/**
* TODO
*
* @author wangli
* @since 2026-01-21 00:27
*/
@Data
@Entity
@Table(name = "goofish_account")
public class GoofishAccount {
@Id
private Long id;
@Column(nullable = false, length = 10000) // cookies can be long
private String value;
@Column(name = "user_id", nullable = false)
@JsonProperty("user_id")
private Long userId;
@Column(name = "auto_confirm")
@ColumnDefault("1")
@JsonProperty("auto_confirm")
private Integer autoConfirm = 1;
@ColumnDefault("''")
private String remark;
@Column(name = "pause_duration")
@ColumnDefault("10")
@JsonProperty("pause_duration")
private Integer pauseDuration = 10;
@ColumnDefault("''")
private String username;
@ColumnDefault("''")
private String password;
@Column(name = "show_browser")
@ColumnDefault("0")
@JsonProperty("show_browser")
private Integer showBrowser = 0;
@Column(name = "enabled")
@ColumnDefault("true")
private Boolean enabled = true;
@CreationTimestamp
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}

View File

@ -0,0 +1,29 @@
package top.biwin.xianyu.core.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "system_settings")
public class SystemSetting {
@Id
@Column(name = "key", unique = true, nullable = false)
private String key;
@Column(nullable = false)
private String value;
private String description;
@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}

14
xianyu-goofish/pom.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.biwin</groupId>
<artifactId>xianyu-freedom</artifactId>
<version>${revision}</version>
</parent>
<artifactId>xianyu-goofish</artifactId>
</project>

31
xianyu-server/pom.xml Normal file
View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.biwin</groupId>
<artifactId>xianyu-freedom</artifactId>
<version>${revision}</version>
</parent>
<artifactId>xianyu-server</artifactId>
<dependencies>
<dependency>
<groupId>top.biwin</groupId>
<artifactId>xianyu-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,17 @@
package top.biwin.xinayu.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* TODO
*
* @author wangli
* @since 2026-01-20 23:51
*/
@SpringBootApplication
public class XianyuFreedomApplication {
public static void main(String[] args) {
SpringApplication.run(XianyuFreedomApplication.class, args);
}
}

View File

@ -0,0 +1,18 @@
-- 系统默认账号
INSERT OR IGNORE INTO users (username, email, password_hash) VALUES ('admin', 'admin@localhost', '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92');
-- 系统默认设置
INSERT OR IGNORE INTO system_settings (key, value, description)
VALUES ('init_system', 'false', '是否初始化'),
('theme_color', 'blue', '主题颜色'),
('registration_enabled', 'true', '是否开启用户注册'),
('show_default_login_info', 'true', '是否显示默认登录信息'),
('login_captcha_enabled', 'true', '登录滑动验证码开关'),
('smtp_server', '', 'SMTP服务器地址'),
('smtp_port', '587', 'SMTP端口'),
('smtp_user', '', 'SMTP登录用户名发件邮箱'),
('smtp_password', '', 'SMTP登录密码/授权码'),
('smtp_from', '', '发件人显示名(留空则使用用户名)'),
('smtp_use_tls', 'true', '是否启用TLS'),
('smtp_use_ssl', 'false', '是否启用SSL'),
('qq_reply_secret_key', 'xianyu_qq_reply_2024', 'QQ回复消息API秘钥');

View File

@ -0,0 +1,42 @@
app:
ddl-auto: update # valid values: none, validate, update, create, create-drop
server:
port: 8080
spring:
application:
name: xianyu-free
datasource:
driver-class-name: org.sqlite.JDBC
url: jdbc:sqlite:./db/xianyu_data.db
username:
password:
sql:
init:
mode: never
jpa:
database-platform: org.hibernate.community.dialect.SQLiteDialect
hibernate:
ddl-auto: ${app.ddl-auto:update}
show-sql: true # Set to false to disable SQL logging
properties:
hibernate:
format_sql: true # Set to false to disable SQL formatting
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
logging:
level:
root: INFO
com.xianyu.autoreply: DEBUG
org.hibernate.SQL: INFO # Ensure Hibernate SQL logging is not set to DEBUG/TRACE
org.hibernate.type.descriptor.sql: INFO # Ensure Hibernate parameter logging is not set to DEBUG/TRACE
file:
name: logs/backend-java.log