# Campus Used Book Trading System C/S architecture: JavaFX client → RESTful API → Spring Boot server → MySQL. ## Tech stack | Layer | Technology | Version | |-------|-----------|---------| | Client | JavaFX + FXML + Scene Builder | 23.0.2 | | Client HTTP | JDK `java.net.http.HttpClient` | built-in | | JSON | Jackson (`jackson-databind` + `jackson-datatype-jsr310`) | 2.17.3 | | Server | Spring Boot Web | 3.4.4 | | ORM | MyBatis-Plus (`mybatis-plus-spring-boot3-starter`) | 3.5.9 | | Database | MySQL 8.0+ (connector 8.4.0) | | | Build | Maven (no wrapper, requires system `mvn`) | 3.9+ | | Java | corretto-23 (`JAVA_HOME` must target JDK 23) | | | Lombok | 1.18.36 (annotation processor configured in parent POM) | | **Must compile with JDK 23.** The system JDK may be newer; always set `JAVA_HOME`: ```sh JAVA_HOME=/path/to/corretto-23.0.2 mvn clean install ``` On this machine: `JAVA_HOME=/home/yangyi/.jdks/corretto-23.0.2` ## Modules ``` common/ space.anyi.common — entities, DTOs (LoginRequest, RegisterRequest, R, PageResult), enums server/ space.anyi.server — Spring Boot app (controllers → services → MyBatis-Plus mappers) client/ space.anyi.client — JavaFX app (App.java entry, FXML views, controllers, HTTP service layer) ``` Dependency: `server → common`, `client → common`. Client and server communicate only via HTTP; no direct dependency. ## Build & run ```sh # Full build (use JDK 23!) JAVA_HOME=/path/to/corretto-23 mvn clean install # Build single module (common must be installed first for server/client) mvn install -pl common mvn compile -pl server mvn compile -pl client # Run server mvn spring-boot:run -pl server # Run client mvn javafx:run -pl client # via plugin # or directly run space.anyi.client.UIApplication main class ``` ## Database - MySQL 8.0+, database `campus_book_trade`, charset `utf8mb4` - Schema: `sql/campus_book_trade.sql` (tables: `user`, `book`, `transaction_record`) - Default credentials: `root`/`root` on `localhost:3306` - Config: `server/src/main/resources/application.yml` - Run SQL directly against local instance before starting server ## Architecture ### Server REST API All under `/api`, unified response `R` = `{code, message, data}`. Port 8080. | Method | Path | Purpose | |--------|------|---------| | POST | `/api/user/login` | Login | | POST | `/api/user/register` | Register | | GET | `/api/user` | List all users (paginated: `?page=&size=`) | | GET | `/api/user/{id}` | Get user | | PUT | `/api/user/{id}` | Update user | | DELETE | `/api/user/{id}` | Delete user | | GET | `/api/book?keyword=&category=&page=&size=` | Search books (paginated) | | GET | `/api/book/all` | List all books | | GET | `/api/book/{id}` | Book detail | | GET | `/api/book/my?sellerId=` | Seller's own books | | POST | `/api/book` | Create listing | | PUT | `/api/book/{id}` | Update book | | DELETE | `/api/book/{id}` | Delete book | | POST | `/api/transaction` | Purchase | | GET | `/api/transaction` | List all transactions (paginated) | | GET | `/api/transaction/{id}` | Transaction detail | | GET | `/api/transaction/user/{userId}` | User's transactions | | PUT | `/api/transaction/{id}` | Update transaction | | DELETE | `/api/transaction/{id}` | Delete transaction | | GET | `/api/statistics/summary` | Total transaction amount & count | | GET | `/api/statistics/top-departments` | Top 3 departments by sales | | GET | `/api/statistics/top-books` | Top 5 best-selling books | | GET | `/api/statistics/discount-rates` | Avg discount rate by department | ### Client JavaFX views ``` login.fxml → LoginController register.fxml → RegisterController main.fxml → MainController (TabPane with 6 tabs: Browse, Transactions, Profile, Seller Dashboard, Statistics, Admin) ``` FXML location: `client/src/main/resources/fxml/*.fxml` ### Identity Simplified auth: login stores `User` object in `LoginUserHolder` (in-memory). Client sends `userId` in request body/params. No JWT. ### Key packages ``` server/ config/WebConfig.java — CORS config controller/*Controller.java — REST endpoints service/*Service.java — business logic service/impl/*ServiceImpl.java mapper/*Mapper.java — MyBatis-Plus BaseMapper client/ App.java — JavaFX entry, scene switching controller/*Controller.java — JavaFX controllers service/*Service.java — HTTP call wrappers util/HttpClientUtil.java — singleton HttpClient + Jackson JSON util/LoginUserHolder.java — current user session resources/fxml/*.fxml — Scene Builder layouts resources/css/style.css ``` ## Notes - No test framework configured yet - No CI, no formatter, no linter - IntelliJ IDEA project (`.idea/` tracked, configured for JDK 23) - Lombok `@Data` on entities/DTOs; annotation processor configured in parent POM's `maven-compiler-plugin` - MyBatis-Plus entity annotations (`@TableName`, `@TableId`, `@TableField`) live in `common` entities alongside Lombok; the `mybatis-plus-spring-boot3-starter` dependency brings in the annotation JAR - `PageResult` DTO wraps MyBatis-Plus `IPage` for clean Jackson serialization across the HTTP boundary - Client uses BootstrapFX (`org.kordamp.bootstrapfx:bootstrapfx-core:0.4.0`) for UI styling