From cd459f4952556b1a2c25971a7de8a4a80b73acbb Mon Sep 17 00:00:00 2001 From: charolote <3057939821@qq.com> Date: Sat, 28 Dec 2024 13:32:40 +0800 Subject: [PATCH] v1.0 --- WaterFare/.gitignore | 29 ++ WaterFare/.idea/.gitignore | 8 + .../artifacts/WaterFare_war_exploded.xml | 13 + WaterFare/.idea/misc.xml | 6 + WaterFare/.idea/modules.xml | 8 + WaterFare/WaterFare.iml | 32 ++ WaterFare/src/ClientService.java | 79 +++ WaterFare/src/DBConnection.java | 23 + WaterFare/src/Main.java | 130 +++++ WaterFare/src/ProcedureService.java | 98 ++++ WaterFare/src/ViewService.java | 123 +++++ WaterFare/src/WaterFeeManagementApp.java | 259 ++++++++++ waterfare manage system.sql | 481 ++++++++++++++++++ 13 files changed, 1289 insertions(+) create mode 100644 WaterFare/.gitignore create mode 100644 WaterFare/.idea/.gitignore create mode 100644 WaterFare/.idea/artifacts/WaterFare_war_exploded.xml create mode 100644 WaterFare/.idea/misc.xml create mode 100644 WaterFare/.idea/modules.xml create mode 100644 WaterFare/WaterFare.iml create mode 100644 WaterFare/src/ClientService.java create mode 100644 WaterFare/src/DBConnection.java create mode 100644 WaterFare/src/Main.java create mode 100644 WaterFare/src/ProcedureService.java create mode 100644 WaterFare/src/ViewService.java create mode 100644 WaterFare/src/WaterFeeManagementApp.java create mode 100644 waterfare manage system.sql diff --git a/WaterFare/.gitignore b/WaterFare/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/WaterFare/.gitignore @@ -0,0 +1,29 @@ +### 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 \ No newline at end of file diff --git a/WaterFare/.idea/.gitignore b/WaterFare/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/WaterFare/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/WaterFare/.idea/artifacts/WaterFare_war_exploded.xml b/WaterFare/.idea/artifacts/WaterFare_war_exploded.xml new file mode 100644 index 0000000..3eb4615 --- /dev/null +++ b/WaterFare/.idea/artifacts/WaterFare_war_exploded.xml @@ -0,0 +1,13 @@ + + + $PROJECT_DIR$/out/artifacts/WaterFare_war_exploded + + + + + + + + + + \ No newline at end of file diff --git a/WaterFare/.idea/misc.xml b/WaterFare/.idea/misc.xml new file mode 100644 index 0000000..862d09b --- /dev/null +++ b/WaterFare/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/WaterFare/.idea/modules.xml b/WaterFare/.idea/modules.xml new file mode 100644 index 0000000..b28877b --- /dev/null +++ b/WaterFare/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/WaterFare/WaterFare.iml b/WaterFare/WaterFare.iml new file mode 100644 index 0000000..b6e0581 --- /dev/null +++ b/WaterFare/WaterFare.iml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WaterFare/src/ClientService.java b/WaterFare/src/ClientService.java new file mode 100644 index 0000000..af499cf --- /dev/null +++ b/WaterFare/src/ClientService.java @@ -0,0 +1,79 @@ +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ClientService { + + // 新增客户 + public void addClient(String customerId, String name, String address, String contact, double balance) { + String query = "INSERT INTO 客户信息表 (客户号, 姓名, 地址, 联系方式, 结余金额) VALUES (?, ?, ?, ?, ?)"; + + try (Connection connection = DBConnection.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query)) { + + stmt.setString(1, customerId); + stmt.setString(2, name); + stmt.setString(3, address); + stmt.setString(4, contact); + stmt.setDouble(5, balance); + + stmt.executeUpdate(); // 执行插入操作 + System.out.println("客户记录已插入。"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // 删除客户 + public void deleteClient(String customerId) { + String query = "DELETE FROM 客户信息表 WHERE 客户号 = ?"; + + try (Connection connection = DBConnection.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query)) { + + stmt.setString(1, customerId); // 设置客户号 + stmt.executeUpdate(); // 执行删除操作 + System.out.println("客户记录已删除。"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // 更新客户余额 + public void updateBalance(String customerId, double amount) { + String query = "UPDATE 客户信息表 SET 结余金额 = ? WHERE 客户号 = ?"; + + try (Connection connection = DBConnection.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query)) { + + stmt.setDouble(1, amount); // 设置新余额 + stmt.setString(2, customerId); // 设置客户号 + stmt.executeUpdate(); // 执行更新操作 + System.out.println("客户余额已更新。"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // 查询客户信息 + public void getClientInfo(String customerId) { + String query = "SELECT * FROM 客户信息表 WHERE 客户号 = ?"; + + try (Connection connection = DBConnection.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query)) { + + stmt.setString(1, customerId); // 设置客户号 + ResultSet rs = stmt.executeQuery(); // 执行查询 + + while (rs.next()) { + System.out.println("客户号: " + rs.getString("客户号")); + System.out.println("姓名: " + rs.getString("姓名")); + System.out.println("地址: " + rs.getString("地址")); + System.out.println("联系方式: " + rs.getString("联系方式")); + System.out.println("结余金额: " + rs.getDouble("结余金额")); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + +} diff --git a/WaterFare/src/DBConnection.java b/WaterFare/src/DBConnection.java new file mode 100644 index 0000000..4116dfe --- /dev/null +++ b/WaterFare/src/DBConnection.java @@ -0,0 +1,23 @@ +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class DBConnection { + + // 数据库连接配置 + private static final String URL = "jdbc:mysql://localhost:3306/WaterFare manage System"; // 数据库名 URL 编码 + private static final String USER = "admin_user"; // 管理员用户 + private static final String PASSWORD = "admin_password"; // 密码 + + // 获取数据库连接 + public static Connection getConnection() throws SQLException { + try { + // 显式加载 MySQL JDBC 驱动 + Class.forName("com.mysql.cj.jdbc.Driver"); + // 返回数据库连接 + return DriverManager.getConnection(URL, USER, PASSWORD); + } catch (ClassNotFoundException e) { + throw new SQLException("MySQL JDBC driver not found.", e); + } + } +} diff --git a/WaterFare/src/Main.java b/WaterFare/src/Main.java new file mode 100644 index 0000000..b76ab15 --- /dev/null +++ b/WaterFare/src/Main.java @@ -0,0 +1,130 @@ +import java.util.Scanner; +import java.sql.Date; + +public class Main { + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + // 服务实例化 + ClientService clientService = new ClientService(); + ViewService viewService = new ViewService(); + ProcedureService procedureService = new ProcedureService(); + + // 菜单循环 + while (true) { + System.out.println("欢迎使用水费管理系统"); + System.out.println("1. 增加客户"); + System.out.println("2. 删除客户"); + System.out.println("3. 更新客户余额"); + System.out.println("4. 查询客户信息"); + System.out.println("5. 查询客户用水信息视图"); + System.out.println("6. 查询未收费用客户视图"); + System.out.println("7. 调用存储过程更新客户余额"); + System.out.println("8. 调用存储过程生成费用记录"); + System.out.println("9. 调用存储过程更新收费状态"); + System.out.println("10. 调用存储过程生成订单记录"); + System.out.println("11. 退出"); + System.out.print("请输入选项: "); + + int choice = scanner.nextInt(); + + switch (choice) { + case 1: // 增加客户 + System.out.print("请输入客户号: "); + String addId = scanner.next(); + System.out.print("请输入姓名: "); + String addName = scanner.next(); + System.out.print("请输入地址: "); + String addAddress = scanner.next(); + System.out.print("请输入联系方式: "); + String addContact = scanner.next(); + System.out.print("请输入余额: "); + double addBalance = scanner.nextDouble(); + clientService.addClient(addId, addName, addAddress, addContact, addBalance); + break; + + case 2: // 删除客户 + System.out.print("请输入要删除的客户号: "); + String delId = scanner.next(); + clientService.deleteClient(delId); + break; + + case 3: // 更新客户余额 + System.out.print("请输入客户号: "); + String updateId = scanner.next(); + System.out.print("请输入新余额: "); + double updateBalance = scanner.nextDouble(); + clientService.updateBalance(updateId, updateBalance); + break; + + case 4: // 查询客户信息 + System.out.print("请输入客户号: "); + String queryId = scanner.next(); + clientService.getClientInfo(queryId); + break; + + case 5: // 查询客户用水信息视图 + System.out.println("查询客户用水信息视图:"); + viewService.getClientWaterUsage(); + break; + + case 6: // 查询未收费用客户视图 + System.out.println("查询未收费用客户视图:"); + viewService.getUnpaidClients(); + break; + + case 7: // 调用存储过程更新客户余额 + System.out.print("请输入客户号: "); + String procUpdateId = scanner.next(); + System.out.print("请输入实收费用: "); + double procReceivedAmount = scanner.nextDouble(); + procedureService.updateClientBalance(procUpdateId, procReceivedAmount); + break; + + case 8: // 调用存储过程生成费用记录 + System.out.print("请输入客户号: "); + String procGenFeeId = scanner.next(); + System.out.print("请输入月份 (yyyy-mm-dd): "); + String procMonthStr = scanner.next(); + Date procMonth = Date.valueOf(procMonthStr); + System.out.print("请输入用水量: "); + double procUsage = scanner.nextDouble(); + System.out.print("请输入水价: "); + double procUnitPrice = scanner.nextDouble(); + procedureService.generateClientFeeRecord(procGenFeeId, procMonth, procUsage, procUnitPrice); + break; + + case 9: // 调用存储过程更新收费状态 + System.out.print("请输入客户号: "); + String procFeeStatusId = scanner.next(); + System.out.print("请输入月份 (yyyy-mm-dd): "); + String procFeeMonthStr = scanner.next(); + Date procFeeMonth = Date.valueOf(procFeeMonthStr); + procedureService.updateFeeStatus(procFeeStatusId, procFeeMonth); + break; + + case 10: // 调用存储过程生成订单记录 + System.out.print("请输入客户号: "); + String procOrderId = scanner.next(); + System.out.print("请输入月份 (yyyy-mm-dd): "); + String procOrderMonthStr = scanner.next(); + Date procOrderMonth = Date.valueOf(procOrderMonthStr); + System.out.print("请输入用水量: "); + double procOrderUsage = scanner.nextDouble(); + System.out.print("请输入用水类别ID: "); + int procOrderTypeId = scanner.nextInt(); + procedureService.generateOrderRecord(procOrderId, procOrderMonth, procOrderUsage, procOrderTypeId); + break; + + case 11: // 退出系统 + System.out.println("感谢使用水费管理系统,再见!"); + scanner.close(); + System.exit(0); + + default: + System.out.println("无效选项,请重新输入。"); + } + } + } +} diff --git a/WaterFare/src/ProcedureService.java b/WaterFare/src/ProcedureService.java new file mode 100644 index 0000000..fe602c1 --- /dev/null +++ b/WaterFare/src/ProcedureService.java @@ -0,0 +1,98 @@ +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Date; + +public class ProcedureService { + + // 调用存储过程更新客户余额 + public void updateClientBalance(String customerId, double receivedAmount) { + String query = "{CALL 更新客户余额(?, ?)}"; // 调用存储过程 + + try (Connection connection = DBConnection.getConnection(); + CallableStatement stmt = connection.prepareCall(query)) { + + stmt.setString(1, customerId); // 设置客户号 + stmt.setDouble(2, receivedAmount); // 设置实收费用 + stmt.executeUpdate(); // 执行存储过程 + System.out.println("客户余额已更新。"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // 调用存储过程为客户生成费用记录 + public void generateClientFeeRecord(String customerId, Date month, double usage, double unitPrice) { + String query = "{CALL 生成客户费用记录(?, ?, ?, ?)}"; // 存储过程的调用 + + try (Connection connection = DBConnection.getConnection(); + CallableStatement stmt = connection.prepareCall(query)) { + + // 设置存储过程参数 + stmt.setString(1, customerId); // 客户号 + stmt.setDate(2, (java.sql.Date) month); // 月份 + stmt.setDouble(3, usage); // 用水量 + stmt.setDouble(4, unitPrice); // 水价 + + // 执行存储过程 + stmt.executeUpdate(); + System.out.println("费用记录已生成。"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // 调用存储过程更新收费状态 + public void updateFeeStatus(String customerId, Date month) { + String query = "{CALL 更新收费状态(?, ?)}"; // 存储过程的调用 + + try (Connection connection = DBConnection.getConnection(); + CallableStatement stmt = connection.prepareCall(query)) { + + // 设置存储过程参数 + stmt.setString(1, customerId); // 客户号 + stmt.setDate(2, (java.sql.Date) month); // 月份 + + // 执行存储过程 + stmt.executeUpdate(); + System.out.println("收费状态已更新。"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // 调用存储过程生成订单记录 + public void generateOrderRecord(String customerId, Date month, double usage, int typeId) { + String query = "{CALL 生成订单记录(?, ?, ?, ?)}"; // 存储过程的调用 + + try (Connection connection = DBConnection.getConnection(); + CallableStatement stmt = connection.prepareCall(query)) { + + // 设置存储过程参数 + stmt.setString(1, customerId); // 客户号 + stmt.setDate(2, (java.sql.Date) month); // 月份 + stmt.setDouble(3, usage); // 用水量 + stmt.setInt(4, typeId); // 用水类别ID + + // 执行存储过程 + stmt.executeUpdate(); + System.out.println("订单记录已生成。"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // 调用存储过程统计区域客户总费用 + public void getAreaClientFeeStats(String area) { + String query = "{CALL 统计区域客户费用(?)}"; // 存储过程的调用 + + try (Connection connection = DBConnection.getConnection(); + CallableStatement stmt = connection.prepareCall(query)) { + + // 设置存储过程参数 + stmt.setString(1, area); // 区域名称 + + // 执行存储过程 + stmt.executeUpdate(); + System.out.println("区域客户总费用统计完成。"); + } catch (SQLException e) { + e.printStackTrace(); + } + } +} diff --git a/WaterFare/src/ViewService.java b/WaterFare/src/ViewService.java new file mode 100644 index 0000000..5919a6c --- /dev/null +++ b/WaterFare/src/ViewService.java @@ -0,0 +1,123 @@ +import java.sql.*; + +public class ViewService { + + // 查询客户用水信息视图 + public void getClientWaterUsage() { + String query = "SELECT * FROM 客户用水信息视图"; // 假设此视图已经创建 + + try (Connection connection = DBConnection.getConnection(); + Statement stmt = connection.createStatement()) { + + // 执行查询操作 + ResultSet rs = stmt.executeQuery(query); + + // 输出查询结果 + while (rs.next()) { + System.out.println("客户号: " + rs.getString("客户编号")); + System.out.println("姓名: " + rs.getString("客户姓名")); + System.out.println("用水类别: " + rs.getString("用水类别")); + System.out.println("用水量: " + rs.getDouble("用水量")); + System.out.println("用水月份: " + rs.getDate("用水月份")); + System.out.println("================================="); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + // 查询未收费用的客户视图 + public void getUnpaidClients() { + String query = "SELECT * FROM 未收费用客户视图"; // 假设此视图已经创建 + + try (Connection connection = DBConnection.getConnection(); + Statement stmt = connection.createStatement()) { + + // 执行查询操作 + ResultSet rs = stmt.executeQuery(query); + + // 输出查询结果 + while (rs.next()) { + System.out.println("客户号: " + rs.getString("客户编号")); + System.out.println("姓名: " + rs.getString("客户姓名")); + System.out.println("联系方式: " + rs.getString("联系方式")); + System.out.println("应缴月份: " + rs.getDate("应缴月份")); + System.out.println("未缴金额: " + rs.getDouble("未缴金额")); + System.out.println("================================="); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + // 查询区域业务员客户分布视图 + public void getClientDistributionByArea() { + String query = "SELECT * FROM 区域业务员客户分布视图"; // 假设此视图已经创建 + + try (Connection connection = DBConnection.getConnection(); + Statement stmt = connection.createStatement()) { + + // 执行查询操作 + ResultSet rs = stmt.executeQuery(query); + + // 输出查询结果 + while (rs.next()) { + System.out.println("业务员姓名: " + rs.getString("业务员姓名")); + System.out.println("负责区域: " + rs.getString("负责区域")); + System.out.println("客户数量: " + rs.getInt("客户数量")); + System.out.println("总余额: " + rs.getDouble("总余额")); + System.out.println("================================="); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + // 查询年度客户用水统计视图 + public void getAnnualClientWaterUsage() { + String query = "SELECT * FROM 年度客户用水统计视图"; // 假设此视图已经创建 + + try (Connection connection = DBConnection.getConnection(); + Statement stmt = connection.createStatement()) { + + // 执行查询操作 + ResultSet rs = stmt.executeQuery(query); + + // 输出查询结果 + while (rs.next()) { + System.out.println("客户号: " + rs.getString("客户编号")); + System.out.println("姓名: " + rs.getString("客户姓名")); + System.out.println("总用水量: " + rs.getDouble("总用水量")); + System.out.println("总费用: " + rs.getDouble("总费用")); + System.out.println("================================="); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + // 查询订单详细信息视图 + public void getOrderDetails() { + String query = "SELECT * FROM 订单详细信息视图"; // 假设此视图已经创建 + + try (Connection connection = DBConnection.getConnection(); + Statement stmt = connection.createStatement()) { + + // 执行查询操作 + ResultSet rs = stmt.executeQuery(query); + + // 输出查询结果 + while (rs.next()) { + System.out.println("订单编号: " + rs.getString("订单编号")); + System.out.println("客户姓名: " + rs.getString("客户姓名")); + System.out.println("用水类别: " + rs.getString("用水类别")); + System.out.println("用水量: " + rs.getDouble("用水量")); + System.out.println("应收费用: " + rs.getDouble("应收费用")); + System.out.println("实收费用: " + rs.getDouble("实收费用")); + System.out.println("================================="); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } +} diff --git a/WaterFare/src/WaterFeeManagementApp.java b/WaterFare/src/WaterFeeManagementApp.java new file mode 100644 index 0000000..8021a37 --- /dev/null +++ b/WaterFare/src/WaterFeeManagementApp.java @@ -0,0 +1,259 @@ +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.sql.Date; + +public class WaterFeeManagementApp { + + // 实例化服务类 + private static ClientService clientService = new ClientService(); + private static ProcedureService procedureService = new ProcedureService(); + + public static void main(String[] args) { + // 创建主窗口 + JFrame frame = new JFrame("水费管理系统"); + frame.setSize(800, 600); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // 创建选项卡面板 + JTabbedPane tabbedPane = new JTabbedPane(); + + // 添加选项卡 + tabbedPane.addTab("客户管理", createClientPanel()); + tabbedPane.addTab("收费管理", createFeePanel()); + tabbedPane.addTab("订单管理", createOrderPanel()); + tabbedPane.addTab("统计与分析", createAnalysisPanel()); + + frame.add(tabbedPane); + frame.setVisible(true); + } + + // **客户管理面板** + private static JPanel createClientPanel() { + JPanel panel = new JPanel(); + panel.setLayout(new BorderLayout()); + + // **表单区域** + JPanel formPanel = new JPanel(new GridLayout(6, 2, 10, 10)); + JLabel lblCustomerId = new JLabel("客户号:"); + JTextField txtCustomerId = new JTextField(); + JLabel lblName = new JLabel("姓名:"); + JTextField txtName = new JTextField(); + JLabel lblAddress = new JLabel("地址:"); + JTextField txtAddress = new JTextField(); + JLabel lblContact = new JLabel("联系方式:"); + JTextField txtContact = new JTextField(); + JLabel lblBalance = new JLabel("余额:"); + JTextField txtBalance = new JTextField(); + JButton btnAddClient = new JButton("添加客户"); + + formPanel.add(lblCustomerId); + formPanel.add(txtCustomerId); + formPanel.add(lblName); + formPanel.add(txtName); + formPanel.add(lblAddress); + formPanel.add(txtAddress); + formPanel.add(lblContact); + formPanel.add(txtContact); + formPanel.add(lblBalance); + formPanel.add(txtBalance); + formPanel.add(new JLabel()); // 空白占位 + formPanel.add(btnAddClient); + + // **表格区域** + JTable table = new JTable(new DefaultTableModel(new Object[]{"客户号", "姓名", "地址", "联系方式", "余额"}, 0)); + JScrollPane tableScrollPane = new JScrollPane(table); + + // **按钮区域** + JPanel buttonPanel = new JPanel(); + JButton btnDeleteClient = new JButton("删除客户"); + JButton btnUpdateBalance = new JButton("更新余额"); + JButton btnQueryClient = new JButton("查询客户"); + buttonPanel.add(btnDeleteClient); + buttonPanel.add(btnUpdateBalance); + buttonPanel.add(btnQueryClient); + + // **按钮事件监听** + btnAddClient.addActionListener(e -> { + try { + String customerId = txtCustomerId.getText(); + String name = txtName.getText(); + String address = txtAddress.getText(); + String contact = txtContact.getText(); + double balance = Double.parseDouble(txtBalance.getText()); + + clientService.addClient(customerId, name, address, contact, balance); + JOptionPane.showMessageDialog(panel, "客户添加成功!"); + } catch (Exception ex) { + JOptionPane.showMessageDialog(panel, "输入有误,请检查数据格式!", "错误", JOptionPane.ERROR_MESSAGE); + } + }); + + btnDeleteClient.addActionListener(e -> { + try { + String customerId = JOptionPane.showInputDialog("请输入要删除的客户号:"); + clientService.deleteClient(customerId); + JOptionPane.showMessageDialog(panel, "客户删除成功!"); + } catch (Exception ex) { + JOptionPane.showMessageDialog(panel, "删除失败,请检查客户号!", "错误", JOptionPane.ERROR_MESSAGE); + } + }); + + btnUpdateBalance.addActionListener(e -> { + try { + String customerId = JOptionPane.showInputDialog("请输入客户号:"); + double balance = Double.parseDouble(JOptionPane.showInputDialog("请输入新的余额:")); + clientService.updateBalance(customerId, balance); + JOptionPane.showMessageDialog(panel, "余额更新成功!"); + } catch (Exception ex) { + JOptionPane.showMessageDialog(panel, "更新失败,请检查输入数据!", "错误", JOptionPane.ERROR_MESSAGE); + } + }); + + btnQueryClient.addActionListener(e -> { + String customerId = JOptionPane.showInputDialog("请输入客户号:"); + clientService.getClientInfo(customerId); // Replace with table update logic + }); + + // **布局** + panel.add(formPanel, BorderLayout.NORTH); + panel.add(tableScrollPane, BorderLayout.CENTER); + panel.add(buttonPanel, BorderLayout.SOUTH); + + return panel; + } + + // **收费管理面板** + private static JPanel createFeePanel() { + JPanel panel = new JPanel(new BorderLayout()); + + // 表格区域 + JTable table = new JTable(new DefaultTableModel(new Object[]{"客户号", "姓名", "应缴月份", "未缴金额"}, 0)); + JScrollPane tableScrollPane = new JScrollPane(table); + + // 按钮区域 + JPanel buttonPanel = new JPanel(); + JButton btnViewUnpaidFees = new JButton("查看未收费用"); + JButton btnUpdateFeeStatus = new JButton("更新收费状态"); + buttonPanel.add(btnViewUnpaidFees); + buttonPanel.add(btnUpdateFeeStatus); + + // 查看未收费用 + btnViewUnpaidFees.addActionListener(e -> { + try { + // TODO: Replace with database call to fetch unpaid fees + DefaultTableModel model = (DefaultTableModel) table.getModel(); + model.setRowCount(0); // 清空表格 + // 模拟数据 + model.addRow(new Object[]{"C001", "张三", "2024-12-01", 50.0}); + model.addRow(new Object[]{"C002", "李四", "2024-12-01", 100.0}); + JOptionPane.showMessageDialog(panel, "未收费用加载成功!"); + } catch (Exception ex) { + JOptionPane.showMessageDialog(panel, "加载失败,请重试!", "错误", JOptionPane.ERROR_MESSAGE); + } + }); + + // 更新收费状态 + btnUpdateFeeStatus.addActionListener(e -> { + try { + String customerId = JOptionPane.showInputDialog("请输入客户号:"); + String monthStr = JOptionPane.showInputDialog("请输入月份 (yyyy-mm-dd):"); + Date month = Date.valueOf(monthStr); + procedureService.updateFeeStatus(customerId, month); + JOptionPane.showMessageDialog(panel, "收费状态更新成功!"); + } catch (Exception ex) { + JOptionPane.showMessageDialog(panel, "更新失败,请检查输入数据!", "错误", JOptionPane.ERROR_MESSAGE); + } + }); + + panel.add(tableScrollPane, BorderLayout.CENTER); + panel.add(buttonPanel, BorderLayout.SOUTH); + return panel; + } + + // **订单管理面板** + private static JPanel createOrderPanel() { + JPanel panel = new JPanel(new BorderLayout()); + + // 表格区域 + JTable table = new JTable(new DefaultTableModel(new Object[]{"订单编号", "客户号", "用水类别", "用水量", "应收费用", "实收费用"}, 0)); + JScrollPane tableScrollPane = new JScrollPane(table); + + // 按钮区域 + JPanel buttonPanel = new JPanel(); + JButton btnViewOrders = new JButton("查看订单记录"); + JButton btnGenerateOrder = new JButton("生成订单记录"); + buttonPanel.add(btnViewOrders); + buttonPanel.add(btnGenerateOrder); + + // 查看订单记录 + btnViewOrders.addActionListener(e -> { + try { + // TODO: Replace with database call to fetch order records + DefaultTableModel model = (DefaultTableModel) table.getModel(); + model.setRowCount(0); // 清空表格 + // 模拟数据 + model.addRow(new Object[]{"O001", "C001", "居民用水", 20.0, 50.0, 50.0}); + model.addRow(new Object[]{"O002", "C002", "工业用水", 30.0, 150.0, 0.0}); + JOptionPane.showMessageDialog(panel, "订单记录加载成功!"); + } catch (Exception ex) { + JOptionPane.showMessageDialog(panel, "加载失败,请重试!", "错误", JOptionPane.ERROR_MESSAGE); + } + }); + + // 生成订单记录 + btnGenerateOrder.addActionListener(e -> { + try { + String customerId = JOptionPane.showInputDialog("请输入客户号:"); + String monthStr = JOptionPane.showInputDialog("请输入月份 (yyyy-mm-dd):"); + Date month = Date.valueOf(monthStr); + double usage = Double.parseDouble(JOptionPane.showInputDialog("请输入用水量:")); + int typeId = Integer.parseInt(JOptionPane.showInputDialog("请输入用水类别ID:")); + procedureService.generateOrderRecord(customerId, month, usage, typeId); + JOptionPane.showMessageDialog(panel, "订单记录生成成功!"); + } catch (Exception ex) { + JOptionPane.showMessageDialog(panel, "生成失败,请检查输入数据!", "错误", JOptionPane.ERROR_MESSAGE); + } + }); + + panel.add(tableScrollPane, BorderLayout.CENTER); + panel.add(buttonPanel, BorderLayout.SOUTH); + return panel; + } + + + // **统计与分析面板** + private static JPanel createAnalysisPanel() { + JPanel panel = new JPanel(new BorderLayout()); + + // 表格区域 + JTable table = new JTable(new DefaultTableModel(new Object[]{"区域", "总费用", "总余额"}, 0)); + JScrollPane tableScrollPane = new JScrollPane(table); + + // 按钮区域 + JPanel buttonPanel = new JPanel(); + JButton btnAnalyzeByArea = new JButton("按区域统计费用"); + buttonPanel.add(btnAnalyzeByArea); + + // 按区域统计费用 + btnAnalyzeByArea.addActionListener(e -> { + try { + String area = JOptionPane.showInputDialog("请输入区域名称:"); + // TODO: Replace with database call to analyze data by area + DefaultTableModel model = (DefaultTableModel) table.getModel(); + model.setRowCount(0); // 清空表格 + // 模拟数据 + model.addRow(new Object[]{"山东青岛", 500.0, 200.0}); + model.addRow(new Object[]{"山东济南", 300.0, 150.0}); + JOptionPane.showMessageDialog(panel, "统计完成!"); + } catch (Exception ex) { + JOptionPane.showMessageDialog(panel, "统计失败,请检查输入!", "错误", JOptionPane.ERROR_MESSAGE); + } + }); + + panel.add(tableScrollPane, BorderLayout.CENTER); + panel.add(buttonPanel, BorderLayout.SOUTH); + return panel; + } + +} diff --git a/waterfare manage system.sql b/waterfare manage system.sql new file mode 100644 index 0000000..5ba398f --- /dev/null +++ b/waterfare manage system.sql @@ -0,0 +1,481 @@ +/* + Navicat Premium Dump SQL + + Source Server : long + Source Server Type : MySQL + Source Server Version : 80040 (8.0.40) + Source Host : localhost:3306 + Source Schema : waterfare manage system + + Target Server Type : MySQL + Target Server Version : 80040 (8.0.40) + File Encoding : 65001 + + Date: 25/12/2024 09:20:41 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for 业务员表 +-- ---------------------------- +DROP TABLE IF EXISTS `业务员表`; +CREATE TABLE `业务员表` ( + `业务员编号` bigint UNSIGNED NOT NULL AUTO_INCREMENT, + `姓名` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `联系方式` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `邮箱` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `入职日期` date NOT NULL, + `负责区域` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + PRIMARY KEY (`业务员编号`) USING BTREE, + UNIQUE INDEX `业务员编号`(`业务员编号` ASC) USING BTREE, + UNIQUE INDEX `联系方式`(`联系方式` ASC) USING BTREE, + UNIQUE INDEX `邮箱`(`邮箱` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of 业务员表 +-- ---------------------------- +INSERT INTO `业务员表` VALUES (1, '李业务员', '1234567890', 'li@example.com', '2022-01-01', '山东青岛'); +INSERT INTO `业务员表` VALUES (2, '王业务员', '0987654321', 'wang@example.com', '2023-03-15', '山东济南'); +INSERT INTO `业务员表` VALUES (3, '赵业务员', '1234509876', 'zhao@example.com', '2023-05-10', '山东烟台'); + +-- ---------------------------- +-- Table structure for 客户信息表 +-- ---------------------------- +DROP TABLE IF EXISTS `客户信息表`; +CREATE TABLE `客户信息表` ( + `客户号` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `姓名` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `地址` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `联系方式` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `结余金额` decimal(10, 2) NULL DEFAULT 0.00, + PRIMARY KEY (`客户号`) USING BTREE, + UNIQUE INDEX `联系方式`(`联系方式` ASC) USING BTREE, + INDEX `idx_客户余额`(`结余金额` ASC) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of 客户信息表 +-- ---------------------------- +INSERT INTO `客户信息表` VALUES ('C001', '张三', '山东济南', '1234567890', 50.00); +INSERT INTO `客户信息表` VALUES ('C002', '李四', '山东济南', '0987654321', 200.00); +INSERT INTO `客户信息表` VALUES ('C003', '王五', '山东烟台', '1234509876', 150.00); +INSERT INTO `客户信息表` VALUES ('C004', '赵六', '山东潍坊', '0987654322', 300.00); +INSERT INTO `客户信息表` VALUES ('C005', '梁明', '山东青岛', '1234561234', 20.00); +INSERT INTO `客户信息表` VALUES ('C006', '朱明', '山东济南', '1234569876', 250.00); +INSERT INTO `客户信息表` VALUES ('C007', '韦明', '山东烟台', '9876543210', 155.00); +INSERT INTO `客户信息表` VALUES ('C008', '田明', '山东潍坊', '9876501234', 160.00); +INSERT INTO `客户信息表` VALUES ('C009', '王明', '山东东营', '8765432109', 300.00); +INSERT INTO `客户信息表` VALUES ('C010', '马明', '山东威海', '6543210987', 220.00); + +-- ---------------------------- +-- Table structure for 收费登记表 +-- ---------------------------- +DROP TABLE IF EXISTS `收费登记表`; +CREATE TABLE `收费登记表` ( + `收费编号` bigint UNSIGNED NOT NULL AUTO_INCREMENT, + `客户号` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `订单编号` bigint UNSIGNED NOT NULL, + `收费日期` date NOT NULL, + `实收费用` decimal(10, 2) NOT NULL, + PRIMARY KEY (`收费编号`) USING BTREE, + INDEX `客户号`(`客户号` ASC) USING BTREE, + INDEX `订单编号`(`订单编号` ASC) USING BTREE, + CONSTRAINT `收费登记表_ibfk_1` FOREIGN KEY (`客户号`) REFERENCES `客户信息表` (`客户号`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `收费登记表_ibfk_2` FOREIGN KEY (`订单编号`) REFERENCES `订单管理表` (`订单编号`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of 收费登记表 +-- ---------------------------- +INSERT INTO `收费登记表` VALUES (4, 'C001', 1, '2024-12-10', 50.00); +INSERT INTO `收费登记表` VALUES (5, 'C005', 2, '2024-12-15', 100.00); +INSERT INTO `收费登记表` VALUES (6, 'C007', 3, '2024-12-12', 25.00); + +-- ---------------------------- +-- Table structure for 用水信息表 +-- ---------------------------- +DROP TABLE IF EXISTS `用水信息表`; +CREATE TABLE `用水信息表` ( + `用水记录编号` bigint UNSIGNED NOT NULL AUTO_INCREMENT, + `客户号` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `月份` date NOT NULL, + `用水类别号` int NOT NULL, + `用水量` decimal(10, 2) NOT NULL, + PRIMARY KEY (`用水记录编号`) USING BTREE, + UNIQUE INDEX `用水记录编号`(`用水记录编号` ASC) USING BTREE, + INDEX `客户号`(`客户号` ASC) USING BTREE, + INDEX `用水类别号`(`用水类别号` ASC) USING BTREE, + INDEX `idx_用水记录月份`(`月份` ASC) USING BTREE, + CONSTRAINT `用水信息表_ibfk_1` FOREIGN KEY (`客户号`) REFERENCES `客户信息表` (`客户号`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `用水信息表_ibfk_2` FOREIGN KEY (`用水类别号`) REFERENCES `用水类型表` (`类别号`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `用水信息表_chk_1` CHECK (`用水量` >= 0) +) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of 用水信息表 +-- ---------------------------- +INSERT INTO `用水信息表` VALUES (1, 'C001', '2024-12-01', 1, 20.00); +INSERT INTO `用水信息表` VALUES (2, 'C002', '2024-12-01', 2, 50.00); +INSERT INTO `用水信息表` VALUES (3, 'C003', '2024-12-01', 1, 15.00); +INSERT INTO `用水信息表` VALUES (4, 'C004', '2024-12-01', 3, 30.00); +INSERT INTO `用水信息表` VALUES (5, 'C005', '2024-12-01', 4, 25.00); +INSERT INTO `用水信息表` VALUES (6, 'C006', '2024-12-01', 2, 40.00); +INSERT INTO `用水信息表` VALUES (7, 'C007', '2024-12-01', 1, 10.00); +INSERT INTO `用水信息表` VALUES (8, 'C008', '2024-12-01', 3, 35.00); +INSERT INTO `用水信息表` VALUES (9, 'C009', '2024-12-01', 4, 20.00); +INSERT INTO `用水信息表` VALUES (10, 'C010', '2024-12-01', 2, 60.00); + +-- ---------------------------- +-- Table structure for 用水类型表 +-- ---------------------------- +DROP TABLE IF EXISTS `用水类型表`; +CREATE TABLE `用水类型表` ( + `类别号` int NOT NULL, + `类别名` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `水价` decimal(10, 2) NOT NULL, + PRIMARY KEY (`类别号`) USING BTREE, + CONSTRAINT `用水类型表_chk_1` CHECK (`水价` > 0) +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of 用水类型表 +-- ---------------------------- +INSERT INTO `用水类型表` VALUES (1, '居民用水', 2.50); +INSERT INTO `用水类型表` VALUES (2, '工业用水', 5.00); +INSERT INTO `用水类型表` VALUES (3, '农业用水', 1.50); +INSERT INTO `用水类型表` VALUES (4, '商业用水', 4.00); + +-- ---------------------------- +-- Table structure for 订单管理表 +-- ---------------------------- +DROP TABLE IF EXISTS `订单管理表`; +CREATE TABLE `订单管理表` ( + `订单编号` bigint UNSIGNED NOT NULL AUTO_INCREMENT, + `客户号` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `月份` date NOT NULL, + `用水类别号` int NOT NULL, + `用水量` decimal(10, 2) NOT NULL, + `应收费用` decimal(10, 2) NOT NULL, + `实收费用` decimal(10, 2) NULL DEFAULT NULL, + PRIMARY KEY (`订单编号`) USING BTREE, + INDEX `客户号`(`客户号` ASC) USING BTREE, + INDEX `用水类别号`(`用水类别号` ASC) USING BTREE, + CONSTRAINT `订单管理表_ibfk_1` FOREIGN KEY (`客户号`) REFERENCES `客户信息表` (`客户号`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `订单管理表_ibfk_2` FOREIGN KEY (`用水类别号`) REFERENCES `用水类型表` (`类别号`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of 订单管理表 +-- ---------------------------- +INSERT INTO `订单管理表` VALUES (1, 'C001', '2024-12-01', 1, 20.00, 50.00, 50.00); +INSERT INTO `订单管理表` VALUES (2, 'C005', '2024-12-01', 4, 25.00, 100.00, 100.00); +INSERT INTO `订单管理表` VALUES (3, 'C007', '2024-12-01', 1, 10.00, 25.00, 25.00); + +-- ---------------------------- +-- Table structure for 费用管理表 +-- ---------------------------- +DROP TABLE IF EXISTS `费用管理表`; +CREATE TABLE `费用管理表` ( + `费用编号` bigint UNSIGNED NOT NULL AUTO_INCREMENT, + `客户号` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `月份` date NOT NULL, + `应收费用` decimal(10, 2) NOT NULL, + `收费标志` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '未收', + PRIMARY KEY (`费用编号`) USING BTREE, + UNIQUE INDEX `费用编号`(`费用编号` ASC) USING BTREE, + INDEX `客户号`(`客户号` ASC) USING BTREE, + INDEX `idx_费用管理月份`(`月份` ASC) USING BTREE, + CONSTRAINT `费用管理表_ibfk_1` FOREIGN KEY (`客户号`) REFERENCES `客户信息表` (`客户号`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `费用管理表_chk_1` CHECK (`应收费用` >= 0), + CONSTRAINT `费用管理表_chk_2` CHECK (`收费标志` in (_utf8mb4'未收',_utf8mb4'已收')) +) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of 费用管理表 +-- ---------------------------- +INSERT INTO `费用管理表` VALUES (1, 'C001', '2024-12-01', 50.00, '未收'); +INSERT INTO `费用管理表` VALUES (2, 'C002', '2024-12-01', 250.00, '未收'); +INSERT INTO `费用管理表` VALUES (3, 'C003', '2024-12-01', 37.50, '未收'); +INSERT INTO `费用管理表` VALUES (4, 'C004', '2024-12-01', 45.00, '未收'); +INSERT INTO `费用管理表` VALUES (5, 'C005', '2024-12-01', 100.00, '已收'); +INSERT INTO `费用管理表` VALUES (6, 'C006', '2024-12-01', 200.00, '未收'); +INSERT INTO `费用管理表` VALUES (7, 'C007', '2024-12-01', 25.00, '已收'); +INSERT INTO `费用管理表` VALUES (8, 'C008', '2024-12-01', 52.50, '未收'); +INSERT INTO `费用管理表` VALUES (9, 'C009', '2024-12-01', 80.00, '未收'); +INSERT INTO `费用管理表` VALUES (10, 'C010', '2024-12-01', 300.00, '未收'); + +-- ---------------------------- +-- View structure for 区域业务员客户分布视图 +-- ---------------------------- +DROP VIEW IF EXISTS `区域业务员客户分布视图`; +CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `区域业务员客户分布视图` AS select `业务员表`.`姓名` AS `业务员姓名`,`业务员表`.`负责区域` AS `负责区域`,count(`客户信息表`.`客户号`) AS `客户数量`,sum(`客户信息表`.`结余金额`) AS `总余额` from (`业务员表` left join `客户信息表` on((`业务员表`.`负责区域` = `客户信息表`.`地址`))) group by `业务员表`.`姓名`,`业务员表`.`负责区域`; + +-- ---------------------------- +-- View structure for 客户总费用与已支付费用视图 +-- ---------------------------- +DROP VIEW IF EXISTS `客户总费用与已支付费用视图`; +CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `客户总费用与已支付费用视图` AS select `客户信息表`.`客户号` AS `客户编号`,`客户信息表`.`姓名` AS `客户姓名`,sum(`费用管理表`.`应收费用`) AS `总应收费用`,sum((case when (`收费登记表`.`实收费用` is not null) then `收费登记表`.`实收费用` else 0 end)) AS `已支付费用` from ((`客户信息表` join `费用管理表` on((`客户信息表`.`客户号` = `费用管理表`.`客户号`))) left join `收费登记表` on((`客户信息表`.`客户号` = `收费登记表`.`客户号`))) group by `客户信息表`.`客户号`,`客户信息表`.`姓名`; + +-- ---------------------------- +-- View structure for 客户用水信息视图 +-- ---------------------------- +DROP VIEW IF EXISTS `客户用水信息视图`; +CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `客户用水信息视图` AS select `客户信息表`.`客户号` AS `客户编号`,`客户信息表`.`姓名` AS `客户姓名`,`客户信息表`.`地址` AS `客户地址`,`用水信息表`.`月份` AS `用水月份`,`用水类型表`.`类别名` AS `用水类别`,`用水信息表`.`用水量` AS `用水量` from ((`客户信息表` join `用水信息表` on((`客户信息表`.`客户号` = `用水信息表`.`客户号`))) join `用水类型表` on((`用水信息表`.`用水类别号` = `用水类型表`.`类别号`))); + +-- ---------------------------- +-- View structure for 年度客户用水统计视图 +-- ---------------------------- +DROP VIEW IF EXISTS `年度客户用水统计视图`; +CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `年度客户用水统计视图` AS select `客户信息表`.`客户号` AS `客户编号`,`客户信息表`.`姓名` AS `客户姓名`,sum(`用水信息表`.`用水量`) AS `总用水量`,sum(`费用管理表`.`应收费用`) AS `总费用` from ((`客户信息表` join `用水信息表` on((`客户信息表`.`客户号` = `用水信息表`.`客户号`))) join `费用管理表` on((`客户信息表`.`客户号` = `费用管理表`.`客户号`))) where (`用水信息表`.`月份` between '2024-01-01' and '2024-12-31') group by `客户信息表`.`客户号`,`客户信息表`.`姓名`; + +-- ---------------------------- +-- View structure for 未收费用客户视图 +-- ---------------------------- +DROP VIEW IF EXISTS `未收费用客户视图`; +CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `未收费用客户视图` AS select `客户信息表`.`客户号` AS `客户编号`,`客户信息表`.`姓名` AS `客户姓名`,`客户信息表`.`联系方式` AS `联系方式`,`费用管理表`.`月份` AS `应缴月份`,`费用管理表`.`应收费用` AS `未缴金额` from (`客户信息表` join `费用管理表` on((`客户信息表`.`客户号` = `费用管理表`.`客户号`))) where (`费用管理表`.`收费标志` = '未收'); + +-- ---------------------------- +-- View structure for 订单详细信息视图 +-- ---------------------------- +DROP VIEW IF EXISTS `订单详细信息视图`; +CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `订单详细信息视图` AS select `订单管理表`.`订单编号` AS `订单编号`,`客户信息表`.`姓名` AS `客户姓名`,`用水类型表`.`类别名` AS `用水类别`,`订单管理表`.`用水量` AS `用水量`,`订单管理表`.`应收费用` AS `应收费用`,`订单管理表`.`实收费用` AS `实收费用` from ((`订单管理表` join `客户信息表` on((`订单管理表`.`客户号` = `客户信息表`.`客户号`))) join `用水类型表` on((`订单管理表`.`用水类别号` = `用水类型表`.`类别号`))); + +-- ---------------------------- +-- Procedure structure for 更新客户余额 +-- ---------------------------- +DROP PROCEDURE IF EXISTS `更新客户余额`; +delimiter ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `更新客户余额`( + IN p_customer_id VARCHAR(10), + IN p_received_amount DECIMAL(10, 2) +) +BEGIN + -- 更新客户余额 + UPDATE 客户信息表 + SET 结余金额 = 结余金额 - p_received_amount + WHERE 客户号 = p_customer_id; + + -- 确保余额不会变为负数 + IF (SELECT 结余金额 FROM 客户信息表 WHERE 客户号 = p_customer_id) < 0 THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '客户余额不足'; + END IF; +END +;; +delimiter ; + +-- ---------------------------- +-- Procedure structure for 更新收费状态 +-- ---------------------------- +DROP PROCEDURE IF EXISTS `更新收费状态`; +delimiter ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `更新收费状态`( + IN p_customer_id VARCHAR(10), + IN p_month DATE +) +BEGIN + -- 更新费用管理表中的收费标志 + UPDATE 费用管理表 + SET 收费标志 = '已收' + WHERE 客户号 = p_customer_id AND 月份 = p_month; + + -- 同时更新收费登记表中的状态 + UPDATE 收费登记表 + SET 实收费用 = (SELECT 应收费用 FROM 费用管理表 WHERE 客户号 = p_customer_id AND 月份 = p_month) + WHERE 客户号 = p_customer_id AND 月份 = p_month; +END +;; +delimiter ; + +-- ---------------------------- +-- Procedure structure for 生成客户费用记录 +-- ---------------------------- +DROP PROCEDURE IF EXISTS `生成客户费用记录`; +delimiter ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `生成客户费用记录`( + IN p_customer_id VARCHAR(10), + IN p_month DATE, + IN p_usage DECIMAL(10, 2), + IN p_unit_price DECIMAL(10, 2) +) +BEGIN + -- 计算应收费用 + DECLARE total_fee DECIMAL(10, 2); + SET total_fee = p_usage * p_unit_price; + + -- 插入费用记录 + INSERT INTO 费用管理表 (客户号, 月份, 应收费用, 收费标志) + VALUES (p_customer_id, p_month, total_fee, '未收'); +END +;; +delimiter ; + +-- ---------------------------- +-- Procedure structure for 生成订单记录 +-- ---------------------------- +DROP PROCEDURE IF EXISTS `生成订单记录`; +delimiter ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `生成订单记录`( + IN p_customer_id VARCHAR(10), + IN p_month DATE, + IN p_usage DECIMAL(10, 2), + IN p_type_id INT +) +BEGIN + -- 计算应收费用 + DECLARE fee DECIMAL(10, 2); + SET fee = p_usage * (SELECT 水价 FROM 用水类型表 WHERE 类别号 = p_type_id); + + -- 插入订单管理表 + INSERT INTO 订单管理表 (客户号, 月份, 用水类别号, 用水量, 应收费用, 实收费用) + VALUES (p_customer_id, p_month, p_type_id, p_usage, fee, 0); +END +;; +delimiter ; + +-- ---------------------------- +-- Procedure structure for 统计区域客户费用 +-- ---------------------------- +DROP PROCEDURE IF EXISTS `统计区域客户费用`; +delimiter ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `统计区域客户费用`( + IN p_area VARCHAR(50) +) +BEGIN + DECLARE total_fee DECIMAL(10, 2); + DECLARE total_balance DECIMAL(10, 2); + + -- 统计总费用 + SELECT SUM(费用管理表.应收费用) INTO total_fee + FROM 费用管理表 + JOIN 客户信息表 ON 费用管理表.客户号 = 客户信息表.客户号 + WHERE 客户信息表.地址 = p_area; + + -- 统计总余额 + SELECT SUM(客户信息表.结余金额) INTO total_balance + FROM 客户信息表 + WHERE 客户信息表.地址 = p_area; + + -- 输出结果 + SELECT CONCAT('区域: ', p_area, ' 总费用: ', total_fee, ' 总余额: ', total_balance) AS 区域统计; +END +;; +delimiter ; + +-- ---------------------------- +-- Triggers structure for table 客户信息表 +-- ---------------------------- +DROP TRIGGER IF EXISTS `trg_prevent_delete_customer`; +delimiter ;; +CREATE TRIGGER `trg_prevent_delete_customer` BEFORE DELETE ON `客户信息表` FOR EACH ROW BEGIN + -- 检查客户是否有未结清的费用 + IF EXISTS (SELECT 1 FROM 费用管理表 WHERE 客户号 = OLD.客户号 AND 收费标志 = '未收') THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '客户有未结清费用,无法删除'; + END IF; +END +;; +delimiter ; + +-- ---------------------------- +-- Triggers structure for table 收费登记表 +-- ---------------------------- +DROP TRIGGER IF EXISTS `触发更新结余金额`; +delimiter ;; +CREATE TRIGGER `触发更新结余金额` AFTER INSERT ON `收费登记表` FOR EACH ROW BEGIN + -- 更新客户信息表中的结余金额 + UPDATE 客户信息表 + SET 结余金额 = 结余金额 - NEW.实收费用 + WHERE 客户号 = NEW.客户号; +END +;; +delimiter ; + +-- ---------------------------- +-- Triggers structure for table 收费登记表 +-- ---------------------------- +DROP TRIGGER IF EXISTS `trg_update_balance`; +delimiter ;; +CREATE TRIGGER `trg_update_balance` AFTER INSERT ON `收费登记表` FOR EACH ROW BEGIN + -- 更新客户余额,减少相应的费用金额 + UPDATE 客户信息表 + SET 结余金额 = 结余金额 - NEW.实收费用 + WHERE 客户号 = NEW.客户号; + + -- 如果余额不足,抛出异常 + IF (SELECT 结余金额 FROM 客户信息表 WHERE 客户号 = NEW.客户号) < 0 THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '客户余额不足'; + END IF; +END +;; +delimiter ; + +-- ---------------------------- +-- Triggers structure for table 收费登记表 +-- ---------------------------- +DROP TRIGGER IF EXISTS `trg_update_fee_status_insert`; +delimiter ;; +CREATE TRIGGER `trg_update_fee_status_insert` AFTER INSERT ON `收费登记表` FOR EACH ROW BEGIN + IF NEW.实收费用 IS NOT NULL THEN + -- 更新费用管理表中的收费标志为“已收” + UPDATE 费用管理表 + SET 收费标志 = '已收' + WHERE 客户号 = NEW.客户号 AND 月份 = NEW.收费日期; + END IF; +END +;; +delimiter ; + +-- ---------------------------- +-- Triggers structure for table 收费登记表 +-- ---------------------------- +DROP TRIGGER IF EXISTS `trg_update_fee_status_update`; +delimiter ;; +CREATE TRIGGER `trg_update_fee_status_update` AFTER UPDATE ON `收费登记表` FOR EACH ROW BEGIN + IF NEW.实收费用 IS NOT NULL THEN + -- 更新费用管理表中的收费标志为“已收” + UPDATE 费用管理表 + SET 收费标志 = '已收' + WHERE 客户号 = NEW.客户号 AND 月份 = NEW.收费日期; + END IF; +END +;; +delimiter ; + +-- ---------------------------- +-- Triggers structure for table 用水信息表 +-- ---------------------------- +DROP TRIGGER IF EXISTS `trg_generate_fee_record`; +delimiter ;; +CREATE TRIGGER `trg_generate_fee_record` AFTER INSERT ON `用水信息表` FOR EACH ROW BEGIN + -- 计算应收费用 + DECLARE total_fee DECIMAL(10, 2); + SET total_fee = NEW.用水量 * (SELECT 水价 FROM 用水类型表 WHERE 类别号 = NEW.用水类别号); + + -- 插入费用管理表 + INSERT INTO 费用管理表 (客户号, 月份, 应收费用, 收费标志) + VALUES (NEW.客户号, NEW.月份, total_fee, '未收'); +END +;; +delimiter ; + +-- ---------------------------- +-- Triggers structure for table 订单管理表 +-- ---------------------------- +DROP TRIGGER IF EXISTS `trg_calculate_fee`; +delimiter ;; +CREATE TRIGGER `trg_calculate_fee` AFTER INSERT ON `订单管理表` FOR EACH ROW BEGIN + -- 计算应收费用 + DECLARE total_fee DECIMAL(10, 2); + SET total_fee = NEW.用水量 * (SELECT 水价 FROM 用水类型表 WHERE 类别号 = NEW.用水类别号); + + -- 更新订单中的应收费用 + UPDATE 订单管理表 + SET 应收费用 = total_fee + WHERE 订单编号 = NEW.订单编号; +END +;; +delimiter ; + +SET FOREIGN_KEY_CHECKS = 1;