add Address option

This commit is contained in:
lds217 committed 2025-01-26 03:41:13 -05:00
1 parent a6292aefb3
commit 423aa6601d
15 files changed
+374 -21

No files matched your search

@@ -4,6 +4,8 @@ import BsK.server.network.entity.Role;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.HashMap;
@AllArgsConstructor
@Data
public class LocalStorage {
@@ -12,4 +14,12 @@ public class LocalStorage {
public static String ClinicName = "Phòng khám BSK";
public static String ClinicAddress = "Số ABC, Đường XYZ, Quận 1, TP.HCM";
public static String ClinicPhone = "0123456789";
public static String[] doctorsName;
public static String[] provinces;
public static String[] districts;
public static String[] wards;
public static HashMap<String, String> provinceToId;
public static HashMap<String, String> districtToId;
public static HashMap<String, String[]> cachedDistricts; // cache local areas
public static HashMap<String, String[]> cachedWards; // cache local areas
}
@@ -5,11 +5,11 @@ import BsK.client.LocalStorage;
import BsK.client.ui.handler.UIHandler;
import BsK.common.packet.Packet;
import BsK.common.packet.PacketSerializer;
import BsK.common.packet.req.GetDoctorGeneralInfo;
import BsK.common.packet.req.GetMedInfoRequest;
import BsK.common.packet.req.GetProvinceRequest;
import BsK.common.packet.req.LoginRequest;
import BsK.common.packet.res.ClinicInfoResponse;
import BsK.common.packet.res.ErrorResponse;
import BsK.common.packet.res.HandshakeCompleteResponse;
import BsK.common.packet.res.LoginSuccessResponse;
import BsK.common.packet.res.*;
import BsK.common.util.network.NetworkUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
@@ -61,6 +61,9 @@ public class ClientHandler extends SimpleChannelInboundHandler<TextWebSocketFram
log.info("Handshake complete");
ClientHandler.ctx = ctx;
ClientHandler.frame = frame;
// If
UIHandler.INSTANCE.showUI();
// When the handshake is complete, the UI is shown
return; // No further processing needed for handshake response
@@ -74,6 +77,33 @@ public class ClientHandler extends SimpleChannelInboundHandler<TextWebSocketFram
return;
}
if (packet instanceof GetDoctorGeneralInfoResponse doctorGeneralInfoResponse) {
log.info("Doctor general info received: {}", doctorGeneralInfoResponse);
LocalStorage.doctorsName = doctorGeneralInfoResponse.getDoctorsName();
return;
}
if (packet instanceof GetProvinceResponse provinceResponse) {
log.info("Province info received: {}", provinceResponse);
LocalStorage.provinces = provinceResponse.getProvinces();
LocalStorage.provinceToId = provinceResponse.getProvinceToId();
return;
}
if (packet instanceof GetDistrictResponse districtResponse) {
log.info("District info received: {}", districtResponse);
LocalStorage.districts = districtResponse.getDistricts();
LocalStorage.districtToId = districtResponse.getDistrictToId();
log.info("District to id: {}", LocalStorage.districtToId);
return;
}
if (packet instanceof GetWardResponse wardResponse) {
log.info("Ward info received: {}", wardResponse);
LocalStorage.wards = wardResponse.getWards();
return;
}
listeners.forEach((key, value) -> {
log.debug("Key: {}", key.getName());
@@ -1,8 +1,11 @@
package BsK.client.ui.component.CheckUpPage.AddDialog;
import BsK.client.LocalStorage;
import BsK.client.network.handler.ClientHandler;
import BsK.client.network.handler.ResponseListener;
import BsK.common.packet.req.GetDoctorGeneralInfo;
import BsK.common.packet.req.GetRecentPatientRequest;
import BsK.common.packet.res.GetDoctorGeneralInfoResponse;
import BsK.common.packet.res.GetMedInfoResponse;
import BsK.common.packet.res.GetRecentPatientResponse;
import BsK.common.util.network.NetworkUtil;
@@ -16,6 +19,8 @@ import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@Slf4j
@@ -30,8 +35,9 @@ public class AddDialog extends JDialog {
private DefaultTableModel patientTableModel;
private JTable patientTable;
private String[] patientColumns = {"Patient ID", "Patient Name", "Patient Year", "Patient Phone" ,"Patient Address"};
private String[][] patientData; // {"P001", "Lê Thành Đạt", "1985", "1234567890", "123 Main St, Springfield"
private String[][] patientData;
private final ResponseListener<GetRecentPatientResponse> getRecentPatientResponseListener = this::getRecentPatientHandler;
private JComboBox doctorComboBox;
private void sendGetRecentPatientRequest() {
log.info("Sending GetRecentPatientRequest");
@@ -39,22 +45,27 @@ public class AddDialog extends JDialog {
NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetRecentPatientRequest());
}
void getRecentPatientHandler(GetRecentPatientResponse response) {
private void getRecentPatientHandler(GetRecentPatientResponse response) {
log.info("Received GetRecentPatientResponse");
patientData = response.getPatientData();
patientTableModel.setDataVector(patientData, patientColumns);
}
public AddDialog(Frame parent) {
super(parent, "Add Patient", true);
// Set size of the dialog
setSize(1000, 400);
// Put in the middle
setLocationRelativeTo(null);
setResizable(true);
// Send request to get the latest 20 patients in the database
sendGetRecentPatientRequest();
// Add patent table on the right side
// Add a scroll pane to the table
patientTableModel = new DefaultTableModel(patientData, patientColumns) {
@@ -70,6 +81,18 @@ public class AddDialog extends JDialog {
patientTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollPane = new JScrollPane(patientTable);
patientTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(() -> {
int selectedRow = patientTable.getSelectedRow();
if (selectedRow != -1) {
handleRowSelection(selectedRow);
}
});
}
});
// Set layout of the dialog
// left side is the text fields, right side is the patient list
@@ -150,6 +173,16 @@ public class AddDialog extends JDialog {
}
});
gbc.gridx = 0;
gbc.gridy++;
inputPanel.add(new JLabel("Doctor:"), gbc);
gbc.gridwidth = 3;
gbc.gridx = 1;
doctorComboBox = new JComboBox<>(LocalStorage.doctorsName);
inputPanel.add(doctorComboBox, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 1;
@@ -163,7 +196,7 @@ public class AddDialog extends JDialog {
inputPanel.add(new JLabel("Patient gender:"), gbc);
gbc.gridx = 3;
patientGenderField = new JComboBox(new String[]{"Nam", "Nữ"});
patientGenderField = new JComboBox<>(new String[]{"Nam", "Nữ"});
inputPanel.add(patientGenderField, gbc);
gbc.gridx = 0;
@@ -237,11 +270,12 @@ public class AddDialog extends JDialog {
String patientYear = patientTable.getValueAt(selectedRow, 2).toString();
String patientPhone = patientTable.getValueAt(selectedRow, 3).toString();
String patientAddress = patientTable.getValueAt(selectedRow, 4).toString();
String patientGender = patientData[selectedRow][5];
patientIdField.setText(patientId);
patientNameField.setText(patientName);
patientYearField.setText(patientYear);
patientPhoneField.setText(patientPhone);
patientGenderField.setSelectedItem(patientGender);
// Extract province, district, village from the address
String[] addressParts = patientAddress.split(", ");
@@ -10,9 +10,7 @@ import BsK.client.ui.component.CheckUpPage.ServiceDialog.ServiceDialog;
import BsK.client.ui.component.MainFrame;
import BsK.client.ui.component.common.DateLabelFormatter;
import BsK.client.ui.component.common.RoundedPanel;
import BsK.common.packet.req.GetCheckUpQueueRequest;
import BsK.common.packet.req.GetCustomerHistoryRequest;
import BsK.common.packet.req.GetDoctorGeneralInfo;
import BsK.common.packet.req.*;
import BsK.common.packet.res.ErrorResponse;
import BsK.common.packet.res.GetCheckUpQueueResponse;
import BsK.common.packet.res.GetCustomerHistoryResponse;
@@ -28,6 +26,8 @@ import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.ParseException;
@@ -42,12 +42,12 @@ public class CheckUpPage extends JPanel {
private String[][] history;
private DefaultTableModel model, historyModel;
private JTable table1, historyTable;
private final ResponseListener<GetDoctorGeneralInfoResponse> doctorGeneralInfoListener = this::handleGetDoctorGeneralInfoResponse;
private final ResponseListener<GetCheckUpQueueResponse> checkUpQueueListener = this::handleGetCheckUpQueueResponse;
private final ResponseListener<GetCustomerHistoryResponse> customerHistoryListener = this::handleGetCustomerHistoryResponse;
private JTextField checkupIdField, customerLastNameField, customerFirstNameField,customerAddressField, customerPhoneField, customerIdField;
private JTextArea symptomsField, diagnosisField, notesField;
private JComboBox<String> doctorComboBox, statusComboBox, genderComboBox;
private JComboBox<String> doctorComboBox, statusComboBox, genderComboBox, provinceComboBox, districtComboBox, wardComboBox;
private JSpinner customerWeightSpinner, customerHeightSpinner;
private JDatePickerImpl datePicker, dobPicker;
private String[][] medicinePrescription;
@@ -66,10 +66,6 @@ public class CheckUpPage extends JPanel {
NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetCheckUpQueueRequest());
}
public void getDoctors() {
ClientHandler.addResponseListener(GetDoctorGeneralInfoResponse.class, doctorGeneralInfoListener);
NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetDoctorGeneralInfo());
}
public CheckUpPage(MainFrame mainFrame) {
setLayout(new BorderLayout());
@@ -77,7 +73,6 @@ public class CheckUpPage extends JPanel {
// add history listener
ClientHandler.addResponseListener(GetCustomerHistoryResponse.class, customerHistoryListener);
updateQueue();
getDoctors();
// Navigation bar
// navBar panel
@@ -328,6 +323,92 @@ public class CheckUpPage extends JPanel {
customerAddressField = new JTextField();
inputPanel.add(customerAddressField, gbc);
gbc.gridy++;
gbc.gridx = 1;
gbc.gridwidth = 1;
provinceComboBox = new JComboBox<>(LocalStorage.provinces);
inputPanel.add(provinceComboBox, gbc);
gbc.gridx = 2;
districtComboBox = new JComboBox<>(new String[]{"Huyện 1", "Huyện 2", "Huyện 3"});
inputPanel.add(districtComboBox, gbc);
// set not editable
districtComboBox.setEnabled(false);
gbc.gridx = 3;
wardComboBox = new JComboBox<>(new String[]{"Phường 1", "Phường 2", "Phường 3"});
inputPanel.add(wardComboBox, gbc);
// set not editable
wardComboBox.setEnabled(false);
// Province ComboBox Listener
provinceComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int selectedIndex = provinceComboBox.getSelectedIndex();
DefaultComboBoxModel<String> districtModel = new DefaultComboBoxModel<>(new String[]{"Quận/Huyện"});
districtComboBox.setModel(districtModel); // Set district combo box model
if (selectedIndex != 0) { // If the selected index is not 0 (which corresponds to "Tỉnh/Thành phố")
NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetDistrictRequest(LocalStorage.provinceToId
.get(provinceComboBox.getSelectedItem().toString())));
while (LocalStorage.districts == null || districtComboBox.getItemCount() <= 1) {
try {
Thread.sleep(100); // Wait for the district data to be fetched
if(LocalStorage.districts != null) {
districtModel = new DefaultComboBoxModel<>(LocalStorage.districts);
districtComboBox.setModel(districtModel);
}
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
}
// Set district combo box model
districtComboBox.setEnabled(true); // Enable district combo box
wardComboBox.setSelectedItem("Xã/Phường"); // Set ward combo box to default value
wardComboBox.setEnabled(false);
} else {
districtComboBox.setEnabled(false); // Disable district combo box if "Tỉnh/Thành phố" is selected
wardComboBox.setEnabled(false); // Disable ward combo box as well
}
}
});
// District ComboBox Listener
districtComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int selectedIndex = districtComboBox.getSelectedIndex();
DefaultComboBoxModel<String> wardModel = new DefaultComboBoxModel<>(new String[]{"Xã/Phường"});
wardComboBox.setModel(wardModel); // Set district combo box model
if (selectedIndex != 0) { // If the selected index is not 0 (which corresponds to "Quận/Huyện")
NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetWardRequest(LocalStorage.districtToId
.get(districtComboBox.getSelectedItem().toString())));
log.info("Sending GetWardRequest with district ID: {}", LocalStorage.districtToId
.get(districtComboBox.getSelectedItem().toString()));
while (LocalStorage.wards == null || wardComboBox.getItemCount() <= 1) {
try {
Thread.sleep(100); // Wait for the district data to be fetched
if(LocalStorage.wards != null) {
wardModel = new DefaultComboBoxModel<>(LocalStorage.wards);
wardComboBox.setModel(wardModel);
}
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
}
wardComboBox.setSelectedItem("Xã/Phường"); // Set ward combo box to default value
wardComboBox.setEnabled(true); // Enable ward combo box
} else {
districtComboBox.setEnabled(false); // Disable district combo box if "Tỉnh/Thành phố" is selected
wardComboBox.setEnabled(false); // Disable ward combo box as well
}
}
});
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 1;
@@ -359,7 +440,6 @@ public class CheckUpPage extends JPanel {
customerHeightSpinner = new JSpinner(heightModel);
inputPanel.add(customerHeightSpinner, gbc);
JLabel checkupInfoLabel = new JLabel("Thông tin khám bệnh");
checkupInfoLabel.setFont(checkupInfoLabel.getFont().deriveFont(Font.BOLD, 16)); // Bold, size 16
checkupInfoLabel.setHorizontalAlignment(SwingConstants.CENTER);
@@ -404,7 +484,7 @@ public class CheckUpPage extends JPanel {
gbc.gridwidth = 3;
gbc.gridx = 1;
doctorComboBox = new JComboBox<>(doctorOptions);
doctorComboBox = new JComboBox<>(LocalStorage.doctorsName);
inputPanel.add(doctorComboBox, gbc);
gbc.gridwidth = 1;
@@ -712,6 +792,7 @@ public class CheckUpPage extends JPanel {
private void handleGetDoctorGeneralInfoResponse(GetDoctorGeneralInfoResponse response) {
log.info("Received doctor general info");
this.doctorOptions = response.getDoctorsName();
LocalStorage.doctorsName = response.getDoctorsName();
}
private void handleGetCheckUpQueueResponse(GetCheckUpQueueResponse response) {
@@ -6,6 +6,8 @@ import BsK.client.ui.component.MainFrame;
import BsK.common.packet.Packet;
import BsK.common.packet.PacketSerializer;
import BsK.common.packet.req.ClinicInfoRequest;
import BsK.common.packet.req.GetDoctorGeneralInfo;
import BsK.common.packet.req.GetProvinceRequest;
import BsK.common.packet.req.LoginRequest;
import BsK.common.packet.res.ErrorResponse;
import BsK.common.packet.res.LoginSuccessResponse;
@@ -89,6 +91,8 @@ public class LoginPage extends JPanel {
log.info("Login successful, UserId: {}, Role: {}", response.getUserId(), response.getRole());
LocalStorage.username = loginField.getText();
NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new ClinicInfoRequest()); // Request clinic info
NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetDoctorGeneralInfo()); // Request doctor info
NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetProvinceRequest()); // Request province info
mainFrame.showPage("DashboardPage");
});
@@ -0,0 +1,13 @@
package BsK.common.packet.req;
import BsK.common.packet.Packet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@AllArgsConstructor
@Data
public class GetDistrictRequest implements Packet {
String provinceId;
}
@@ -0,0 +1,12 @@
package BsK.common.packet.req;
import BsK.common.packet.Packet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@AllArgsConstructor
@Data
public class GetProvinceRequest implements Packet {
}
@@ -0,0 +1,14 @@
package BsK.common.packet.req;
import BsK.common.packet.Packet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@AllArgsConstructor
@Data
@Slf4j
public class GetWardRequest implements Packet {
String districtId;
}
@@ -20,5 +20,6 @@ public class ErrorResponse implements Packet {
USERNAME_NOT_FOUND,
PASSWORD_INCORRECT,
USER_ALREADY_EXISTS,INVALID_CREDENTIALS,
SQL_EXCEPTION,
}
}
@@ -0,0 +1,16 @@
package BsK.common.packet.res;
import BsK.common.packet.Packet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
@Slf4j
@Data
@AllArgsConstructor
public class GetDistrictResponse implements Packet {
String[] districts;
HashMap<String, String> districtToId;
}
@@ -0,0 +1,16 @@
package BsK.common.packet.res;
import BsK.common.packet.Packet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
@Slf4j
@AllArgsConstructor
@Data
public class GetProvinceResponse implements Packet {
String[] provinces;
HashMap<String, String> provinceToId;
}
@@ -0,0 +1,13 @@
package BsK.common.packet.res;
import BsK.common.packet.Packet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@AllArgsConstructor
@Data
public class GetWardResponse implements Packet {
String[] wards;
}
+1 -1
View File
@@ -27,7 +27,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Server {
private static final int PORT = 1999;
static Connection connection;
public static Connection connection;
static {
try {
@@ -6,6 +6,7 @@ import BsK.common.packet.req.*;
import BsK.common.packet.res.*;
import BsK.common.packet.res.ErrorResponse.Error;
import BsK.common.util.date.DateUtils;
import BsK.server.Server;
import BsK.server.network.manager.SessionManager;
import BsK.server.network.util.UserUtil;
import io.netty.channel.ChannelHandlerContext;
@@ -15,17 +16,21 @@ import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.Han
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import lombok.extern.slf4j.Slf4j;
import static BsK.server.Server.statement;
@Slf4j
public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@@ -344,6 +349,110 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
throw new RuntimeException(e);
}
}
if (packet instanceof GetProvinceRequest getProvinceRequest) {
log.debug("Received GetProvinceRequest");
try {
ResultSet rs = statement.executeQuery(
"select provinces.code, provinces.name\n" +
"from provinces" +
" order by provinces.name"
);
if (!rs.isBeforeFirst()) {
System.out.println("No data found in the province table.");
} else {
ArrayList<String> resultList = new ArrayList<>();
HashMap<String, String> provinceIdMap = new HashMap<>();
resultList.add("Tỉnh/Thành phố");
while (rs.next()) {
String provinceId = rs.getString("code");
String provinceName = rs.getString("name");
provinceIdMap.put(provinceName, provinceId);
resultList.add(provinceName);
}
String[] resultString = resultList.toArray(new String[0]);
UserUtil.sendPacket(user.getSessionId(), new GetProvinceResponse(resultString, provinceIdMap));
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (packet instanceof GetDistrictRequest getDistrictRequest) {
log.debug("Received GetDistrictRequest");
try{
PreparedStatement preparedStatement = Server.connection.prepareStatement(
"SELECT districts.code, districts.name " +
" FROM districts " +
" WHERE province_code = ? " +
" ORDER BY districts.name"
);
preparedStatement.setString(1, getDistrictRequest.getProvinceId());
ResultSet rs = preparedStatement.executeQuery();
if (!rs.isBeforeFirst()) {
System.out.println("No data found in the district table.");
} else {
ArrayList<String> resultList = new ArrayList<>();
HashMap<String, String> districtIdMap = new HashMap<>();
resultList.add("Quận/Huyện");
while (rs.next()) {
String districtId = rs.getString("code");
String districtName = rs.getString("name");
districtIdMap.put(districtName, districtId);
resultList.add(districtName);
}
String[] resultString = resultList.toArray(new String[0]);
UserUtil.sendPacket(user.getSessionId(), new GetDistrictResponse(resultString, districtIdMap));
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (packet instanceof GetWardRequest getWardRequest) {
log.debug("Received GetWardRequest");
try{
PreparedStatement preparedStatement = Server.connection.prepareStatement(
"SELECT wards.code, wards.name \n" +
" FROM wards\n" +
" WHERE district_code = ? " +
" ORDER BY wards.name"
);
preparedStatement.setString(1, getWardRequest.getDistrictId());
ResultSet rs = preparedStatement.executeQuery();
if (!rs.isBeforeFirst()) {
System.out.println("No data found in the district table.");
} else {
ArrayList<String> resultList = new ArrayList<>();
HashMap<String, String> districtIdMap = new HashMap<>();
resultList.add("Xã/Phường");
while (rs.next()) {
String districtId = rs.getString("code");
String districtName = rs.getString("name");
districtIdMap.put(districtName, districtId);
resultList.add(districtName);
}
String[] resultString = resultList.toArray(new String[0]);
UserUtil.sendPacket(user.getSessionId(), new GetWardResponse(resultString));
}
} catch (SQLException e) {
UserUtil.sendPacket(user.getSessionId(), new ErrorResponse(Error.SQL_EXCEPTION));
throw new RuntimeException(e);
}
}
}
}
Binary file not shown.