Compare commits
6 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
13b7590288 | 5 months ago |
|
|
c0b0221bdf | 5 months ago |
|
|
af66ca2908 | 5 months ago |
|
|
c5f534097c | 5 months ago |
|
|
9a1fd27ea3 | 5 months ago |
|
|
a513810fbc | 5 months ago |
Binary file not shown.
Binary file not shown.
@ -1,29 +0,0 @@
|
|||||||
### IntelliJ IDEA ###
|
|
||||||
out/
|
|
||||||
!**/src/main/**/out/
|
|
||||||
!**/src/test/**/out/
|
|
||||||
|
|
||||||
### Eclipse ###
|
|
||||||
.apt_generated
|
|
||||||
.classpath
|
|
||||||
.factorypath
|
|
||||||
.project
|
|
||||||
.settings
|
|
||||||
.springBeans
|
|
||||||
.sts4-cache
|
|
||||||
bin/
|
|
||||||
!**/src/main/**/bin/
|
|
||||||
!**/src/test/**/bin/
|
|
||||||
|
|
||||||
### NetBeans ###
|
|
||||||
/nbproject/private/
|
|
||||||
/nbbuild/
|
|
||||||
/dist/
|
|
||||||
/nbdist/
|
|
||||||
/.nb-gradle/
|
|
||||||
|
|
||||||
### VS Code ###
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
### Mac OS ###
|
|
||||||
.DS_Store
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# 基于编辑器的 HTTP 客户端请求
|
|
||||||
/httpRequests/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/demo/demo.iml" filepath="$PROJECT_DIR$/demo/demo.iml" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/project.iml" filepath="$PROJECT_DIR$/project.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Palette2">
|
|
||||||
<group name="Swing">
|
|
||||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
|
||||||
<initial-values>
|
|
||||||
<property name="text" value="Button" />
|
|
||||||
</initial-values>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
|
||||||
<initial-values>
|
|
||||||
<property name="text" value="RadioButton" />
|
|
||||||
</initial-values>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
|
||||||
<initial-values>
|
|
||||||
<property name="text" value="CheckBox" />
|
|
||||||
</initial-values>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
|
||||||
<initial-values>
|
|
||||||
<property name="text" value="Label" />
|
|
||||||
</initial-values>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
|
||||||
<preferred-size width="150" height="-1" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
|
||||||
<preferred-size width="150" height="-1" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
|
||||||
<preferred-size width="150" height="-1" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
|
||||||
<preferred-size width="200" height="200" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
|
||||||
<preferred-size width="200" height="200" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
|
||||||
<preferred-size width="-1" height="20" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
|
||||||
</item>
|
|
||||||
</group>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="JAVA_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
public class Main {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
System.out.println("Hello world!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
// main/Main.java (程序入口)
|
|
||||||
package main;
|
|
||||||
|
|
||||||
import view.MainFrame;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
// 仅负责启动主窗口,所有界面逻辑在 view 包中实现
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
MainFrame mainFrame = new MainFrame(); // 这里使用的是 view.MainFrame
|
|
||||||
mainFrame.setVisible(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package model;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Order {
|
|
||||||
private final int id;
|
|
||||||
private final Date orderDate;
|
|
||||||
private final List<OrderItem> orderItems;
|
|
||||||
private final double totalAmount;
|
|
||||||
|
|
||||||
public Order(int id, Date orderDate, List<OrderItem> orderItems, double totalAmount) {
|
|
||||||
this.id = id;
|
|
||||||
this.orderDate = orderDate;
|
|
||||||
this.orderItems = orderItems;
|
|
||||||
this.totalAmount = totalAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getter方法
|
|
||||||
public int getId() { return id; }
|
|
||||||
public Date getOrderDate() { return orderDate; }
|
|
||||||
public List<OrderItem> getOrderItems() { return orderItems; }
|
|
||||||
public double getTotalAmount() { return totalAmount; }
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package model;
|
|
||||||
|
|
||||||
public class OrderItem {
|
|
||||||
private final int productId;
|
|
||||||
private final String productName;
|
|
||||||
private final double price;
|
|
||||||
private final int quantity;
|
|
||||||
private final double subtotal;
|
|
||||||
|
|
||||||
public OrderItem(int productId, String productName, double price, int quantity, double subtotal) {
|
|
||||||
this.productId = productId;
|
|
||||||
this.productName = productName;
|
|
||||||
this.price = price;
|
|
||||||
this.quantity = quantity;
|
|
||||||
this.subtotal = subtotal;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getter方法
|
|
||||||
public int getProductId() { return productId; }
|
|
||||||
public String getProductName() { return productName; }
|
|
||||||
public double getPrice() { return price; }
|
|
||||||
public int getQuantity() { return quantity; }
|
|
||||||
public double getSubtotal() { return subtotal; }
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
package model;
|
|
||||||
|
|
||||||
public class Product {
|
|
||||||
private int id;
|
|
||||||
private String name;
|
|
||||||
private double price;
|
|
||||||
private String description;
|
|
||||||
private int stock; // 库存数量
|
|
||||||
|
|
||||||
// 构造函数
|
|
||||||
public Product(int id, String name, double price, String description, int stock) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.price = price;
|
|
||||||
this.description = description;
|
|
||||||
this.stock = stock;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getter 和 Setter 方法
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getPrice() {
|
|
||||||
return price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStock() {
|
|
||||||
return stock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStock(int stock) {
|
|
||||||
this.stock = stock;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其他方法...
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
package model;
|
|
||||||
|
|
||||||
public class test {
|
|
||||||
}
|
|
||||||
@ -1,96 +0,0 @@
|
|||||||
package service;
|
|
||||||
|
|
||||||
import model.CartItem;
|
|
||||||
import model.Order;
|
|
||||||
import model.OrderItem;
|
|
||||||
import model.Product;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class OrderService {
|
|
||||||
private final List<Order> orders = new ArrayList<>();
|
|
||||||
private final AtomicInteger orderIdCounter = new AtomicInteger(1); // 订单ID计数器
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建新订单
|
|
||||||
* @param cartItems 购物车商品列表
|
|
||||||
* @return 创建的订单
|
|
||||||
* @throws IllegalArgumentException 如果购物车为空
|
|
||||||
* @throws IllegalStateException 如果库存不足
|
|
||||||
*/
|
|
||||||
public Order createOrder(List<CartItem> cartItems) {
|
|
||||||
if (cartItems == null || cartItems.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("购物车为空,无法创建订单");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 检查所有商品库存是否充足
|
|
||||||
for (CartItem item : cartItems) {
|
|
||||||
Product product = item.getProduct();
|
|
||||||
if (product.getStock() < item.getQuantity()) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
String.format("商品 '%s' 库存不足,当前库存: %d, 需要: %d",
|
|
||||||
product.getName(), product.getStock(), item.getQuantity()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 扣减库存
|
|
||||||
for (CartItem item : cartItems) {
|
|
||||||
Product product = item.getProduct();
|
|
||||||
product.setStock(product.getStock() - item.getQuantity());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 创建订单项目列表
|
|
||||||
List<OrderItem> orderItems = new ArrayList<>();
|
|
||||||
for (CartItem cartItem : cartItems) {
|
|
||||||
orderItems.add(new OrderItem(
|
|
||||||
cartItem.getProduct().getId(),
|
|
||||||
cartItem.getProduct().getName(),
|
|
||||||
cartItem.getProduct().getPrice(),
|
|
||||||
cartItem.getQuantity(),
|
|
||||||
cartItem.getSubtotal()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 创建新订单
|
|
||||||
int orderId = orderIdCounter.getAndIncrement();
|
|
||||||
Order newOrder = new Order(
|
|
||||||
orderId,
|
|
||||||
new Date(), // 订单创建时间
|
|
||||||
orderItems,
|
|
||||||
calculateTotal(orderItems) // 计算订单总金额
|
|
||||||
);
|
|
||||||
|
|
||||||
// 5. 保存订单
|
|
||||||
orders.add(newOrder);
|
|
||||||
return newOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算订单总金额
|
|
||||||
*/
|
|
||||||
private double calculateTotal(List<OrderItem> orderItems) {
|
|
||||||
return orderItems.stream()
|
|
||||||
.mapToDouble(OrderItem::getSubtotal)
|
|
||||||
.sum();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有订单
|
|
||||||
*/
|
|
||||||
public List<Order> getAllOrders() {
|
|
||||||
return new ArrayList<>(orders); // 返回副本,防止外部修改
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据ID获取订单
|
|
||||||
*/
|
|
||||||
public Order getOrderById(int orderId) {
|
|
||||||
return orders.stream()
|
|
||||||
.filter(order -> order.getId() == orderId)
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
package service;
|
|
||||||
|
|
||||||
import model.Product;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ProductService {
|
|
||||||
private final List<Product> products;
|
|
||||||
|
|
||||||
public ProductService() {
|
|
||||||
this.products = new ArrayList<>();
|
|
||||||
initializeSampleProducts();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeSampleProducts() {
|
|
||||||
// 初始化一些示例商品
|
|
||||||
addProduct(new Product(1, "MacBook Pro", 12999.00, "13英寸 M1芯片 8核CPU 8核GPU", 50));
|
|
||||||
addProduct(new Product(2, "iPhone 13", 5999.00, "6.1英寸 Super Retina XDR 显示屏", 100));
|
|
||||||
addProduct(new Product(3, "AirPods Pro", 1999.00, "主动降噪无线蓝牙耳机", 200));
|
|
||||||
addProduct(new Product(4, "iPad Air", 4799.00, "10.9英寸 Liquid 视网膜显示屏", 80));
|
|
||||||
addProduct(new Product(5, "Apple Watch Series 7", 2999.00, "45毫米 GPS 款", 120));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Product> getAllProducts() {
|
|
||||||
return new ArrayList<>(products); // 返回副本以避免外部修改
|
|
||||||
}
|
|
||||||
|
|
||||||
public Product getProductById(int id) {
|
|
||||||
return products.stream()
|
|
||||||
.filter(p -> p.getId() == id)
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addProduct(Product product) {
|
|
||||||
if (product != null && !products.contains(product)) {
|
|
||||||
products.add(product);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean updateProductStock(int productId, int quantityChange) {
|
|
||||||
Product product = getProductById(productId);
|
|
||||||
if (product != null) {
|
|
||||||
int newStock = product.getStock() + quantityChange;
|
|
||||||
if (newStock >= 0) {
|
|
||||||
product.setStock(newStock);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,191 +0,0 @@
|
|||||||
package view;
|
|
||||||
|
|
||||||
import model.CartItem;
|
|
||||||
import model.Product;
|
|
||||||
import service.OrderService;
|
|
||||||
import service.ShoppingCartService;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CartPanel extends JPanel {
|
|
||||||
private final ShoppingCartService cartService;
|
|
||||||
private final OrderService orderService;
|
|
||||||
private JTable cartTable;
|
|
||||||
private JButton removeButton;
|
|
||||||
private JButton checkoutButton;
|
|
||||||
private JLabel totalLabel;
|
|
||||||
private MainFrame mainFrame;
|
|
||||||
|
|
||||||
public CartPanel(ShoppingCartService cartService, OrderService orderService, MainFrame mainFrame) {
|
|
||||||
this.cartService = cartService;
|
|
||||||
this.orderService = orderService;
|
|
||||||
this.mainFrame = mainFrame;
|
|
||||||
initComponents();
|
|
||||||
layoutComponents(); // 调用布局方法(之前缺失实现)
|
|
||||||
updateCartDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ 确保此方法是 public 的
|
|
||||||
public void updateCartDisplay() {
|
|
||||||
((CartTableModel) cartTable.getModel()).setCartItems(cartService.getCartItems());
|
|
||||||
totalLabel.setText(String.format("总金额: ¥%.2f", cartService.getTotalAmount()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initComponents() {
|
|
||||||
cartTable = new JTable(new CartTableModel());
|
|
||||||
cartTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
|
||||||
|
|
||||||
// ✅ 修复:使用静态内部类或独立类作为渲染器
|
|
||||||
cartTable.getColumnModel().getColumn(1).setCellRenderer(new CurrencyRenderer());
|
|
||||||
cartTable.getColumnModel().getColumn(3).setCellRenderer(new CurrencyRenderer());
|
|
||||||
|
|
||||||
removeButton = new JButton("移除选中商品");
|
|
||||||
removeButton.addActionListener(this::removeSelectedItem); // ✅ 实现此方法
|
|
||||||
|
|
||||||
checkoutButton = new JButton("结算");
|
|
||||||
checkoutButton.addActionListener(this::checkout);
|
|
||||||
|
|
||||||
totalLabel = new JLabel("总金额: ¥0.00");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ 添加缺失的 layoutComponents() 方法实现
|
|
||||||
private void layoutComponents() {
|
|
||||||
setLayout(new BorderLayout(10, 10));
|
|
||||||
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
|
||||||
|
|
||||||
// 添加表格滚动面板
|
|
||||||
add(new JScrollPane(cartTable), BorderLayout.CENTER);
|
|
||||||
|
|
||||||
// 底部控制面板
|
|
||||||
JPanel controlPanel = new JPanel(new BorderLayout(10, 10));
|
|
||||||
|
|
||||||
// 按钮面板
|
|
||||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
|
||||||
buttonPanel.add(removeButton);
|
|
||||||
buttonPanel.add(checkoutButton);
|
|
||||||
|
|
||||||
// 总金额标签
|
|
||||||
JPanel totalPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
|
||||||
totalPanel.add(totalLabel);
|
|
||||||
|
|
||||||
// 组装控制面板
|
|
||||||
controlPanel.add(buttonPanel, BorderLayout.WEST);
|
|
||||||
controlPanel.add(totalPanel, BorderLayout.EAST);
|
|
||||||
|
|
||||||
add(controlPanel, BorderLayout.SOUTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ 实现之前缺失的 removeSelectedItem 方法
|
|
||||||
private void removeSelectedItem(ActionEvent e) {
|
|
||||||
int selectedRow = cartTable.getSelectedRow();
|
|
||||||
if (selectedRow >= 0) {
|
|
||||||
CartItem item = ((CartTableModel) cartTable.getModel()).getItemAt(selectedRow);
|
|
||||||
cartService.removeItem(item.getProduct().getId()); // 假设 ShoppingCartService 有此方法
|
|
||||||
updateCartDisplay();
|
|
||||||
} else {
|
|
||||||
JOptionPane.showMessageDialog(this, "请先选择要移除的商品", "警告", JOptionPane.WARNING_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkout(ActionEvent e) {
|
|
||||||
if (cartService.getCartItems().isEmpty()) {
|
|
||||||
JOptionPane.showMessageDialog(this, "购物车为空,无法结算", "警告", JOptionPane.WARNING_MESSAGE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int confirm = JOptionPane.showConfirmDialog(this,
|
|
||||||
"确认结算购物车中的商品吗?", "确认结算",
|
|
||||||
JOptionPane.YES_NO_OPTION);
|
|
||||||
|
|
||||||
if (confirm == JOptionPane.YES_OPTION) {
|
|
||||||
try {
|
|
||||||
orderService.createOrder(cartService.getCartItems());
|
|
||||||
cartService.clearCart();
|
|
||||||
updateCartDisplay();
|
|
||||||
|
|
||||||
if (mainFrame != null) {
|
|
||||||
mainFrame.refreshProductList();
|
|
||||||
mainFrame.refreshOrderList();
|
|
||||||
}
|
|
||||||
|
|
||||||
JOptionPane.showMessageDialog(this, "订单已创建", "成功", JOptionPane.INFORMATION_MESSAGE);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
JOptionPane.showMessageDialog(this, "结算失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ 修复:使用静态内部类作为渲染器,解决访问权限问题
|
|
||||||
private static class CurrencyRenderer extends DefaultTableCellRenderer { // 改为静态内部类
|
|
||||||
private final DecimalFormat currencyFormat = new DecimalFormat("¥#,##0.00");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getTableCellRendererComponent(JTable table, Object value,
|
|
||||||
boolean isSelected, boolean hasFocus,
|
|
||||||
int row, int column) {
|
|
||||||
if (value instanceof Number) {
|
|
||||||
value = currencyFormat.format(value);
|
|
||||||
}
|
|
||||||
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CartTableModel extends AbstractTableModel {
|
|
||||||
private List<CartItem> cartItems;
|
|
||||||
private final String[] columnNames = {"商品名称", "单价", "数量", "小计", "操作"};
|
|
||||||
|
|
||||||
public void setCartItems(List<CartItem> cartItems) {
|
|
||||||
this.cartItems = cartItems;
|
|
||||||
fireTableDataChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CartItem getItemAt(int row) {
|
|
||||||
return cartItems.get(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRowCount() {
|
|
||||||
return cartItems == null ? 0 : cartItems.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColumnCount() {
|
|
||||||
return columnNames.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColumnName(int column) {
|
|
||||||
return columnNames[column];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValueAt(int row, int column) {
|
|
||||||
CartItem item = cartItems.get(row);
|
|
||||||
Product product = item.getProduct(); // 需要 CartItem 有 getProduct() 方法
|
|
||||||
switch (column) {
|
|
||||||
case 0: return product.getName();
|
|
||||||
case 1: return product.getPrice(); // 返回 Double 类型
|
|
||||||
case 2: return item.getQuantity(); // 返回 Integer 类型
|
|
||||||
case 3: return item.getSubtotal(); // 返回 Double 类型
|
|
||||||
case 4: return "移除";
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> getColumnClass(int columnIndex) {
|
|
||||||
switch (columnIndex) {
|
|
||||||
case 1: return Double.class;
|
|
||||||
case 2: return Integer.class;
|
|
||||||
case 3: return Double.class;
|
|
||||||
default: return String.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
package view;
|
|
||||||
|
|
||||||
import service.OrderService;
|
|
||||||
import service.ProductService;
|
|
||||||
import service.ShoppingCartService;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
public class MainFrame extends JFrame {
|
|
||||||
private final ProductService productService;
|
|
||||||
private final ShoppingCartService cartService;
|
|
||||||
private final OrderService orderService;
|
|
||||||
|
|
||||||
private ProductPanel productPanel;
|
|
||||||
private CartPanel cartPanel;
|
|
||||||
private OrderPanel orderPanel; // 新增:订单面板引用
|
|
||||||
|
|
||||||
public MainFrame() {
|
|
||||||
this.productService = new ProductService();
|
|
||||||
this.cartService = new ShoppingCartService();
|
|
||||||
this.orderService = new OrderService();
|
|
||||||
initializeUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeUI() {
|
|
||||||
setTitle("在线购物平台");
|
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
setSize(900, 700);
|
|
||||||
setLocationRelativeTo(null);
|
|
||||||
|
|
||||||
createPanels();
|
|
||||||
setupTabbedPane();
|
|
||||||
setupMenuBar();
|
|
||||||
|
|
||||||
add(tabbedPane, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
private void createPanels() {
|
|
||||||
this.productPanel = new ProductPanel(productService, cartService, this);
|
|
||||||
this.cartPanel = new CartPanel(cartService, orderService, this); // 正确初始化 CartPanel
|
|
||||||
this.orderPanel = new OrderPanel(orderService);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private final JTabbedPane tabbedPane = new JTabbedPane();
|
|
||||||
private void setupTabbedPane() { // 修改此方法
|
|
||||||
tabbedPane.addTab("商品展示", new JScrollPane(productPanel));
|
|
||||||
tabbedPane.addTab("购物车", new JScrollPane(cartPanel));
|
|
||||||
tabbedPane.addTab("订单管理", new JScrollPane(orderPanel)); // 新增订单标签页
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupMenuBar() { // 保持不变
|
|
||||||
JMenuBar menuBar = new JMenuBar();
|
|
||||||
JMenu fileMenu = new JMenu("文件");
|
|
||||||
|
|
||||||
JMenuItem exitItem = new JMenuItem("退出");
|
|
||||||
|
|
||||||
exitItem.addActionListener(e -> System.exit(0));
|
|
||||||
fileMenu.add(exitItem);
|
|
||||||
menuBar.add(fileMenu);
|
|
||||||
|
|
||||||
setJMenuBar(menuBar);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增以下刷新方法
|
|
||||||
public void refreshOrderList() { // 添加此新方法
|
|
||||||
if (orderPanel != null) { // 确保订单面板已初始化
|
|
||||||
orderPanel.refreshOrderList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 原有刷新方法保持不变...
|
|
||||||
// ✅ 确保调用 CartPanel 的 public 方法 updateCartDisplay()
|
|
||||||
public void refreshCartDisplay() {
|
|
||||||
if (cartPanel != null) {
|
|
||||||
cartPanel.updateCartDisplay(); // 现在可以正确访问,因为方法是 public 的
|
|
||||||
} else {
|
|
||||||
System.err.println("CartPanel 未初始化");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refreshProductList() { // 已存在
|
|
||||||
if (productPanel != null) productPanel.refreshProductList();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,151 +0,0 @@
|
|||||||
package view;
|
|
||||||
|
|
||||||
import model.Order;
|
|
||||||
import model.OrderItem;
|
|
||||||
import service.OrderService;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class OrderPanel extends JPanel {
|
|
||||||
private final OrderService orderService;
|
|
||||||
private JTable orderTable;
|
|
||||||
private JTable orderItemsTable;
|
|
||||||
private OrderTableModel orderTableModel;
|
|
||||||
|
|
||||||
public OrderPanel(OrderService orderService) {
|
|
||||||
this.orderService = orderService;
|
|
||||||
initComponents();
|
|
||||||
layoutComponents();
|
|
||||||
refreshOrderList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initComponents() {
|
|
||||||
orderTableModel = new OrderTableModel();
|
|
||||||
orderTable = new JTable(orderTableModel);
|
|
||||||
orderTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
|
||||||
orderTable.getSelectionModel().addListSelectionListener(e -> {
|
|
||||||
if (!e.getValueIsAdjusting()) {
|
|
||||||
showSelectedOrderItems();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
orderItemsTable = new JTable(new OrderItemsTableModel());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void layoutComponents() {
|
|
||||||
setLayout(new BorderLayout(10, 10));
|
|
||||||
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
|
||||||
|
|
||||||
JLabel titleLabel = new JLabel("订单管理");
|
|
||||||
titleLabel.setFont(new Font("Arial", Font.BOLD, 18));
|
|
||||||
add(titleLabel, BorderLayout.NORTH);
|
|
||||||
|
|
||||||
JPanel orderListPanel = new JPanel(new BorderLayout());
|
|
||||||
orderListPanel.setBorder(BorderFactory.createTitledBorder("订单列表"));
|
|
||||||
orderListPanel.add(new JScrollPane(orderTable), BorderLayout.CENTER);
|
|
||||||
|
|
||||||
JPanel orderItemsPanel = new JPanel(new BorderLayout());
|
|
||||||
orderItemsPanel.setBorder(BorderFactory.createTitledBorder("订单商品明细"));
|
|
||||||
orderItemsPanel.add(new JScrollPane(orderItemsTable), BorderLayout.CENTER);
|
|
||||||
|
|
||||||
add(orderListPanel, BorderLayout.CENTER);
|
|
||||||
add(orderItemsPanel, BorderLayout.SOUTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refreshOrderList() {
|
|
||||||
List<Order> orders = orderService.getAllOrders();
|
|
||||||
orderTableModel.setOrders(orders);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showSelectedOrderItems() {
|
|
||||||
int selectedRow = orderTable.getSelectedRow();
|
|
||||||
if (selectedRow >= 0) {
|
|
||||||
Order selectedOrder = orderTableModel.getOrderAt(selectedRow);
|
|
||||||
((OrderItemsTableModel) orderItemsTable.getModel()).setOrderItems(selectedOrder.getOrderItems());
|
|
||||||
} else {
|
|
||||||
((OrderItemsTableModel) orderItemsTable.getModel()).setOrderItems(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class OrderTableModel extends AbstractTableModel {
|
|
||||||
private List<Order> orders;
|
|
||||||
private final String[] columnNames = {"订单ID", "订单日期", "总金额", "状态"};
|
|
||||||
|
|
||||||
public void setOrders(List<Order> orders) {
|
|
||||||
this.orders = orders;
|
|
||||||
fireTableDataChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Order getOrderAt(int row) {
|
|
||||||
return orders.get(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRowCount() {
|
|
||||||
return orders == null ? 0 : orders.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColumnCount() {
|
|
||||||
return columnNames.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColumnName(int column) {
|
|
||||||
return columnNames[column];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValueAt(int row, int column) {
|
|
||||||
Order order = orders.get(row);
|
|
||||||
switch (column) {
|
|
||||||
case 0: return order.getId();
|
|
||||||
case 1: return order.getOrderDate();
|
|
||||||
case 2: return String.format("¥%.2f", order.getTotalAmount());
|
|
||||||
case 3: return "已完成";
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class OrderItemsTableModel extends AbstractTableModel {
|
|
||||||
private List<OrderItem> orderItems;
|
|
||||||
private final String[] columnNames = {"商品ID", "商品名称", "单价", "数量", "小计"};
|
|
||||||
|
|
||||||
public void setOrderItems(List<OrderItem> orderItems) {
|
|
||||||
this.orderItems = orderItems;
|
|
||||||
fireTableDataChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRowCount() {
|
|
||||||
return orderItems == null ? 0 : orderItems.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColumnCount() {
|
|
||||||
return columnNames.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColumnName(int column) {
|
|
||||||
return columnNames[column];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValueAt(int row, int column) {
|
|
||||||
OrderItem item = orderItems.get(row);
|
|
||||||
switch (column) {
|
|
||||||
case 0: return item.getProductId();
|
|
||||||
case 1: return item.getProductName();
|
|
||||||
case 2: return String.format("¥%.2f", item.getPrice());
|
|
||||||
case 3: return item.getQuantity();
|
|
||||||
case 4: return String.format("¥%.2f", item.getSubtotal());
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="JAVA_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
public class Main {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
System.out.println("Hello world!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in new issue