package ManagementSystem001;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.List;
// 会员等级枚举
enum MembershipLevel {
DIAMOND(0.77, "钻石卡"),
PLATINUM(0.83, "白金卡"),
GOLD(0.88, "黄金卡"),
SILVER(0.9, "白银卡");
private final double discount;
private final String name;
MembershipLevel(double discount, String name) {
this.discount = discount;
this.name = name;
}
public double getDiscount() { return discount; }
public String getName() { return name; }
}
// 交易类型和消费类型枚举
enum TransactionType {
RECHARGE("充值"),
PAYMENT("消费");
private final String displayName;
TransactionType(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() { return displayName; }
}
enum ConsumptionType {
HAIR_CARE("头发护理"),
SHOPPING("商场购物"),
FRESH_FOOD("生鲜食品");
private final String name;
ConsumptionType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
// 交易记录类
class TransactionRecord {
private LocalDate date;
private double amount;
private TransactionType type;
private ConsumptionType category;
public TransactionRecord(LocalDate date, double amount, TransactionType type, ConsumptionType category) {
this.date = date;
this.amount = amount;
this.type = type;
this.category = category;
}
public LocalDate getDate() { return date; }
public double getAmount() { return amount; }
public TransactionType getType() { return type; }
public ConsumptionType getCategory() { return category; }
}
// 会员类
class Member {
private String cardNumber;
private String name;
private String gender;
private int age;
private String occupation;
private String phone;
private String idNumber;
private double balance;
private LocalDate registrationDate;
private MembershipLevel level;
private List<TransactionRecord> transactionHistory;
private double accumulatedExpense;
public Member(String cardNumber, String name, String gender, int age, String occupation,
String phone, String idNumber) {
this.cardNumber = cardNumber;
this.name = name;
this.gender = gender;
this.age = age;
this.occupation = occupation;
this.phone = phone;
this.idNumber = idNumber;
this.balance = 0;
this.registrationDate = LocalDate.now();
this.level = MembershipLevel.SILVER;
this.transactionHistory = new ArrayList<>();
this.accumulatedExpense = 0;
}
// 会员卡升级逻辑
public void checkMembershipUpgrade() {
LocalDate now = LocalDate.now();
long daysSinceRegistration = ChronoUnit.DAYS.between(registrationDate, now);
if (level == MembershipLevel.SILVER && daysSinceRegistration >= 180) {
level = MembershipLevel.GOLD;
} else if (level == MembershipLevel.GOLD && accumulatedExpense >= 1288) {
level = MembershipLevel.PLATINUM;
} else if (level == MembershipLevel.PLATINUM && accumulatedExpense >= 5888) {
level = MembershipLevel.DIAMOND;
}
}
// 充值余额
public boolean recharge(double amount, String authCode) {
if (verifyAuthCode(authCode)) {
balance += amount;
transactionHistory.add(new TransactionRecord(
LocalDate.now(), amount, TransactionType.RECHARGE, null));
return true;
}
return false;
}
// 消费扣款
public boolean deduct(double amount, String authCode, ConsumptionType category) {
if (!verifyAuthCode(authCode)) return false;
double amountToPay = amount * level.getDiscount();
if (balance >= amountToPay) {
balance -= amountToPay;
accumulatedExpense += amountToPay;
transactionHistory.add(new TransactionRecord(
LocalDate.now(), -amountToPay, TransactionType.PAYMENT, category));
checkMembershipUpgrade();
return true;
}
return false;
}
// 验证授权码(手机/身份证/卡号后6位)
private boolean verifyAuthCode(String authCode) {
if (authCode == null || authCode.length() != 6) return false;
return (phone != null && phone.length() > 6 && phone.substring(phone.length() - 6).equals(authCode)) ||
(idNumber != null && idNumber.length() > 6 && idNumber.substring(idNumber.length() - 6).equals(authCode)) ||
(cardNumber != null && cardNumber.length() > 6 && cardNumber.substring(cardNumber.length() - 6).equals(authCode));
}
// Getters
public String getCardNumber() { return cardNumber; }
public String getName() { return name; }
public String getGender() { return gender; }
public int getAge() { return age; }
public String getOccupation() { return occupation; }
public String getPhone() { return phone; }
public String getIdNumber() { return idNumber; }
public MembershipLevel getLevel() { return level; }
public double getBalance() { return balance; }
public LocalDate getRegistrationDate() { return registrationDate; }
public double getAccumulatedExpense() { return accumulatedExpense; }
public List<TransactionRecord> getTransactionHistory() { return transactionHistory; }
}
// 会员管理系统类
class MembershipSystem {
private Map<String, Member> members;
private static final String ADMIN_USER = "admin";
private static final String ADMIN_PASS = "admin123";
public MembershipSystem() {
members = new HashMap<>();
// 添加测试数据
addTestData();
}
private void addTestData() {
Member m1 = new Member("CN10001", "张三", "男", 30, "工程师", "13800138000", "110101199001011234");
m1.recharge(1000, "800000");
m1.deduct(200, "234", ConsumptionType.SHOPPING);
members.put(m1.getCardNumber(), m1);
Member m2 = new Member("CN10002", "李四", "女", 28, "设计师", "13900139000", "110101199002022345");
m2.recharge(2000, "90000");
m2.deduct(500, "345", ConsumptionType.FRESH_FOOD);
members.put(m2.getCardNumber(), m2);
// 模拟会员升级(修改注册日期)
Member m3 = new Member("CN10003", "王五", "男", 35, "经理", "13600136000", "110101198511113333");
m3.recharge(5000, "36000");
// 设置注册日期为6个月前
m3 = modifyRegistrationDate(m3, LocalDate.now().minusMonths(6));
// 设置累计消费达到升级条件
m3 = modifyAccumulatedExpense(m3, 6000);
members.put(m3.getCardNumber(), m3);
}
// 辅助方法(仅用于测试)
private Member modifyRegistrationDate(Member member, LocalDate newDate) {
try {
java.lang.reflect.Field field = Member.class.getDeclaredField("registrationDate");
field.setAccessible(true);
field.set(member, newDate);
return member;
} catch (Exception e) {
e.printStackTrace();
return member;
}
}
private Member modifyAccumulatedExpense(Member member, double amount) {
try {
java.lang.reflect.Field field = Member.class.getDeclaredField("accumulatedExpense");
field.setAccessible(true);
field.set(member, amount);
return member;
} catch (Exception e) {
e.printStackTrace();
return member;
}
}
// 管理员验证
public boolean authenticateAdmin(String username, String password) {
return ADMIN_USER.equals(username) && ADMIN_PASS.equals(password);
}
// 添加新会员
public void addMember(Member member) {
members.put(member.getCardNumber(), member);
}
// 查找会员
public Member getMember(String cardNumber) {
return members.get(cardNumber);
}
// 获取所有会员
public List<Member> getAllMembers() {
return new ArrayList<>(members.values());
}
// 获取会员卡号是否已存在
public boolean isCardNumberExists(String cardNumber) {
return members.containsKey(cardNumber);
}
}
// GUI主类
public class MembershipManagementApp extends JFrame {
private MembershipSystem system;
private JPanel cardPanel;
private CardLayout cardLayout;
private DefaultListModel<Member> listModel;
private JList<Member> memberList;
private Member selectedMember;
private JTextArea detailsArea;
private DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public MembershipManagementApp() {
system = new MembershipSystem();
initializeUI();
}
private void initializeUI() {
setTitle("综合智慧会员管理系统");
setSize(900, 650);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// 使用卡片布局
cardLayout = new CardLayout();
cardPanel = new JPanel(cardLayout);
// 创建登录面板
JPanel loginPanel = createLoginPanel();
cardPanel.add(loginPanel, "login");
// 创建主功能面板
JPanel mainPanel = createMainPanel();
cardPanel.add(mainPanel, "main");
add(cardPanel);
cardLayout.show(cardPanel, "login");
}
private JPanel createLoginPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBackground(new Color(245, 245, 245));
panel.setBorder(new EmptyBorder(20, 20, 20, 20));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(15, 15, 15, 15);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
JLabel titleLabel = new JLabel("综合智慧会员管理系统");
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 28));
titleLabel.setForeground(new Color(70, 130, 180));
panel.add(titleLabel, gbc);
gbc.gridwidth = 1;
gbc.gridy++;
// 用户名和密码区域
JPanel inputPanel = new JPanel(new GridLayout(2, 2, 10, 15));
inputPanel.setBorder(BorderFactory.createTitledBorder("管理员登录"));
inputPanel.setBackground(new Color(240, 248, 255));
inputPanel.setPreferredSize(new Dimension(350, 150));
JLabel userLabel = new JLabel("用户名:");
userLabel.setFont(new Font("宋体", Font.PLAIN, 16));
JTextField userField = new JTextField(15);
userField.setFont(new Font("宋体", Font.PLAIN, 16));
JLabel passLabel = new JLabel("密码:");
passLabel.setFont(new Font("宋体", Font.PLAIN, 16));
JPasswordField passField = new JPasswordField(15);
passField.setFont(new Font("宋体", Font.PLAIN, 16));
inputPanel.add(userLabel);
inputPanel.add(userField);
inputPanel.add(passLabel);
inputPanel.add(passField);
gbc.gridx = 0;
gbc.gridy++;
panel.add(inputPanel, gbc);
gbc.gridy++;
JButton loginBtn = new JButton("登录");
loginBtn.setFont(new Font("微软雅黑", Font.BOLD, 16));
loginBtn.setBackground(new Color(70, 130, 180));
loginBtn.setForeground(Color.WHITE);
loginBtn.setPreferredSize(new Dimension(120, 40));
loginBtn.addActionListener(e -> {
String username = userField.getText();
String password = new String(passField.getPassword());
if (system.authenticateAdmin(username, password)) {
cardLayout.show(cardPanel, "main");
loadMemberList();
} else {
JOptionPane.showMessageDialog(this, "用户名或密码错误!", "登录失败", JOptionPane.ERROR_MESSAGE);
}
});
panel.add(loginBtn, gbc);
// 回车键登录功能
passField.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
loginBtn.doClick();
}
}
});
return panel;
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new BorderLayout(10, 10));
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
// 顶部菜单栏
JMenuBar menuBar = new JMenuBar();
JMenu memberMenu = new JMenu("会员管理");
memberMenu.setFont(new Font("微软雅黑", Font.PLAIN, 14));
JMenuItem addMemberItem = new JMenuItem("添加新会员");
addMemberItem.addActionListener(e -> showAddMemberDialog());
addMemberItem.setFont(new Font("微软雅黑", Font.PLAIN, 14));
JMenuItem searchMemberItem = new JMenuItem("查找会员");
searchMemberItem.setFont(new Font("微软雅黑", Font.PLAIN, 14));
searchMemberItem.addActionListener(e -> showSearchDialog());
memberMenu.add(addMemberItem);
memberMenu.add(searchMemberItem);
menuBar.add(memberMenu);
JMenu reportMenu = new JMenu("报表");
reportMenu.setFont(new Font("微软雅黑", Font.PLAIN, 14));
JMenuItem salesReportItem = new JMenuItem("销售分析");
salesReportItem.setFont(new Font("微软雅黑", Font.PLAIN, 14));
salesReportItem.addActionListener(e -> showSalesReport());
JMenuItem memberReportItem = new JMenuItem("会员统计");
memberReportItem.setFont(new Font("微软雅黑", Font.PLAIN, 14));
memberReportItem.addActionListener(e -> showMemberStatistics());
reportMenu.add(salesReportItem);
reportMenu.add(memberReportItem);
menuBar.add(reportMenu);
panel.add(menuBar, BorderLayout.NORTH);
// 主内容区域
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setDividerLocation(250);
// 左侧会员列表
listModel = new DefaultListModel<>();
memberList = new JList<>(listModel);
memberList.setCellRenderer(new MemberListRenderer());
memberList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
memberList.setFont(new Font("微软雅黑", Font.PLAIN, 14));
memberList.addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
selectedMember = memberList.getSelectedValue();
showMemberDetails(selectedMember);
}
});
JScrollPane listScroll = new JScrollPane(memberList);
listScroll.setBorder(BorderFactory.createTitledBorder("会员列表"));
splitPane.setLeftComponent(listScroll);
// 中间会员详情
JPanel detailPanel = new JPanel(new BorderLayout());
detailPanel.setBorder(BorderFactory.createTitledBorder("会员详情"));
detailsArea = new JTextArea();
detailsArea.setEditable(false);
detailsArea.setFont(new Font("微软雅黑", Font.PLAIN, 14));
detailsArea.setBorder(new EmptyBorder(10, 10, 10, 10));
detailPanel.add(new JScrollPane(detailsArea), BorderLayout.CENTER);
// 底部操作按钮
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 15));
JButton rechargeBtn = new JButton("充值");
rechargeBtn.setFont(new Font("微软雅黑", Font.BOLD, 14));
rechargeBtn.setPreferredSize(new Dimension(120, 35));
rechargeBtn.addActionListener(e -> showRechargeDialog());
JButton payBtn = new JButton("消费");
payBtn.setFont(new Font("微软雅黑", Font.BOLD, 14));
payBtn.setPreferredSize(new Dimension(120, 35));
payBtn.addActionListener(e -> showPaymentDialog());
JButton historyBtn = new JButton("查看记录");
historyBtn.setFont(new Font("微软雅黑", Font.BOLD, 14));
historyBtn.setPreferredSize(new Dimension(120, 35));
historyBtn.addActionListener(e -> showTransactionHistory());
JButton upgradeBtn = new JButton("强制升级");
upgradeBtn.setFont(new Font("微软雅黑", Font.BOLD, 14));
upgradeBtn.setPreferredSize(new Dimension(120, 35));
upgradeBtn.addActionListener(e -> forceUpgrade());
buttonPanel.add(rechargeBtn);
buttonPanel.add(payBtn);
buttonPanel.add(historyBtn);
buttonPanel.add(upgradeBtn);
detailPanel.add(buttonPanel, BorderLayout.SOUTH);
splitPane.setRightComponent(detailPanel);
panel.add(splitPane, BorderLayout.CENTER);
// 状态栏
JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JLabel statusLabel = new JLabel("就绪");
statusLabel.setFont(new Font("微软雅黑", Font.PLAIN,12));
statusPanel.add(statusLabel);
panel.add(statusPanel, BorderLayout.SOUTH);
return panel;
}
private void loadMemberList() {
listModel.clear();
for (Member member : system.getAllMembers()) {
listModel.addElement(member);
}
}
private void showMemberDetails(Member member) {
if (member == null) {
detailsArea.setText("请从左侧列表选择会员");
return;
}
StringBuilder sb = new StringBuilder();
sb.append("卡号: ").append(member.getCardNumber()).append("\n");
sb.append("姓名: ").append(member.getName()).append("\n");
sb.append("性别: ").append(member.getGender()).append("\n");
sb.append("年龄: ").append(member.getAge()).append("\n");
sb.append("职业: ").append(member.getOccupation()).append("\n");
sb.append("手机: ").append(member.getPhone()).append("\n");
sb.append("身份证: ").append(member.getIdNumber()).append("\n\n");
sb.append("等级: ").append(member.getLevel().getName()).append("\n");
sb.append("余额: ¥").append(String.format("%.2f", member.getBalance())).append("\n");
sb.append("累计消费: ¥").append(String.format("%.2f", member.getAccumulatedExpense())).append("\n");
sb.append("注册日期: ").append(member.getRegistrationDate().format(dateFormatter)).append("\n");
sb.append("会员天数: ").append(ChronoUnit.DAYS.between(member.getRegistrationDate(), LocalDate.now())).append("\n");
detailsArea.setText(sb.toString());
}
private void showAddMemberDialog() {
JDialog dialog = new JDialog(this, "添加新会员", true);
dialog.setSize(500,450);
JPanel panel = new JPanel(new GridLayout(9, 2, 10, 10));
panel.setBorder(new EmptyBorder(15,15,15,15));
// 表单字段
JTextField cardField = new JTextField();
JTextField nameField = new JTextField();
JTextField genderField = new JTextField();
JTextField ageField = new JTextField();
JTextField occupationField = new JTextField();
JTextField phoneField = new JTextField();
JTextField idField = new JTextField();
panel.add(new JLabel("卡号*:"));
panel.add(cardField);
panel.add(new JLabel("姓名*:"));
panel.add(nameField);
panel.add(new JLabel("性别:"));
panel.add(genderField);
panel.add(new JLabel("年龄:"));
panel.add(ageField);
panel.add(new JLabel("职业:"));
panel.add(occupationField);
panel.add(new JLabel("手机*:"));
panel.add(phoneField);
panel.add(new JLabel("身份证*:"));
panel.add(idField);
panel.add(new JLabel("")); // 占位符
JButton addBtn = new JButton("添加");
panel.add(addBtn);
addBtn.addActionListener(e -> {
// 验证必填字段
if (cardField.getText().isEmpty() || nameField.getText().isEmpty() ||
phoneField.getText().isEmpty() || idField.getText().isEmpty()) {
JOptionPane.showMessageDialog(dialog, "带*的字段不能为空", "输入错误", JOptionPane.ERROR_MESSAGE);
return;
}
if (system.isCardNumberExists(cardField.getText())) {
JOptionPane.showMessageDialog(dialog, "该卡号已存在", "输入错误", JOptionPane.ERROR_MESSAGE);
return;
}
try {
int age = ageField.getText().isEmpty() ? 0 : Integer.parseInt(ageField.getText());
Member member = new Member(
cardField.getText(),
nameField.getText(),
genderField.getText(),
age,
occupationField.getText(),
phoneField.getText(),
idField.getText()
);
system.addMember(member);
loadMemberList();
dialog.dispose();
JOptionPane.showMessageDialog(this, "会员添加成功");
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(dialog, "年龄必须是整数", "输入错误", JOptionPane.ERROR_MESSAGE);
}
});
dialog.add(panel);
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
private void showRechargeDialog() {
if (selectedMember == null) {
JOptionPane.showMessageDialog(this, "请先选择一个会员", "操作失败", JOptionPane.WARNING_MESSAGE);
return;
}
JDialog dialog = new JDialog(this, "会员充值", true);
dialog.setSize(400,200);
JPanel panel = new JPanel(new GridLayout(3,2,10,10));
panel.setBorder(new EmptyBorder(15,15,15,15));
panel.add(new JLabel("当前余额:"));
panel.add(new JLabel(String.format("¥%.2f", selectedMember.getBalance())));
panel.add(new JLabel("充值金额*:"));
JTextField amountField = new JTextField();
panel.add(amountField);
panel.add(new JLabel("授权码(后6位):"));
JTextField authField = new JTextField();
panel.add(authField);
JButton rechargeBtn = new JButton("确认充值");
panel.add(new JLabel(""));
panel.add(rechargeBtn);
rechargeBtn.addActionListener(e -> {
try {
double amount = Double.parseDouble(amountField.getText());
if (amount <= 0) throw new NumberFormatException();
if (selectedMember.recharge(amount, authField.getText())) {
JOptionPane.showMessageDialog(dialog, "充值成功");
showMemberDetails(selectedMember);
dialog.dispose();
} else {
JOptionPane.showMessageDialog(dialog, "授权码验证失败", "充值失败", JOptionPane.ERROR_MESSAGE);
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(dialog, "请输入有效的充值金额", "输入错误", JOptionPane.ERROR_MESSAGE);
}
});
dialog.add(panel);
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
private void showPaymentDialog() {
if (selectedMember == null) {
JOptionPane.showMessageDialog(this, "请先选择一个会员", "操作失败", JOptionPane.WARNING_MESSAGE);
return;
}
JDialog dialog = new JDialog(this, "会员消费", true);
dialog.setSize(400,250);
JPanel panel = new JPanel(new GridLayout(4,2,10,10));
panel.setBorder(new EmptyBorder(15,15,15,15));
panel.add(new JLabel("当前余额:"));
panel.add(new JLabel(String.format("¥%.2f", selectedMember.getBalance())));
panel.add(new JLabel("消费金额*:"));
JTextField amountField = new JTextField();
panel.add(amountField);
panel.add(new JLabel("消费类型:"));
JComboBox<ConsumptionType> typeCombo = new JComboBox<>(ConsumptionType.values());
panel.add(typeCombo);
panel.add(new JLabel("授权码(后6位):"));
JTextField authField = new JTextField();
panel.add(authField);
JButton payBtn = new JButton("确认支付");
panel.add(new JLabel(""));
panel.add(payBtn);
payBtn.addActionListener(e -> {
try {
double amount = Double.parseDouble(amountField.getText());
if (amount <= 0) throw new NumberFormatException();
ConsumptionType type = (ConsumptionType) typeCombo.getSelectedItem();
if (selectedMember.deduct(amount, authField.getText(), type)) {
double actualPay = amount * selectedMember.getLevel().getDiscount();
JOptionPane.showMessageDialog(dialog,
String.format("支付成功! 实际支付: ¥%.2f (折扣率:%.0f%%)",
actualPay, (1 - selectedMember.getLevel().getDiscount()) * 100));
showMemberDetails(selectedMember);
dialog.dispose();
} else {
JOptionPane.showMessageDialog(dialog, "授权码验证失败或余额不足", "支付失败", JOptionPane.ERROR_MESSAGE);
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(dialog, "请输入有效的消费金额", "输入错误", JOptionPane.ERROR_MESSAGE);
}
});
dialog.add(panel);
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
private void showTransactionHistory() {
if (selectedMember == null) {
JOptionPane.showMessageDialog(this, "请先选择一个会员", "操作失败", JOptionPane.WARNING_MESSAGE);
return;
}
List<TransactionRecord> transactions = selectedMember.getTransactionHistory();
if (transactions.isEmpty()) {
JOptionPane.showMessageDialog(this, "该会员暂无交易记录", "交易历史", JOptionPane.INFORMATION_MESSAGE);
return;
}
JDialog dialog = new JDialog(this, "交易记录 - " + selectedMember.getName(), true);
dialog.setSize(600,400);
// 创建表格
String[] columns = {"日期", "类型", "金额", "消费类型"};
DefaultTableModel model = new DefaultTableModel(columns, 0);
for (TransactionRecord tr : transactions) {
Object[] row = {
tr.getDate().format(dateFormatter),
tr.getType().getDisplayName(),
String.format("%.2f", tr.getAmount()),
tr.getCategory() == null ? "" : tr.getCategory().getName()
};
model.addRow(row);
}
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
dialog.add(scrollPane);
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
private void forceUpgrade() {
if (selectedMember == null) {
JOptionPane.showMessageDialog(this, "请先选择一个会员", "操作失败", JOptionPane.WARNING_MESSAGE);
return;
}
MembershipLevel[] levels = MembershipLevel.values();
int currentIndex = Arrays.asList(levels).indexOf(selectedMember.getLevel());
if (currentIndex == 0) {
JOptionPane.showMessageDialog(this, "该会员已经是最高等级", "强制升级", JOptionPane.INFORMATION_MESSAGE);
return;
}
MembershipLevel nextLevel = levels[currentIndex - 1]; // 反向获取更高等级
String[] options = {"确认", "取消"};
int choice = JOptionPane.showOptionDialog(
this,
"将会员 " + selectedMember.getName() + " 从 " + selectedMember.getLevel().getName() +
" 升级到 " + nextLevel.getName() + "?",
"强制升级确认",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]
);
if (choice == 0) { // 确认
// 通过反射强制修改会员等级
try {
java.lang.reflect.Field levelField = Member.class.getDeclaredField("level");
levelField.setAccessible(true);
levelField.set(selectedMember, nextLevel);
showMemberDetails(selectedMember);
JOptionPane.showMessageDialog(this, "升级成功!");
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "升级失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
}
}
}
private void showSearchDialog() {
JDialog dialog = new JDialog(this, "查找会员", true);
dialog.setSize(400,150);
JPanel panel = new JPanel(new GridLayout(3,2,10,10));
panel.setBorder(new EmptyBorder(15,15,15,15));
panel.add(new JLabel("搜索条件:"));
JComboBox<String> criteriaCombo = new JComboBox<>(new String[]{"卡号", "姓名", "手机"});
panel.add(criteriaCombo);
panel.add(new JLabel("搜索内容:"));
JTextField searchField = new JTextField();
panel.add(searchField);
JButton searchBtn = new JButton("搜索");
panel.add(new JLabel(""));
panel.add(searchBtn);
searchBtn.addActionListener(e -> {
String criteria = (String) criteriaCombo.getSelectedItem();
String value = searchField.getText().trim();
Member found = null;
for (Member m : system.getAllMembers()) {
if ("卡号".equals(criteria) && m.getCardNumber().equals(value)) {
found = m;
break;
} else if ("姓名".equals(criteria) && m.getName().contains(value)) {
found = m;
break;
} else if ("手机".equals(criteria) && m.getPhone().contains(value)) {
found = m;
break;
}
}
if (found != null) {
memberList.setSelectedValue(found, true);
showMemberDetails(found);
dialog.dispose();
} else {
JOptionPane.showMessageDialog(dialog, "未找到匹配的会员", "搜索结果", JOptionPane.INFORMATION_MESSAGE);
}
});
dialog.add(panel);
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
private void showSalesReport() {
JDialog dialog = new JDialog(this, "销售分析报告", true);
dialog.setSize(600,500);
JTextArea reportArea = new JTextArea();
reportArea.setFont(new Font("微软雅黑", Font.PLAIN,14));
// 计算统计数据
double totalRecharge = 0;
double totalExpenses = 0;
Map<ConsumptionType, Double> expensesByCategory = new EnumMap<>(ConsumptionType.class);
Map<MembershipLevel, Double> expensesByLevel = new EnumMap<>(MembershipLevel.class);
for (Member m : system.getAllMembers()) {
for (TransactionRecord tr : m.getTransactionHistory()) {
if (tr.getType() == TransactionType.RECHARGE) {
totalRecharge += tr.getAmount();
} else if (tr.getType() == TransactionType.PAYMENT) {
double amount = Math.abs(tr.getAmount());
totalExpenses += amount;
// 按消费类型统计
ConsumptionType category = tr.getCategory();
expensesByCategory.put(category, expensesByCategory.getOrDefault(category, 0.0) + amount);
// 按会员等级统计
expensesByLevel.put(m.getLevel(), expensesByLevel.getOrDefault(m.getLevel(), 0.0) + amount);
}
}
}
// 生成报告
StringBuilder report = new StringBuilder();
report.append("===== 销售分析报告 =====\n\n");
report.append(String.format("总收入: ¥%.2f\n", totalRecharge));
report.append(String.format("总消费: ¥%.2f\n\n", totalExpenses));
report.append("---- 按消费类型分布 ----\n");
for (ConsumptionType type : ConsumptionType.values()) {
double amount = expensesByCategory.getOrDefault(type, 0.0);
if (amount > 0) {
report.append(String.format("%-12s: ¥%.2f (%.1f%%)\n",
type.getName(), amount, (amount / totalExpenses) * 100));
}
}
report.append("\n---- 按会员等级分布 ----\n");
for (MembershipLevel level : MembershipLevel.values()) {
double amount = expensesByLevel.getOrDefault(level, 0.0);
if (amount > 0) {
report.append(String.format("%-8s: ¥%.2f (%.1f%%)\n",
level.getName(), amount, (amount / totalExpenses) * 100));
}
}
reportArea.setText(report.toString());
dialog.add(new JScrollPane(reportArea));
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
private void showMemberStatistics() {
JDialog dialog = new JDialog(this, "会员统计报告", true);
dialog.setSize(500,400);
// 计算统计数据
Map<MembershipLevel, Integer> countByLevel = new EnumMap<>(MembershipLevel.class);
int totalMembers = system.getAllMembers().size();
for (Member m : system.getAllMembers()) {
countByLevel.put(m.getLevel(), countByLevel.getOrDefault(m.getLevel(), 0) + 1);
}
// 创建表格
String[] columns = {"会员等级", "会员数量", "占比"};
DefaultTableModel model = new DefaultTableModel(columns, 0);
for (MembershipLevel level : MembershipLevel.values()) {
int count = countByLevel.getOrDefault(level, 0);
model.addRow(new Object[]{
level.getName(),
count,
String.format("%.1f%%", ((double)count / totalMembers) * 100)
});
}
model.addRow(new Object[]{
"总计",
totalMembers,
"100%"
});
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
dialog.add(scrollPane);
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MembershipManagementApp app = new MembershipManagementApp();
app.setVisible(true);
});
}
}
//自定义会员列表渲染器
class MemberListRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof Member) {
Member member = (Member) value;
setText(member.getCardNumber() + " - " + member.getName() + " (" + member.getLevel().getName() + ")");
// 根据会员等级设置不同颜色
switch (member.getLevel()) {
case DIAMOND:
setBackground(isSelected ? new Color(180, 230, 255) : new Color(200, 240, 255));
setForeground(Color.BLUE);
break;
case PLATINUM:
setBackground(isSelected ? new Color(220, 240, 255) : new Color(230, 245, 255));
setForeground(new Color(0, 100, 0));
break;
case GOLD:
setBackground(isSelected ? new Color(255, 250, 200) : new Color(255, 255, 220));
setForeground(new Color(140, 70, 0));
break;
default: // SILVER
setBackground(isSelected ? new Color(220, 220, 220) : Color.WHITE);
break;
}
}
return this;
}
}
依据上面代码,增加删除与修改会员功能
最新发布