Java大作业——酒店管理系统(五):餐饮管理

Java大作业(一)介绍了全部功能点

一、Main类——用于启动整个程序

......代码于Java大作业(二)

二、LoginWindowWindow类——用于登录

......代码于Java大作业(二)

三、FunctionSelectionWindow类——用于选择对应的功能

......代码于Java大作业(二)

四、AccountManagementWindow类——用于管理酒店工作人员账户

......代码于Java大作业(三)

五、RoomManagementWindow类——用于办理预定、入住、退房

......代码于Java大作业(四)

    

六、DiningManagementWindow类——用于预定餐饮
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class DiningManagementWindow extends JFrame {
    private JTable table;
    private DefaultTableModel model;
    private List<String[]> foodData;
    private String privilegePassword;

    // 构建餐饮管理窗口,设置属性,读取菜品与权限密码数据,
    // 布局界面,添加按钮及对应监听,展示后设为可见。
    public DiningManagementWindow() {
        setTitle("餐饮管理");
        setSize(1200, 800);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setLocationRelativeTo(null);

        // 从文件中读取菜品数据
        foodData = loadFoodDataFromFile();
        privilegePassword = loadPrivilegePassword();

        // 左侧显示酒店餐饮管理
        JPanel leftPanel = new JPanel();
        leftPanel.setLayout(new GridBagLayout());
        leftPanel.setBackground(Color.LIGHT_GRAY);

        // 创建并设置标签
        JLabel label = new JLabel("酒店餐饮管理", SwingConstants.CENTER);
        label.setFont(new Font("Serif", Font.BOLD, 24));

        // 使用 GridBagLayout 精确控制标签的位置
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.anchor = GridBagConstraints.CENTER; // 居中对齐
        gbc.insets = new Insets(10, 10, 10, 10); // 内边距

        leftPanel.add(label, gbc);

        // 右侧显示餐饮信息
        JPanel rightPanel = new JPanel(new BorderLayout());

        // 餐饮表格
        model = new DefaultTableModel(new Object[]{"序号", "菜品", "金额", "操作"}, 0);
        table = new JTable(model);
        table.getColumnModel().getColumn(3).setCellRenderer(new ButtonRenderer());
        table.getColumnModel().getColumn(3).setCellEditor(new ButtonEditor(new JCheckBox()));

        // 填充表格数据
        for (String[] data : foodData) {
            model.addRow(new Object[]{data[0], data[1], data[2], "预定"});
        }

        JScrollPane scrollPane = new JScrollPane(table);
        rightPanel.add(scrollPane, BorderLayout.CENTER);

        // 界面下方添加四个按钮
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));

        JButton modifyAmountButton = new JButton("修改金额");
        JButton modifyNameButton = new JButton("修改菜名");
        JButton addButton = new JButton("添加菜品");
        JButton deleteButton = new JButton("删除菜品");

        modifyAmountButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                modifyAmount();
            }
        });

        modifyNameButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                modifyName();
            }
        });

        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addDish();
            }
        });

        deleteButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                deleteDish();
            }
        });

        buttonPanel.add(modifyAmountButton);
        buttonPanel.add(modifyNameButton);
        buttonPanel.add(addButton);
        buttonPanel.add(deleteButton);

        rightPanel.add(buttonPanel, BorderLayout.SOUTH);

        // 使用 JSplitPane 将左侧标签和右侧表格分开
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
        splitPane.setDividerLocation(200); // 设置初始分隔条位置
        splitPane.setOneTouchExpandable(false); // 禁用单击展开
        splitPane.setResizeWeight(0.0); // 左侧部分不可调整大小

        setContentPane(splitPane);
        setVisible(true);
    }

    // 从 “Hotel management system/src/Food” 文件读数据,
    // 按格式解析存进列表,遇异常打印栈信息并提示读取失败,最后返回列表。
    private List<String[]> loadFoodDataFromFile() {
        List<String[]> data = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader("Hotel management system/src/Food"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(",");
                if (parts.length == 3) {
                    data.add(parts);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "读取数据失败: " + e.getMessage());
        }
        return data;
    }

    // 尝试从 “Hotel management system/src/privilege_password” 文件读取权限密码,
    // 失败则打印栈信息并提示,成功则返回读取内容。
    private String loadPrivilegePassword() {
        try (BufferedReader reader = new BufferedReader(new FileReader("Hotel management system/src/privilege_password"))) {
            return reader.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "读取权限密码失败: " + e.getMessage());
            return "";
        }
    }

    // 响应修改金额按钮,先选菜品,验证权限密码后获取新金额,
    // 格式正确则更新表格并保存数据,有误则提示相应错误。
    private void modifyAmount() {
        int selectedRow = table.getSelectedRow();
        if (selectedRow == -1) {
            JOptionPane.showMessageDialog(this, "请先选择一个菜品!");
            return;
        }

        String currentAmount = (String) model.getValueAt(selectedRow, 2);
        String inputPassword = JOptionPane.showInputDialog(this, "请输入权限密码:");
        if (inputPassword == null || !inputPassword.equals(privilegePassword)) {
            JOptionPane.showMessageDialog(this, "权限密码错误,您没有权限进行此操作!");
            return;
        }

        String newAmount = JOptionPane.showInputDialog(this, "请输入新的金额:", currentAmount);
        if (newAmount == null || newAmount.isEmpty()) {
            return;
        }

        try {
            double amount = Double.parseDouble(newAmount);
            model.setValueAt(amount, selectedRow, 2);
            saveFoodDataToFile();
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(this, "请输入有效的金额!");
        }
    }

    //针对修改菜名按钮点击,先选菜品,验证密码,
    // 获取新菜名后更新表格并保存数据,没选菜品或密码错则相应提示。
    private void modifyName() {
        int selectedRow = table.getSelectedRow();
        if (selectedRow == -1) {
            JOptionPane.showMessageDialog(this, "请先选择一个菜品!");
            return;
        }

        String currentName = (String) model.getValueAt(selectedRow, 1);
        String inputPassword = JOptionPane.showInputDialog(this, "请输入权限密码:");
        if (inputPassword == null || !inputPassword.equals(privilegePassword)) {
            JOptionPane.showMessageDialog(this, "权限密码错误,您没有权限进行此操作!");
            return;
        }

        String newName = JOptionPane.showInputDialog(this, "请输入新的菜名:", currentName);
        if (newName == null || newName.isEmpty()) {
            return;
        }

        model.setValueAt(newName, selectedRow, 1);
        saveFoodDataToFile();
    }

    // 响应添加菜品按钮,验证权限密码,
    // 按规则依次输入并验证序号、菜名、金额,无误则添加到表格并保存菜品数据。
    private void addDish() {
        // 输入权限密码
        String inputPassword = JOptionPane.showInputDialog(this, "请输入权限密码:");
        if (inputPassword == null || !inputPassword.equals(privilegePassword)) {
            JOptionPane.showMessageDialog(this, "权限密码错误,您没有权限进行此操作!", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        // 从文件中读取数据
        List<String[]> data = loadFoodDataFromFile();

        // 输入新菜品的序号并验证
        String newId = JOptionPane.showInputDialog(this, "请输入新菜品的序号:");
        if (newId == null || newId.isEmpty()) {
            JOptionPane.showMessageDialog(this, "序号不能为空!", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        try {
            int id = Integer.parseInt(newId);

            // 检查序号是否重复
            for (String[] entry : data) {
                int existingId = Integer.parseInt(entry[0]);
                if (existingId == id) {
                    JOptionPane.showMessageDialog(this, "序号重复,序号不能重复且需要按顺序", "错误", JOptionPane.ERROR_MESSAGE);
                    return;
                }
            }

            // 检查序号是否按顺序填写
            if (!data.isEmpty()) {
                int lastId = Integer.parseInt(data.get(data.size() - 1)[0]);
                if (id != lastId + 1) {
                    JOptionPane.showMessageDialog(this, "序号不按顺序,序号必须是最后一个序号加1", "错误", JOptionPane.ERROR_MESSAGE);
                    return;
                }
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(this, "请输入有效的序号!", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        // 输入新菜品的名称并验证
        String newName = JOptionPane.showInputDialog(this, "请输入新菜品的名称:");
        if (newName == null || newName.isEmpty()) {
            JOptionPane.showMessageDialog(this, "菜名不能为空!", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        // 检查菜名是否重复
        for (String[] entry : data) {
            String existingName = entry[1];
            if (existingName.equalsIgnoreCase(newName)) {
                JOptionPane.showMessageDialog(this, "菜名重复,菜名不能重复", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
        }

        // 输入新菜品的金额并验证
        String newAmount = JOptionPane.showInputDialog(this, "请输入新菜品的金额:");
        if (newAmount == null || newAmount.isEmpty()) {
            JOptionPane.showMessageDialog(this, "金额不能为空!", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        try {
            double amount = Double.parseDouble(newAmount);

            // 添加新菜品
            model.addRow(new Object[]{Integer.parseInt(newId), newName, amount, "预定"});
            saveFoodDataToFile();
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(this, "请输入有效的金额!", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    // 响应删除菜品操作,先选菜品,验证权限密码后从表格删行,重排行号,
    // 再保存更新后的菜品数据到文件。
    private void deleteDish() {
        int selectedRow = table.getSelectedRow();
        if (selectedRow == -1) {
            JOptionPane.showMessageDialog(this, "请先选择一个菜品!");
            return;
        }

        String inputPassword = JOptionPane.showInputDialog(this, "请输入权限密码:");
        if (inputPassword == null || !inputPassword.equals(privilegePassword)) {
            JOptionPane.showMessageDialog(this, "权限密码错误,您没有权限进行此操作!");
            return;
        }

        model.removeRow(selectedRow);
        renumberRows();
        saveFoodDataToFile();
    }

    // 遍历表格模型的行,将每行序号列(第 1 列)的值更新为当前行索引加 1,
    // 用于重新编排菜品序号,保证顺序正确。
    private void renumberRows() {
        for (int i = 0; i < model.getRowCount(); i++) {
            model.setValueAt(i + 1, i, 0);
        }
    }

    // 把表格模型中的菜品序号、名称、金额数据按格式
    // 写入 “Hotel management system/src/Food” 文件,遇异常提示错误信息。
    private void saveFoodDataToFile() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("Hotel management system/src/Food"))) {
            for (int i = 0; i < model.getRowCount(); i++) {
                String id = model.getValueAt(i, 0).toString();
                String name = model.getValueAt(i, 1).toString();
                String amount = model.getValueAt(i, 2).toString();
                writer.write(id + "," + name + "," + amount + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "保存数据失败: " + e.getMessage());
        }
    }

    // 弹出对话框让用户选顾客是否入住,
    // 依选择分别展示对应预订菜品对话框,引导后续预订操作流程。
    private void reserveDish(String dishName, double dishPrice) {
        // 创建一个简单的对话框让用户选择顾客是否入住
        int result = JOptionPane.showOptionDialog(
                this,
                "请选择顾客是否入住",
                "预定菜品",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                new Object[]{"顾客已入住", "顾客未入住"},
                "顾客未入住"
        );

        if (result == JOptionPane.YES_OPTION) {
            showCheckInReservationDialog(dishName, dishPrice);
        } else if (result == JOptionPane.NO_OPTION) {
            showNoCheckInReservationDialog(dishName, dishPrice);
        }
    }

    // 显示顾客已入住的预定对话框
    private void showCheckInReservationDialog(String dishName, double dishPrice) {
        JDialog dialog = new JDialog(this, "顾客已入住 - 预定菜品", true);
        dialog.setMinimumSize(new Dimension(600, 400));
        dialog.setPreferredSize(new Dimension(600, 400));
        dialog.pack();
        dialog.setLocationRelativeTo(this);

        JPanel panel = new JPanel(new GridLayout(0, 1));
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // 日期
        JLabel dateLabel = new JLabel("日期:");
        JTextField dateField = new JTextField();

        // 姓名
        JLabel nameLabel = new JLabel("姓名:");
        JTextField nameField = new JTextField();

        // 房号
        JLabel roomNumberLabel = new JLabel("房号:");
        JTextField roomNumberField = new JTextField();

        // 状态
        JLabel statusLabel = new JLabel("状态:");
        JTextField statusField = new JTextField("已入住"); // 默认值为“已入住”

        // 支付状态
        JLabel paymentStatusLabel = new JLabel("支付状态:");
        JTextField paymentStatusField = new JTextField("未支付");

        // 提交按钮
        JButton submitButton = new JButton("提交");
        submitButton.addActionListener(e -> {
            String date = dateField.getText();
            String name = nameField.getText();
            String roomNumber = roomNumberField.getText();
            String status = statusField.getText();
            String paymentStatus = paymentStatusField.getText();

            if (date.isEmpty() || name.isEmpty() || roomNumber.isEmpty() || status.isEmpty()) {
                JOptionPane.showMessageDialog(dialog, "所有字段都必须填写!");
                return;
            }

            saveReservation(true, date, roomNumber, name, dishName, dishPrice, status, paymentStatus);
            dialog.dispose();
        });

        // 添加组件到面板
        panel.add(dateLabel);
        panel.add(dateField);
        panel.add(nameLabel);
        panel.add(nameField);
        panel.add(roomNumberLabel);
        panel.add(roomNumberField);
        panel.add(statusLabel);
        panel.add(statusField);
        panel.add(paymentStatusLabel);
        panel.add(paymentStatusField);
        panel.add(submitButton);

        // 设置对话框内容
        dialog.setContentPane(panel);
        dialog.setVisible(true);
    }

    // 显示顾客未入住的预定对话框
    private void showNoCheckInReservationDialog(String dishName, double dishPrice) {
        JDialog dialog = new JDialog(this, "顾客未入住 - 预定菜品", true);
        dialog.setMinimumSize(new Dimension(600, 400));
        dialog.setPreferredSize(new Dimension(600, 400));
        dialog.pack();
        dialog.setLocationRelativeTo(this);

        JPanel panel = new JPanel(new GridLayout(0, 1));
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // 日期
        JLabel dateLabel = new JLabel("日期:");
        JTextField dateField = new JTextField();

        // 姓名
        JLabel nameLabel = new JLabel("姓名:");
        JTextField nameField = new JTextField();

        // 状态
        JLabel statusLabel = new JLabel("状态:");
        JComboBox<String> statusComboBox = new JComboBox<>(new String[]{"未入住", "已预定"});

        // 支付方式
        JLabel paymentMethodLabel = new JLabel("支付方式:");
        JRadioButton onlinePaymentButton = new JRadioButton("线上支付");
        JRadioButton cashPaymentButton = new JRadioButton("现金支付");
        ButtonGroup paymentGroup = new ButtonGroup();
        paymentGroup.add(onlinePaymentButton);
        paymentGroup.add(cashPaymentButton);

        // 提交按钮
        JButton submitButton = new JButton("提交");
        submitButton.addActionListener(e -> {
            String date = dateField.getText().trim();
            String name = nameField.getText().trim();
            String status = (String) statusComboBox.getSelectedItem();
            String paymentMethod = "";

            if (date.isEmpty() || name.isEmpty() || status.isEmpty()) {
                JOptionPane.showMessageDialog(dialog, "所有字段都必须填写!");
                return;
            }

            if (onlinePaymentButton.isSelected()) {
                paymentMethod = "线上支付";
            } else if (cashPaymentButton.isSelected()) {
                paymentMethod = "现金支付";
            } else {
                JOptionPane.showMessageDialog(dialog, "请选择支付方式!");
                return;
            }

            // 保存预定信息
            saveReservation(false, date, "", name, dishName, dishPrice, status, paymentMethod);

            if (paymentMethod.equals("线上支付")) {
                showOnlinePayment(dishPrice);
            } else if (paymentMethod.equals("现金支付")) {
                showCashPayment(dishPrice);
            }

            dialog.dispose();
        });

        // 添加组件到面板
        panel.add(dateLabel);
        panel.add(dateField);
        panel.add(nameLabel);
        panel.add(nameField);
        panel.add(statusLabel);
        panel.add(statusComboBox);
        panel.add(paymentMethodLabel);
        panel.add(onlinePaymentButton);
        panel.add(cashPaymentButton);
        panel.add(submitButton);

        // 设置对话框内容
        dialog.setContentPane(panel);
        dialog.setVisible(true);
    }

    // 按入住状态选对应文件,构造含各预订信息的行数据,
    // 写入文件,遇异常打印栈信息并提示保存预订信息失败。
    private void saveReservation(boolean isCheckIn, String date, String roomNumber, String name, String dishName, double dishPrice, String status, String paymentInfo) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(isCheckIn ? "Hotel management system/src/Customeryrz" : "Hotel management system/src/Customerwrz", true))) {
            int nextId = getNextId(isCheckIn);
            StringBuilder lineBuilder = new StringBuilder();

            // 写入 ID 和日期
            lineBuilder.append(nextId).append(",");
            lineBuilder.append(date).append(",");

            // 写入房号(如果存在)
            if (!roomNumber.isEmpty()) {
                lineBuilder.append(roomNumber).append(",");
            }

            // 写入姓名(如果存在)
            if (!name.isEmpty()) {
                lineBuilder.append(name).append(",");
            }

            // 写入菜品名称
            lineBuilder.append(dishName).append(",");

            // 写入菜品价格
            lineBuilder.append(dishPrice).append(",");

            // 写入状态(如果存在)
            if (!status.isEmpty()) {
                lineBuilder.append(status).append(",");
            }

            // 写入支付信息(如果存在)
            if (!paymentInfo.isEmpty()) {
                lineBuilder.append(paymentInfo);
            }

            // 移除最后一个逗号(如果有)
            if (lineBuilder.charAt(lineBuilder.length() - 1) == ',') {
                lineBuilder.deleteCharAt(lineBuilder.length() - 1);
            }

            writer.write(lineBuilder.toString());
            writer.newLine();
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "保存预定信息失败: " + e.getMessage());
        }
    }

    // 依入住状态确定文件路径,读取文件中已有最大 ID,
    // 在此基础上加 1 后返回,用于获取新预订记录的序号。
    private int getNextId(boolean isCheckIn) {
        String filePath = isCheckIn ? "Hotel management system/src/Customeryrz" : "Hotel management system/src/Customerwrz";
        int nextId = 1;
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(",");
                int currentId = Integer.parseInt(parts[0]);
                if (currentId >= nextId) {
                    nextId = currentId + 1;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return nextId;
    }

    // 提示需支付金额,尝试展示微信支付二维码图片,
    // 若失败则提示无法显示收款码,引导线上支付操作。
    private void showOnlinePayment(double totalAmount) {
        JOptionPane.showMessageDialog(this, "你需要支付 " + totalAmount + " 元。");
        try {
            ImageIcon icon = new ImageIcon("Hotel management system/src/weixinzhifuma.jpg");
            JOptionPane.showMessageDialog(this, "请扫描二维码支付", "收款码", JOptionPane.INFORMATION_MESSAGE, icon);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "无法显示收款码: " + e.getMessage());
        }
    }

    //向用户提示需要支付的现金金额,
    // 用于告知用户线下现金支付时应支付的具体费用情况。
    private void showCashPayment(double totalAmount) {
        JOptionPane.showMessageDialog(this, "你需要支付 " + totalAmount + " 元。");
    }

    // 按钮渲染器
    private class ButtonRenderer extends JButton implements TableCellRenderer {
        public ButtonRenderer() {
            setOpaque(true);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
                setForeground(table.getSelectionForeground());
                setBackground(table.getSelectionBackground());
            } else {
                setForeground(table.getForeground());
                setBackground(UIManager.getColor("Button.background"));
            }
            setText((value == null) ? "" : value.toString());
            return this;
        }
    }

    // 按钮编辑器
    private class ButtonEditor extends DefaultCellEditor {
        protected JButton button;

        private String label;

        private boolean isPushed;

        public ButtonEditor(JCheckBox checkBox) {
            super(checkBox);
            button = new JButton();
            button.setOpaque(true);
            button.addActionListener(e -> {
                int row = table.convertRowIndexToModel(table.getEditingRow());
                String dishName = (String) model.getValueAt(row, 1);
                String dishPriceStr = (String) model.getValueAt(row, 2);
                double dishPrice = Double.parseDouble(dishPriceStr);
                reserveDish(dishName, dishPrice);
                fireEditingStopped();
            });
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            if (isSelected) {
                button.setForeground(table.getSelectionForeground());
                button.setBackground(table.getSelectionBackground());
            } else {
                button.setForeground(table.getForeground());
                button.setBackground(table.getBackground());
            }
            label = (value == null) ? "" : value.toString();
            button.setText(label);
            isPushed = true;
            return button;
        }

        @Override
        public Object getCellEditorValue() {
            if (isPushed) {
                // 这里可以添加按钮点击后的处理逻辑
                System.out.println("Button clicked: " + label);
            }
            isPushed = false;
            return new String(label);
        }

        @Override
        public boolean stopCellEditing() {
            isPushed = false;
            return super.stopCellEditing();
        }

        @Override
        protected void fireEditingStopped() {
            super.fireEditingStopped();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值