基于SpringBoot的模拟证券交易系统

模拟证券交易系统

项目概述

本项目是一个基于 Java 的模拟证券交易系统,主要功能包括用户注册、登录、账户管理、股票查询、股票买卖以及交易记录查询等操作。系统采用 Spring Boot 实现后端,MySQL 作为数据存储,前端使用 HTML 和 JavaScript 提供简单交互。


主要功能模块

1. 用户注册与登录

  • 用户可以注册一个账户,包括用户名、密码、初始余额。
  • 用户登录后可访问其账户信息和进行股票交易操作。

2. 股票查询

  • 查询当前市场上的股票信息,包括股票代码、名称、当前价格等。

3. 股票买卖

  • 用户可指定股票代码、数量进行买入或卖出操作。
  • 买入操作会扣减用户账户余额并增加持有的股票数量。
  • 卖出操作会减少持有的股票数量并增加账户余额。

4. 交易记录查询

  • 用户可查看自己所有的股票交易记录,包括买入和卖出的详细信息。

数据库表设计

数据库表

-- 用户表
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    balance DOUBLE DEFAULT 0
);

-- 股票表
CREATE TABLE stocks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    stock_code VARCHAR(10) NOT NULL UNIQUE,
    stock_name VARCHAR(50) NOT NULL,
    current_price DOUBLE NOT NULL
);

-- 用户持仓表
CREATE TABLE user_stocks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    stock_id INT NOT NULL,
    quantity INT DEFAULT 0,
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (stock_id) REFERENCES stocks(id)
);

-- 交易记录表
CREATE TABLE transactions (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    stock_id INT NOT NULL,
    transaction_type ENUM('BUY', 'SELL') NOT NULL,
    quantity INT NOT NULL,
    price_per_stock DOUBLE NOT NULL,
    total_price DOUBLE NOT NULL,
    transaction_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (stock_id) REFERENCES stocks(id)
);

后端代码实现

1. 用户注册与登录

用户实体类
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(nullable = false, unique = true)
    private String username;

    @Column(nullable = false)
    private String password;

    private Double balance = 0.0;

    // Getters and Setters
}
用户控制器
@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @PostMapping("/register")
    public ResponseEntity<String> register(@RequestBody User user) {
        if (userRepository.findByUsername(user.getUsername()).isPresent()) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Username already exists!");
        }
        user.setPassword(BCrypt.hashpw(user.getPassword(), BCrypt.gensalt()));
        userRepository.save(user);
        return ResponseEntity.ok("Registration successful!");
    }

    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestParam String username, @RequestParam String password) {
        Optional<User> userOpt = userRepository.findByUsername(username);
        if (userOpt.isEmpty() || !BCrypt.checkpw(password, userOpt.get().getPassword())) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
        }
        return ResponseEntity.ok("Login successful!");
    }
}

2. 股票查询

股票实体类
@Entity
@Table(name = "stocks")
public class Stock {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(nullable = false, unique = true)
    private String stockCode;

    @Column(nullable = false)
    private String stockName;

    @Column(nullable = false)
    private Double currentPrice;

    // Getters and Setters
}
股票控制器
@RestController
@RequestMapping("/api/stocks")
public class StockController {

    @Autowired
    private StockRepository stockRepository;

    @GetMapping("/all")
    public List<Stock> getAllStocks() {
        return stockRepository.findAll();
    }
}

3. 股票买卖

交易记录实体类
@Entity
@Table(name = "transactions")
public class Transaction {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    @ManyToOne
    @JoinColumn(name = "stock_id", nullable = false)
    private Stock stock;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private TransactionType transactionType;

    @Column(nullable = false)
    private Integer quantity;

    @Column(nullable = false)
    private Double pricePerStock;

    @Column(nullable = false)
    private Double totalPrice;

    @Column(nullable = false, updatable = false)
    private LocalDateTime transactionTime = LocalDateTime.now();

    // Getters and Setters
}

public enum TransactionType {
    BUY, SELL
}
股票交易控制器
@RestController
@RequestMapping("/api/trade")
public class TradeController {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private StockRepository stockRepository;

    @Autowired
    private TransactionRepository transactionRepository;

    @PostMapping("/buy")
    public ResponseEntity<String> buyStock(@RequestParam String username,
                                            @RequestParam String stockCode,
                                            @RequestParam Integer quantity) {
        Optional<User> userOpt = userRepository.findByUsername(username);
        Optional<Stock> stockOpt = stockRepository.findByStockCode(stockCode);

        if (userOpt.isEmpty() || stockOpt.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User or stock not found");
        }

        User user = userOpt.get();
        Stock stock = stockOpt.get();

        double totalPrice = stock.getCurrentPrice() * quantity;
        if (user.getBalance() < totalPrice) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Insufficient balance");
        }

        user.setBalance(user.getBalance() - totalPrice);
        Transaction transaction = new Transaction();
        transaction.setUser(user);
        transaction.setStock(stock);
        transaction.setTransactionType(TransactionType.BUY);
        transaction.setQuantity(quantity);
        transaction.setPricePerStock(stock.getCurrentPrice());
        transaction.setTotalPrice(totalPrice);

        transactionRepository.save(transaction);
        userRepository.save(user);

        return ResponseEntity.ok("Stock purchased successfully!");
    }
}

总结

本文展示了一个模拟证券交易系统的基本实现,涵盖用户注册登录、股票查询、买卖交易及交易记录的完整功能。开发中采用 Spring Boot 构建后端,结合 MySQL 实现数据存储。用户可通过接口完成股票交易流程,为构建真实证券系统提供参考。


用原生Java实现的测试demo

以下是一个使用原生 Java 实现的简单证券交易系统,支持用户注册、股票查询和买卖交易。

一、基础类设计

用户类

public class User {
    private String username;
    private String password;
    private double balance;

    public User(String username, String password, double balance) {
        this.username = username;
        this.password = password;
        this.balance = balance;
    }

    public String getUsername() {
        return username;
    }

    public boolean authenticate(String password) {
        return this.password.equals(password);
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }
}

股票类

public class Stock {
    private String code;
    private String name;
    private double price;

    public Stock(String code, String name, double price) {
        this.code = code;
        this.name = name;
        this.price = price;
    }

    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

二、核心逻辑实现

用户注册和登录

import java.util.HashMap;
import java.util.Scanner;

public class SecuritiesSystem {
    private static HashMap<String, User> users = new HashMap<>();
    private static HashMap<String, Stock> stocks = new HashMap<>();

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("欢迎进入模拟证券交易系统");

        // 初始化一些股票
        stocks.put("AAPL", new Stock("AAPL", "Apple Inc.", 150.0));
        stocks.put("TSLA", new Stock("TSLA", "Tesla Inc.", 700.0));

        while (true) {
            System.out.println("1. 注册\n2. 登录\n3. 退出");
            int choice = scanner.nextInt();

            if (choice == 1) {
                register(scanner);
            } else if (choice == 2) {
                login(scanner);
            } else {
                break;
            }
        }
        scanner.close();
    }

    private static void register(Scanner scanner) {
        System.out.print("请输入用户名: ");
        String username = scanner.next();
        System.out.print("请输入密码: ");
        String password = scanner.next();
        System.out.print("请输入初始余额: ");
        double balance = scanner.nextDouble();

        if (users.containsKey(username)) {
            System.out.println("用户名已存在!");
        } else {
            users.put(username, new User(username, password, balance));
            System.out.println("注册成功!");
        }
    }

    private static void login(Scanner scanner) {
        System.out.print("请输入用户名: ");
        String username = scanner.next();
        System.out.print("请输入密码: ");
        String password = scanner.next();

        User user = users.get(username);
        if (user != null && user.authenticate(password)) {
            System.out.println("登录成功!余额: " + user.getBalance());
            tradeMenu(scanner, user);
        } else {
            System.out.println("用户名或密码错误!");
        }
    }

    private static void tradeMenu(Scanner scanner, User user) {
        while (true) {
            System.out.println("1. 查看股票\n2. 买入股票\n3. 卖出股票\n4. 退出");
            int choice = scanner.nextInt();

            if (choice == 1) {
                showStocks();
            } else if (choice == 2) {
                buyStock(scanner, user);
            } else if (choice == 3) {
                sellStock(scanner, user);
            } else {
                break;
            }
        }
    }

    private static void showStocks() {
        System.out.println("当前市场股票信息:");
        for (Stock stock : stocks.values()) {
            System.out.println(stock.getCode() + " - " + stock.getName() + ", 当前价格: " + stock.getPrice());
        }
    }

    private static void buyStock(Scanner scanner, User user) {
        System.out.print("请输入股票代码: ");
        String code = scanner.next();
        System.out.print("请输入购买数量: ");
        int quantity = scanner.nextInt();

        Stock stock = stocks.get(code);
        if (stock != null) {
            double totalCost = stock.getPrice() * quantity;
            if (user.getBalance() >= totalCost) {
                user.setBalance(user.getBalance() - totalCost);
                System.out.println("购买成功!总花费: " + totalCost + ", 余额: " + user.getBalance());
            } else {
                System.out.println("余额不足,购买失败!");
            }
        } else {
            System.out.println("股票代码无效!");
        }
    }

    private static void sellStock(Scanner scanner, User user) {
        System.out.print("请输入股票代码: ");
        String code = scanner.next();
        System.out.print("请输入卖出数量: ");
        int quantity = scanner.nextInt();

        Stock stock = stocks.get(code);
        if (stock != null) {
            double totalRevenue = stock.getPrice() * quantity;
            user.setBalance(user.getBalance() + totalRevenue);
            System.out.println("卖出成功!总收益: " + totalRevenue + ", 余额: " + user.getBalance());
        } else {
            System.out.println("股票代码无效!");
        }
    }
}

你可能感兴趣的:(#,一,SpringBoot,spring,boot,后端,java)