|
|
|
@ -2,55 +2,154 @@ package view;
|
|
|
|
|
|
|
|
|
|
import javafx.collections.FXCollections;
|
|
|
|
|
import javafx.collections.ObservableList;
|
|
|
|
|
import javafx.event.EventHandler;
|
|
|
|
|
import javafx.geometry.Insets;
|
|
|
|
|
import javafx.scene.control.Button;
|
|
|
|
|
import javafx.scene.control.Label;
|
|
|
|
|
import javafx.scene.control.TreeItem;
|
|
|
|
|
import javafx.scene.control.TreeView;
|
|
|
|
|
import javafx.scene.input.MouseEvent;
|
|
|
|
|
import javafx.scene.layout.AnchorPane;
|
|
|
|
|
import javafx.scene.layout.BorderPane;
|
|
|
|
|
import javafx.scene.layout.VBox;
|
|
|
|
|
import model.DataManager;
|
|
|
|
|
import model.Goods;
|
|
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
public class CategoryManagementView extends AnchorPane {
|
|
|
|
|
|
|
|
|
|
private TreeView<String> categoryTreeView;
|
|
|
|
|
private BorderPane contentArea;
|
|
|
|
|
private Map<String, Goods> goodsMap; // 用于快速查找商品
|
|
|
|
|
|
|
|
|
|
public CategoryManagementView() {
|
|
|
|
|
public CategoryManagementView(BorderPane contentArea) {
|
|
|
|
|
this.contentArea = contentArea;
|
|
|
|
|
initializeComponents();
|
|
|
|
|
loadCategoriesAndGoods();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initializeComponents() {
|
|
|
|
|
categoryTreeView = new TreeView<>();
|
|
|
|
|
categoryTreeView.setShowRoot(false); // 不显示根节点
|
|
|
|
|
AnchorPane.setTopAnchor(categoryTreeView, 10.0);
|
|
|
|
|
AnchorPane.setRightAnchor(categoryTreeView, 10.0);
|
|
|
|
|
AnchorPane.setBottomAnchor(categoryTreeView, 10.0);
|
|
|
|
|
AnchorPane.setLeftAnchor(categoryTreeView, 10.0);
|
|
|
|
|
categoryTreeView.setShowRoot(false); // 隐藏根节点
|
|
|
|
|
AnchorPane.setTopAnchor(categoryTreeView, 0.0);
|
|
|
|
|
AnchorPane.setBottomAnchor(categoryTreeView, 0.0);
|
|
|
|
|
AnchorPane.setLeftAnchor(categoryTreeView, 0.0);
|
|
|
|
|
AnchorPane.setRightAnchor(categoryTreeView, 0.0);
|
|
|
|
|
this.getChildren().add(categoryTreeView);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void loadCategoriesAndGoods() {
|
|
|
|
|
DataManager dataManager = DataManager.getInstance();
|
|
|
|
|
ObservableList<Goods> allGoods = FXCollections.observableArrayList(dataManager.getAllGoods());
|
|
|
|
|
ObservableList<String> categories = FXCollections.observableArrayList(dataManager.getAllCategories());
|
|
|
|
|
|
|
|
|
|
// 获取所有分类
|
|
|
|
|
ObservableList<String> categories = FXCollections.observableArrayList(allGoods.stream()
|
|
|
|
|
.map(Goods::getCategory)
|
|
|
|
|
.distinct()
|
|
|
|
|
.toArray(String[]::new));
|
|
|
|
|
// 对商品按照价格进行排序
|
|
|
|
|
allGoods.sort((g1, g2) -> Double.compare(g1.getPrice(), g2.getPrice()));
|
|
|
|
|
|
|
|
|
|
// 构建树结构
|
|
|
|
|
TreeItem<String> root = new TreeItem<>();
|
|
|
|
|
for (String category : categories) {
|
|
|
|
|
TreeItem<String> categoryItem = new TreeItem<>(category);
|
|
|
|
|
for (Goods goods : allGoods) {
|
|
|
|
|
if (goods.getCategory().equals(category)) {
|
|
|
|
|
TreeItem<String> goodsItem = new TreeItem<>(goods.getName() + " (" + goods.getSpecification() + ")");
|
|
|
|
|
categoryItem.getChildren().add(goodsItem);
|
|
|
|
|
TreeItem<String> root = new TreeItem<>("Root"); // 设置根节点
|
|
|
|
|
|
|
|
|
|
// 使用嵌套的 Map 结构来存储类别和价格区间
|
|
|
|
|
Map<String, Map<String, TreeItem<String>>> categoryPriceRangeItems = new HashMap<>();
|
|
|
|
|
goodsMap = new HashMap<>(); // 初始化商品映射
|
|
|
|
|
|
|
|
|
|
for (Goods goods : allGoods) {
|
|
|
|
|
String category = goods.getCategory();
|
|
|
|
|
int price = (int) goods.getPrice();
|
|
|
|
|
int rangeStart = (price / 1000) * 1000;
|
|
|
|
|
String priceRange = rangeStart + "-" + (rangeStart + 999);
|
|
|
|
|
|
|
|
|
|
// 获取或创建类别分类
|
|
|
|
|
Map<String, TreeItem<String>> priceRangeItems = categoryPriceRangeItems.get(category);
|
|
|
|
|
if (priceRangeItems == null) {
|
|
|
|
|
priceRangeItems = new HashMap<>();
|
|
|
|
|
categoryPriceRangeItems.put(category, priceRangeItems);
|
|
|
|
|
|
|
|
|
|
// 创建类别节点并添加到根节点
|
|
|
|
|
TreeItem<String> categoryItem = new TreeItem<>(category);
|
|
|
|
|
root.getChildren().add(categoryItem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取或创建价格区间分类
|
|
|
|
|
TreeItem<String> priceRangeItem = priceRangeItems.get(priceRange);
|
|
|
|
|
if (priceRangeItem == null) {
|
|
|
|
|
priceRangeItem = new TreeItem<>(priceRange);
|
|
|
|
|
priceRangeItems.put(priceRange, priceRangeItem);
|
|
|
|
|
|
|
|
|
|
// 获取类别节点并添加价格区间节点
|
|
|
|
|
TreeItem<String> categoryItem = root.getChildren().stream()
|
|
|
|
|
.filter(item -> item.getValue().equals(category))
|
|
|
|
|
.findFirst()
|
|
|
|
|
.orElse(null);
|
|
|
|
|
if (categoryItem != null) {
|
|
|
|
|
categoryItem.getChildren().add(priceRangeItem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
root.getChildren().add(categoryItem);
|
|
|
|
|
|
|
|
|
|
// 获取库存和价格
|
|
|
|
|
int stock = dataManager.getStock(goods.getId());
|
|
|
|
|
// 构建显示文本
|
|
|
|
|
String displayText = goods.getName() + " (" + goods.getSpecification() + ") - 库存: " + stock + " - 价格: " + price;
|
|
|
|
|
TreeItem<String> goodsItem = new TreeItem<>(displayText);
|
|
|
|
|
priceRangeItem.getChildren().add(goodsItem);
|
|
|
|
|
|
|
|
|
|
// 将商品存储到映射中以便快速查找
|
|
|
|
|
goodsMap.put(displayText, goods);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
categoryTreeView.setRoot(root);
|
|
|
|
|
|
|
|
|
|
// 展开所有一级节点(类别)
|
|
|
|
|
for (TreeItem<String> categoryItem : root.getChildren()) {
|
|
|
|
|
categoryItem.setExpanded(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 为 TreeView 添加鼠标点击事件监听器
|
|
|
|
|
categoryTreeView.setOnMouseClicked(new EventHandler<MouseEvent>() {
|
|
|
|
|
@Override
|
|
|
|
|
public void handle(MouseEvent event) {
|
|
|
|
|
if (event.getClickCount() == 2) { // 双击事件
|
|
|
|
|
TreeItem<String> selectedItem = categoryTreeView.getSelectionModel().getSelectedItem();
|
|
|
|
|
if (selectedItem != null && !selectedItem.isLeaf()) {
|
|
|
|
|
// 如果点击的是分类或价格区间,不显示详细信息
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (selectedItem != null) {
|
|
|
|
|
Goods selectedGoods = goodsMap.get(selectedItem.getValue());
|
|
|
|
|
if (selectedGoods != null) {
|
|
|
|
|
showGoodsDetails(selectedGoods);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showGoodsDetails(Goods goods) {
|
|
|
|
|
// 创建一个 VBox 来显示商品详细信息
|
|
|
|
|
VBox detailsBox = new VBox(10);
|
|
|
|
|
detailsBox.setPadding(new Insets(10));
|
|
|
|
|
|
|
|
|
|
Label nameLabel = new Label("名称: " + goods.getName());
|
|
|
|
|
Label specificationLabel = new Label("规格: " + goods.getSpecification());
|
|
|
|
|
Label categoryLabel = new Label("类别: " + goods.getCategory());
|
|
|
|
|
Label priceLabel = new Label("价格: " + goods.getPrice());
|
|
|
|
|
Label stockLabel = new Label("库存: " + DataManager.getInstance().getStock(goods.getId()));
|
|
|
|
|
|
|
|
|
|
detailsBox.getChildren().addAll(nameLabel, specificationLabel, categoryLabel, priceLabel, stockLabel);
|
|
|
|
|
|
|
|
|
|
// 添加返回按钮
|
|
|
|
|
Button backButton = new Button("返回");
|
|
|
|
|
backButton.setOnAction(event -> {
|
|
|
|
|
// 清空 contentArea 并重新加载分类视图
|
|
|
|
|
contentArea.setCenter(categoryTreeView); // 重新显示分类视图
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
detailsBox.getChildren().add(backButton); // 将返回按钮添加到最后
|
|
|
|
|
|
|
|
|
|
// 将详细信息显示在 contentArea 中
|
|
|
|
|
contentArea.setCenter(detailsBox);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|