2025年3月31日18:17:15
parent
b81f2a1801
commit
f0a6466feb
|
|
@ -59,7 +59,7 @@ public class ApiUtils {
|
|||
|
||||
public static DataView getUserList() {
|
||||
DataLoad dataLoad = new UserDataLoad();
|
||||
dataLoad.setForm(new UserForm());
|
||||
dataLoad.setForm(new UserForm(true));
|
||||
return dataLoad.loadData(PAGE_NUM,PAGE_SIZE);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.zhangmeng.online.exam.ui.components.DynamicTableComponent;
|
|||
import com.zhangmeng.online.exam.ui.components.callBack.DynamicTableComponentCallBack;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.PasswordField;
|
||||
|
|
@ -16,6 +17,7 @@ import javafx.scene.layout.AnchorPane;
|
|||
import javafx.stage.Stage;
|
||||
import javafx.stage.Window;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -31,6 +33,18 @@ public class UserForm extends Form {
|
|||
private TextField phone_field;
|
||||
private TextField email_field;
|
||||
|
||||
private boolean isfxml = true;
|
||||
|
||||
public UserForm(boolean isfxml) {
|
||||
this.isfxml = isfxml;
|
||||
try {
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/user-edit.fxml"));
|
||||
this.getChildren().add(fxmlLoader.load());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public UserForm() {
|
||||
|
||||
Label username_label = new Label("用户名:");
|
||||
|
|
@ -144,4 +158,12 @@ public class UserForm extends Form {
|
|||
public void setEmail_field(TextField email_field) {
|
||||
this.email_field = email_field;
|
||||
}
|
||||
|
||||
public boolean isIsfxml() {
|
||||
return isfxml;
|
||||
}
|
||||
|
||||
public void setIsfxml(boolean isfxml) {
|
||||
this.isfxml = isfxml;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public class UserDataLoad implements DataLoad {
|
|||
@Override
|
||||
public void editData(String id,Stage stage) {
|
||||
|
||||
UserForm userForm = new UserForm();
|
||||
UserForm userForm = new UserForm(true);
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("id", id);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.zhangmeng.online.exam.ui.api.form.UserForm;
|
|||
import com.zhangmeng.online.exam.ui.api.form.base.Form;
|
||||
import com.zhangmeng.online.exam.ui.components.DynamicTableComponent;
|
||||
import com.zhangmeng.online.exam.ui.utils.AlertUtils;
|
||||
import com.zhangmeng.online.exam.ui.utils.FxUtils;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.Node;
|
||||
|
|
@ -42,9 +43,10 @@ public class DynamicTableComponentCallBackImpl implements DynamicTableComponentC
|
|||
|
||||
@Override
|
||||
public void Add(Parent node, Stage primaryStage, DynamicTableComponent table) {
|
||||
Form form = (Form) node;
|
||||
form.setTableComponent(table);
|
||||
AlertUtils.alert("设置", node, primaryStage);
|
||||
// Form form = (Form) node;
|
||||
// form.setTableComponent(table);
|
||||
// AlertUtils.alert("设置", node, primaryStage);
|
||||
FxUtils.alert("设置",node, primaryStage);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -5,13 +5,18 @@ import com.zhangmeng.online.exam.ui.admin.IndexPage;
|
|||
import com.zhangmeng.online.exam.ui.admin.LoginPage;
|
||||
import com.zhangmeng.online.exam.ui.admin.PaperPage;
|
||||
import com.zhangmeng.online.exam.ui.api.ApiUtils;
|
||||
import com.zhangmeng.online.exam.ui.module.User;
|
||||
import com.zhangmeng.online.exam.ui.service.UserService;
|
||||
import com.zhangmeng.online.exam.ui.utils.AlertUtils;
|
||||
import com.zhangmeng.online.exam.ui.utils.FxUtils;
|
||||
import com.zhangmeng.online.exam.ui.utils.HttpUtils;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.concurrent.ScheduledService;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
|
|
@ -21,6 +26,7 @@ import javafx.scene.image.ImageView;
|
|||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -79,8 +85,15 @@ public class LoginController {
|
|||
Map<String, Object> data = (Map<String, Object>) jsonObject.get("data");
|
||||
Object token = data.get("token");
|
||||
HttpUtils.USER_INFO.put("token", token);
|
||||
new Thread(this::user_type).start();
|
||||
Alert alert = AlertUtils.alert_msg(jsonObject.getString("message"));
|
||||
|
||||
User user = new User();
|
||||
user.setUsername(username.getText());
|
||||
user.setPassword(password.getText());
|
||||
user.setToken(token.toString());
|
||||
UserService.setCurrentUser(user);
|
||||
|
||||
new Thread(UserService::user_type).start();
|
||||
// Alert alert = AlertUtils.alert_msg(jsonObject.getString("message"));
|
||||
|
||||
LoginController.MyScheduledService myService = new LoginController.MyScheduledService();
|
||||
//myService.setDelay(Duration.seconds(5));//延迟
|
||||
|
|
@ -112,7 +125,7 @@ public class LoginController {
|
|||
System.out.println("lastValueProperty:" + newValue.intValue());
|
||||
if (newValue.intValue() == 3) {
|
||||
myService.cancel();
|
||||
alert.close();
|
||||
//alert.close();
|
||||
success();
|
||||
}
|
||||
}
|
||||
|
|
@ -127,21 +140,10 @@ public class LoginController {
|
|||
}
|
||||
}
|
||||
|
||||
private void user_type() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("token", HttpUtils.USER_INFO.get("token"));
|
||||
String response = HttpUtils.GET(ApiUtils.API_URL + "/user/getUserInfo", params);
|
||||
JSONObject jsonObject = JSONObject.parseObject(response);
|
||||
if (jsonObject.getIntValue("code") == 200) {
|
||||
Map<String, Object> data = (Map<String, Object>) jsonObject.get("data");
|
||||
String type = data.get("type").toString();
|
||||
HttpUtils.USER_INFO.put("type", type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void success() {
|
||||
String type = HttpUtils.USER_INFO.get("type").toString();
|
||||
|
||||
String type = UserService.getCurrentUser().getRoleType();
|
||||
switch (type) {
|
||||
case "STUDENT" -> user_page();
|
||||
case "ADMIN" -> admin_page();
|
||||
|
|
@ -166,15 +168,15 @@ public class LoginController {
|
|||
private void admin_page() {
|
||||
Scene scene = loginButton.getScene();
|
||||
Stage window = (Stage) scene.getWindow();
|
||||
window.close();
|
||||
|
||||
Stage stage = new Stage();
|
||||
IndexPage indexPage = new IndexPage();
|
||||
|
||||
scene = new Scene(indexPage, 1280, 720);
|
||||
stage.setScene(scene);
|
||||
stage.setTitle("在线考试系统");
|
||||
stage.show();
|
||||
// IndexPage indexPage = new IndexPage();
|
||||
try {
|
||||
Parent main = FXMLLoader.load(this.getClass().getResource("/fxml/main.fxml"));
|
||||
scene = new Scene(main, FxUtils.DEFAULT_WIDTH, FxUtils.DEFAULT_HEIGHT);
|
||||
window.setScene(scene);
|
||||
window.centerOnScreen();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
class MyScheduledService extends ScheduledService<Number> {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,184 @@
|
|||
package com.zhangmeng.online.exam.ui.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.zhangmeng.online.exam.ui.admin.IndexPage;
|
||||
import com.zhangmeng.online.exam.ui.admin.UserListPage;
|
||||
import com.zhangmeng.online.exam.ui.api.ApiUtils;
|
||||
import com.zhangmeng.online.exam.ui.components.DynamicTableComponent;
|
||||
import com.zhangmeng.online.exam.ui.components.callBack.DynamicTableComponentCallBackImpl;
|
||||
import com.zhangmeng.online.exam.ui.layouts.SideMenu;
|
||||
import com.zhangmeng.online.exam.ui.module.MenuData;
|
||||
import com.zhangmeng.online.exam.ui.module.User;
|
||||
import com.zhangmeng.online.exam.ui.utils.FxUtils;
|
||||
import com.zhangmeng.online.exam.ui.utils.HttpUtils;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.zhangmeng.online.exam.ui.service.UserService;
|
||||
import javafx.util.Callback;
|
||||
|
||||
/**
|
||||
* @author zm
|
||||
* @date 2025/3/31 15:17
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class MainController {
|
||||
|
||||
@FXML
|
||||
private TreeView<MenuData> menuTree;
|
||||
|
||||
@FXML
|
||||
private TabPane contentTabPane;
|
||||
|
||||
@FXML
|
||||
private Label userLabel;
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
initializeMenu();
|
||||
// 显示当前用户
|
||||
User currentUser = UserService.getCurrentUser();
|
||||
if (currentUser != null) {
|
||||
userLabel.setText("当前用户:" + currentUser.getUsername());
|
||||
}
|
||||
|
||||
// 添加菜单点击事件
|
||||
menuTree.setOnMouseClicked(event -> {
|
||||
TreeItem<MenuData> selectedItem = menuTree.getSelectionModel().getSelectedItem();
|
||||
if (selectedItem != null && selectedItem.isLeaf()) {
|
||||
openTab(selectedItem.getValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initializeMenu() {
|
||||
TreeItem<MenuData> root = new TreeItem<>(new MenuData("系统菜单", null, null));
|
||||
root.setGraphic(new Label(root.getValue().getTitle()));
|
||||
root.setExpanded(true);
|
||||
|
||||
menuTree.setCellFactory(new Callback<TreeView<MenuData>, TreeCell<MenuData>>() {
|
||||
@Override
|
||||
public TreeCell<MenuData> call(TreeView<MenuData> menuDataTreeView) {
|
||||
return new TreeCell<MenuData>() {
|
||||
@Override
|
||||
protected void updateItem(MenuData item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (!empty) {
|
||||
HBox hBox = new HBox();
|
||||
hBox.setAlignment(Pos.CENTER);
|
||||
Label label = new Label(item.getTitle());
|
||||
hBox.getChildren().addAll(label);
|
||||
hBox.setMaxWidth(50);
|
||||
this.setGraphic(hBox);
|
||||
} else {
|
||||
this.setGraphic(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
root.getChildren().addAll(UserService.menu_tree_item());
|
||||
menuTree.setRoot(root);
|
||||
|
||||
ContextMenu contextMenu = new ContextMenu();
|
||||
MenuItem close_current_tab = new MenuItem("关闭当前标签");
|
||||
|
||||
close_current_tab.setOnAction(actionEvent -> {
|
||||
Tab selectedItem = contentTabPane.getSelectionModel().getSelectedItem();
|
||||
contentTabPane.getTabs().remove(selectedItem);
|
||||
});
|
||||
|
||||
MenuItem close_all_tab = new MenuItem("关闭全部标签");
|
||||
close_all_tab.setOnAction(actionEvent -> {
|
||||
contentTabPane.getTabs().clear();
|
||||
});
|
||||
|
||||
|
||||
contextMenu.getItems().add(close_current_tab);
|
||||
contextMenu.getItems().add(close_all_tab);
|
||||
contentTabPane.setContextMenu(contextMenu);
|
||||
}
|
||||
|
||||
private void openTab(MenuData menuData) {
|
||||
// 检查是否已经存在相同的标签页
|
||||
for (Tab tab : contentTabPane.getTabs()) {
|
||||
MenuData userData = (MenuData) tab.getUserData();
|
||||
if (userData.getUrl().equals(menuData.getUrl())) {
|
||||
contentTabPane.getSelectionModel().select(tab);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 创建新的标签页
|
||||
Tab tab = new Tab(menuData.getTitle());
|
||||
tab.setUserData(menuData);
|
||||
|
||||
// 根据标题加载不同的内容
|
||||
Node content = switch (menuData.getUrl()) {
|
||||
case "/user/list" -> init_table( ApiUtils.getUserList());
|
||||
case "添加用户" -> FXMLLoader.load(getClass().getResource("/fxml/user-edit.fxml"));
|
||||
case "角色列表" -> FXMLLoader.load(getClass().getResource("/fxml/role-list.fxml"));
|
||||
case "权限分配" -> FXMLLoader.load(getClass().getResource("/fxml/role-permission.fxml"));
|
||||
case "基本设置" -> FXMLLoader.load(getClass().getResource("/fxml/setting.fxml"));
|
||||
case "日志查看" -> FXMLLoader.load(getClass().getResource("/fxml/log.fxml"));
|
||||
case "公告列表" -> FXMLLoader.load(getClass().getResource("/fxml/notice-list.fxml"));
|
||||
case "发布公告" -> FXMLLoader.load(getClass().getResource("/fxml/notice-edit.fxml"));
|
||||
case "在线用户" -> FXMLLoader.load(getClass().getResource("/fxml/monitor-online.fxml"));
|
||||
case "系统日志" -> FXMLLoader.load(getClass().getResource("/fxml/monitor-log.fxml"));
|
||||
case "性能监控" -> FXMLLoader.load(getClass().getResource("/fxml/monitor-performance.fxml"));
|
||||
case "数据监控" -> FXMLLoader.load(getClass().getResource("/fxml/monitor-data.fxml"));
|
||||
default -> new Label("这是" + menuData.getTitle() + "的内容页面");
|
||||
};
|
||||
|
||||
tab.setContent(content);
|
||||
contentTabPane.getTabs().add(tab);
|
||||
contentTabPane.getSelectionModel().select(tab);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("错误");
|
||||
alert.setHeaderText(null);
|
||||
alert.setContentText("加载页面失败:" + e.getMessage());
|
||||
alert.showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
private DynamicTableComponent init_table(ApiUtils.DataView dataView) {
|
||||
dataView.setPageNum(dataView.getPageNum());
|
||||
dataView.setPageSize(dataView.getPageSize());
|
||||
dataView.setTotal(dataView.getTotal());
|
||||
DynamicTableComponent dynamicTableComponent = new DynamicTableComponent(dataView);
|
||||
dynamicTableComponent.setCallBack(new DynamicTableComponentCallBackImpl(dataView.getDataLoad(),dataView.getDataLoad().getForm()));
|
||||
dynamicTableComponent.setPadding(new Insets(15));
|
||||
dynamicTableComponent.prefHeightProperty().bind(contentTabPane.heightProperty().subtract(15));
|
||||
return dynamicTableComponent;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleLogout() {
|
||||
try {
|
||||
UserService.logout();
|
||||
Parent root = FXMLLoader.load(getClass().getResource("/fxml/login.fxml"));
|
||||
Stage stage = (Stage) userLabel.getScene().getWindow();
|
||||
stage.setScene(new Scene(root));
|
||||
stage.centerOnScreen();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
package com.zhangmeng.online.exam.ui.controller;
|
||||
|
||||
import com.zhangmeng.online.exam.ui.module.Role;
|
||||
import com.zhangmeng.online.exam.ui.module.User;
|
||||
import com.zhangmeng.online.exam.ui.service.LogService;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.CheckBoxListCell;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import com.zhangmeng.online.exam.ui.service.RoleService;
|
||||
import com.zhangmeng.online.exam.ui.service.UserService;
|
||||
|
||||
/**
|
||||
* @author zm
|
||||
* @date 2025/3/31 16:59
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class UserEditController {
|
||||
@FXML
|
||||
private TextField usernameField;
|
||||
|
||||
@FXML
|
||||
private TextField nameField;
|
||||
|
||||
@FXML
|
||||
private PasswordField passwordField;
|
||||
|
||||
@FXML
|
||||
private TextField emailField;
|
||||
|
||||
@FXML
|
||||
private ComboBox<String> statusComboBox;
|
||||
|
||||
@FXML
|
||||
private ListView<Role> roleListView;
|
||||
|
||||
private User user;
|
||||
private boolean saveClicked = false;
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
// 初始化状态下拉框
|
||||
statusComboBox.getItems().addAll("启用", "禁用");
|
||||
statusComboBox.setValue("启用");
|
||||
|
||||
// 初始化角色列表
|
||||
roleListView.setItems(FXCollections.observableArrayList(RoleService.getAllRoles()));
|
||||
roleListView.setCellFactory(CheckBoxListCell.forListView(role -> {
|
||||
return role.selectedProperty();
|
||||
}));
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
|
||||
usernameField.setText(user.getUsername());
|
||||
nameField.setText(user.getName());
|
||||
emailField.setText(user.getEmail());
|
||||
statusComboBox.setValue(user.getStatus());
|
||||
|
||||
// 设置已有角色的选中状态
|
||||
user.getRoles().forEach(role -> {
|
||||
role.setSelected(true);
|
||||
});
|
||||
|
||||
// 编辑模式下禁用用户名修改
|
||||
usernameField.setDisable(true);
|
||||
// 编辑模式下密码为可选
|
||||
passwordField.setPromptText("不修改请留空");
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleSave() {
|
||||
if (!validateInput()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (user == null) {
|
||||
// 创建新用户
|
||||
user = new User();
|
||||
user.setUsername(usernameField.getText());
|
||||
user.setPassword(passwordField.getText());
|
||||
} else if (!passwordField.getText().isEmpty()) {
|
||||
// 如果输入了新密码,则更新密码
|
||||
user.setPassword(passwordField.getText());
|
||||
}
|
||||
|
||||
// 更新基本信息
|
||||
user.setName(nameField.getText());
|
||||
user.setEmail(emailField.getText());
|
||||
user.setStatus(statusComboBox.getValue());
|
||||
|
||||
// 更新角色
|
||||
user.getRoles().clear();
|
||||
roleListView.getItems().stream()
|
||||
.filter(Role::isSelected)
|
||||
.forEach(user::addRole);
|
||||
|
||||
// 保存用户
|
||||
if (user.getId() == 0) {
|
||||
UserService.createUser(user);
|
||||
LogService.log("用户管理", "创建", "创建用户:" + user.getUsername());
|
||||
} else {
|
||||
UserService.updateUser(user);
|
||||
LogService.log("用户管理", "更新", "更新用户:" + user.getUsername());
|
||||
}
|
||||
|
||||
saveClicked = true;
|
||||
closeDialog();
|
||||
} catch (Exception e) {
|
||||
LogService.log("用户管理", "保存", "保存用户失败", e);
|
||||
showError("保存失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleCancel() {
|
||||
closeDialog();
|
||||
}
|
||||
|
||||
private boolean validateInput() {
|
||||
StringBuilder errorMessage = new StringBuilder();
|
||||
|
||||
if (usernameField.getText() == null || usernameField.getText().trim().isEmpty()) {
|
||||
errorMessage.append("用户名不能为空!\n");
|
||||
}
|
||||
if (nameField.getText() == null || nameField.getText().trim().isEmpty()) {
|
||||
errorMessage.append("姓名不能为空!\n");
|
||||
}
|
||||
if (user == null && (passwordField.getText() == null || passwordField.getText().trim().isEmpty())) {
|
||||
errorMessage.append("密码不能为空!\n");
|
||||
}
|
||||
if (emailField.getText() == null || emailField.getText().trim().isEmpty()) {
|
||||
errorMessage.append("邮箱不能为空!\n");
|
||||
}
|
||||
if (roleListView.getItems().stream().noneMatch(Role::isSelected)) {
|
||||
errorMessage.append("至少选择一个角色!\n");
|
||||
}
|
||||
|
||||
if (errorMessage.length() == 0) {
|
||||
return true;
|
||||
} else {
|
||||
showError("输入错误", errorMessage.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void closeDialog() {
|
||||
Stage stage = (Stage) usernameField.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public boolean isSaveClicked() {
|
||||
return saveClicked;
|
||||
}
|
||||
|
||||
private void showError(String title, String message) {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle(title);
|
||||
alert.setHeaderText(null);
|
||||
alert.setContentText(message);
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
private void showError(String title, Exception e) {
|
||||
showError(title, e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.zhangmeng.online.exam.ui.controller;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
|
||||
/**
|
||||
* @author zm
|
||||
* @date 2025/3/31 16:34
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class UserListController {
|
||||
public void handleSearch(ActionEvent actionEvent) {
|
||||
|
||||
}
|
||||
|
||||
public void handleAdd(ActionEvent actionEvent) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.zhangmeng.online.exam.ui.module;
|
||||
|
||||
/**
|
||||
* @author zm
|
||||
* @date 2025/3/31 15:58
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class MenuData {
|
||||
|
||||
private String title;
|
||||
|
||||
private String icon;
|
||||
|
||||
private String url;
|
||||
|
||||
public MenuData(String title, String icon, String url) {
|
||||
this.title = title;
|
||||
this.icon = icon;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(String icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package com.zhangmeng.online.exam.ui.module;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class OperationLog {
|
||||
private int id;
|
||||
private String username; // 操作用户
|
||||
private String module; // 操作模块
|
||||
private String action; // 操作类型
|
||||
private String content; // 操作内容
|
||||
private String ip; // 操作IP
|
||||
private LocalDateTime operateTime; // 操作时间
|
||||
private String status; // 操作状态(成功/失败)
|
||||
private String errorMsg; // 错误信息
|
||||
|
||||
public OperationLog() {
|
||||
}
|
||||
|
||||
public OperationLog(int id, String module, String action, String content,
|
||||
String ip, LocalDateTime operateTime, String status, String errorMsg) {
|
||||
this.id = id;
|
||||
this.module = module;
|
||||
this.action = action;
|
||||
this.content = content;
|
||||
this.ip = ip;
|
||||
this.operateTime = operateTime;
|
||||
this.status = status;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public void setModule(String module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public LocalDateTime getOperateTime() {
|
||||
return operateTime;
|
||||
}
|
||||
|
||||
public void setOperateTime(LocalDateTime operateTime) {
|
||||
this.operateTime = operateTime;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getErrorMsg() {
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
public void setErrorMsg(String errorMsg) {
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package com.zhangmeng.online.exam.ui.module;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Permission {
|
||||
private int id;
|
||||
private String code; // 权限代码
|
||||
private String name; // 权限名称
|
||||
private String type; // 权限类型(菜单、按钮等)
|
||||
private int parentId; // 父权限ID
|
||||
private String url; // 资源路径
|
||||
private int sort; // 排序号
|
||||
private List<Permission> children = new ArrayList<>();
|
||||
|
||||
public Permission(int id, String code, String name, String type, int parentId, String url, int sort) {
|
||||
this.id = id;
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.parentId = parentId;
|
||||
this.url = url;
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(int parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public int getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public void setSort(int sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
public List<Permission> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Permission> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
package com.zhangmeng.online.exam.ui.module;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zm
|
||||
* @date 2025/3/31 17:05
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class Role {
|
||||
private int id;
|
||||
private String name;
|
||||
private String description;
|
||||
private String status;
|
||||
private List<Permission> permissions;
|
||||
private BooleanProperty selected;
|
||||
|
||||
public Role(int id, String name, String description, String status) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.status = status;
|
||||
this.permissions = new ArrayList<>();
|
||||
this.selected = new SimpleBooleanProperty(false);
|
||||
}
|
||||
|
||||
public Role() {
|
||||
}
|
||||
|
||||
// Getters and setters
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public List<Permission> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(List<Permission> permissions) {
|
||||
this.permissions = new ArrayList<>(permissions);
|
||||
}
|
||||
|
||||
public void addPermission(Permission permission) {
|
||||
if (!permissions.contains(permission)) {
|
||||
permissions.add(permission);
|
||||
}
|
||||
}
|
||||
|
||||
public void removePermission(Permission permission) {
|
||||
permissions.remove(permission);
|
||||
}
|
||||
|
||||
public boolean hasPermission(String permissionCode) {
|
||||
return permissions.stream()
|
||||
.anyMatch(p -> p.getCode().equals(permissionCode));
|
||||
}
|
||||
|
||||
public BooleanProperty selectedProperty() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return selected.get();
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
this.selected.set(selected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
package com.zhangmeng.online.exam.ui.module;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zm
|
||||
* @date 2025/3/31 15:33
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class User {
|
||||
|
||||
private int id;
|
||||
private String username;
|
||||
private String name;
|
||||
private String email;
|
||||
private String status;
|
||||
private String password; // 加密后的密码
|
||||
private String salt; // 密码盐值
|
||||
private List<Role> roles = new ArrayList<>();
|
||||
private String phone;
|
||||
private String avatarUrl;
|
||||
|
||||
private String token;
|
||||
|
||||
private String roleType;
|
||||
|
||||
|
||||
public User(int id, String username, String name, String email, String status) {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(int id, String username, String name, String email, String status, String password, String salt) {
|
||||
this(id, username, name, email, status);
|
||||
this.password = password;
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public void setSalt(String salt) {
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
public List<Role> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(List<Role> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public void addRole(Role role) {
|
||||
if (!roles.contains(role)) {
|
||||
roles.add(role);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasPermission(String permissionCode) {
|
||||
return roles.stream()
|
||||
.anyMatch(role -> role.hasPermission(permissionCode));
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return "启用".equals(status);
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getAvatarUrl() {
|
||||
return avatarUrl;
|
||||
}
|
||||
|
||||
public void setAvatarUrl(String avatarUrl) {
|
||||
this.avatarUrl = avatarUrl;
|
||||
}
|
||||
|
||||
|
||||
public String getRoleType() {
|
||||
return roleType;
|
||||
}
|
||||
|
||||
public void setRoleType(String roleType) {
|
||||
this.roleType = roleType;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
package com.zhangmeng.online.exam.ui.service;
|
||||
|
||||
|
||||
import com.zhangmeng.online.exam.ui.module.OperationLog;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class LogService {
|
||||
private static final List<LogEntry> logs = new ArrayList<>();
|
||||
private static final int MAX_LOGS = 10000; // 最多保存10000条日志
|
||||
|
||||
/**
|
||||
* 记录日志
|
||||
*/
|
||||
public static void log(String module, String operation, String message) {
|
||||
log(module, operation, message, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录带异常的日志
|
||||
*/
|
||||
public static void log(String module, String operation, String message, Exception e) {
|
||||
LogEntry entry = new LogEntry(
|
||||
module,
|
||||
operation,
|
||||
message,
|
||||
e != null ? e.getMessage() : null,
|
||||
LocalDateTime.now()
|
||||
);
|
||||
|
||||
synchronized (logs) {
|
||||
logs.add(entry);
|
||||
if (logs.size() > MAX_LOGS) {
|
||||
logs.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索日志
|
||||
*/
|
||||
public static List<OperationLog> searchLogs(String keyword) {
|
||||
return logs.stream()
|
||||
.filter(log -> keyword == null || keyword.isEmpty() || log.getMessage().contains(keyword))
|
||||
.map(log -> new OperationLog(
|
||||
0, // Assuming ID is not used or set elsewhere
|
||||
log.getModule(),
|
||||
log.getOperation(),
|
||||
log.getMessage(),
|
||||
"127.0.0.1", // Placeholder for IP
|
||||
log.getTime(),
|
||||
"成功", // Placeholder for status
|
||||
log.getError() // Assuming error message is used as errorMsg
|
||||
))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<OperationLog> searchLogs(String keyword, String type, LocalDateTime startDate, LocalDateTime endDate) {
|
||||
|
||||
return logs.stream()
|
||||
|
||||
.filter(log -> {
|
||||
|
||||
// 检查日期范围
|
||||
|
||||
if (startDate != null && log.getTime().isBefore(startDate)) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (endDate != null && log.getTime().isAfter(endDate)) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 检查日志类型
|
||||
|
||||
if (type != null && !type.isEmpty() && !log.getModule().equals(type)) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 检查关键字
|
||||
|
||||
if (keyword != null && !keyword.isEmpty() && !log.getMessage().contains(keyword)) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
})
|
||||
|
||||
.map(log -> new OperationLog(
|
||||
|
||||
0, // Assuming ID is not used or set elsewhere
|
||||
|
||||
log.getModule(),
|
||||
|
||||
log.getOperation(),
|
||||
|
||||
log.getMessage(),
|
||||
|
||||
"127.0.0.1", // Placeholder for IP
|
||||
|
||||
log.getTime(),
|
||||
|
||||
"成功", // Placeholder for status
|
||||
|
||||
log.getError() // Assuming error message is used as errorMsg
|
||||
|
||||
))
|
||||
|
||||
.collect(Collectors.toList());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空日志
|
||||
*/
|
||||
public static void clearLogs() {
|
||||
synchronized (logs) {
|
||||
logs.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志条目类
|
||||
*/
|
||||
private static class LogEntry {
|
||||
private final String module;
|
||||
private final String operation;
|
||||
private final String message;
|
||||
private final String error;
|
||||
private final LocalDateTime time;
|
||||
|
||||
public LogEntry(String module, String operation, String message,
|
||||
String error, LocalDateTime time) {
|
||||
this.module = module;
|
||||
this.operation = operation;
|
||||
this.message = message;
|
||||
this.error = error;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public LocalDateTime getTime() {
|
||||
return time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.zhangmeng.online.exam.ui.service;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.zhangmeng.online.exam.ui.api.ApiUtils;
|
||||
import com.zhangmeng.online.exam.ui.module.Role;
|
||||
import com.zhangmeng.online.exam.ui.module.User;
|
||||
import com.zhangmeng.online.exam.ui.utils.HttpUtils;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.zhangmeng.online.exam.ui.api.ApiUtils.API_URL;
|
||||
|
||||
/**
|
||||
* @author zm
|
||||
* @date 2025/3/31 17:04
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class RoleService {
|
||||
public static List<Role> getAllRoles() {
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("pageNum", ApiUtils.PAGE_NUM);
|
||||
params.put("pageSize", ApiUtils.PAGE_SIZE);
|
||||
|
||||
String userListData = HttpUtils.GET(API_URL + "/role/list",params);
|
||||
JSONObject jsonObject = JSON.parseObject(userListData);
|
||||
JSONArray data = jsonObject.getJSONArray("data");
|
||||
Integer total = jsonObject.getInteger("total");
|
||||
List<Role> roles = new ArrayList<>();
|
||||
for (Object datum : data) {
|
||||
JSONObject rolemap = (JSONObject) datum;
|
||||
|
||||
Role role = new Role();
|
||||
role.setId(rolemap.getInteger("id"));
|
||||
role.setName(rolemap.getString("name"));
|
||||
role.setDescription(rolemap.getString("desc")); // 角色描述
|
||||
role.setStatus(rolemap.getString("status"));
|
||||
role.setPermissions(new ArrayList<>()); // 角色权限
|
||||
|
||||
roles.add(role);
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
package com.zhangmeng.online.exam.ui.service;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.zhangmeng.online.exam.ui.api.ApiUtils;
|
||||
import com.zhangmeng.online.exam.ui.module.MenuData;
|
||||
import com.zhangmeng.online.exam.ui.module.User;
|
||||
import com.zhangmeng.online.exam.ui.utils.HttpUtils;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 模块
|
||||
* @author zm
|
||||
* @date 2025/3/31 15:29
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class UserService {
|
||||
|
||||
private static User currentUser;
|
||||
|
||||
public static User getCurrentUser() {
|
||||
|
||||
if (currentUser == null){
|
||||
return new User();
|
||||
}
|
||||
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
public static void setCurrentUser(User user) {
|
||||
currentUser = user;
|
||||
}
|
||||
|
||||
public static void user_type() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("token", currentUser.getToken());
|
||||
String response = HttpUtils.GET(ApiUtils.API_URL + "/user/getUserInfo", params);
|
||||
JSONObject jsonObject = JSONObject.parseObject(response);
|
||||
if (jsonObject.getIntValue("code") == 200) {
|
||||
Map<String, Object> data = (Map<String, Object>) jsonObject.get("data");
|
||||
String type = data.get("type").toString();
|
||||
currentUser.setRoleType(type);
|
||||
}
|
||||
}
|
||||
|
||||
public static void logout() {
|
||||
currentUser = null;
|
||||
}
|
||||
|
||||
public static List<TreeItem<MenuData>> menu_tree_item() {
|
||||
|
||||
String sideData = HttpUtils.GET(ApiUtils.API_URL + "/user/menu");
|
||||
JSONObject jsonObject = JSON.parseObject(sideData);
|
||||
JSONArray data = jsonObject.getJSONArray("data");
|
||||
|
||||
List<TreeItem<MenuData>> menuList = new ArrayList<>();
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
JSONObject menu = data.getJSONObject(i);
|
||||
String name = menu.getString("name");
|
||||
String url = menu.getString("url");
|
||||
TreeItem<MenuData> management = new TreeItem<>(new MenuData(name, null, url));
|
||||
management.setGraphic(new Label(management.getValue().getTitle()));
|
||||
|
||||
JSONArray children = (JSONArray) menu.get("children");
|
||||
children.forEach(child -> {
|
||||
JSONObject childMenu = (JSONObject) child;
|
||||
String childName = childMenu.getString("name");
|
||||
String childUrl = childMenu.getString("url");
|
||||
TreeItem<MenuData> menuDataTreeItem = new TreeItem<>(new MenuData(childName, null, childUrl));
|
||||
menuDataTreeItem.setGraphic(new Label(menuDataTreeItem.getValue().getTitle()));
|
||||
management.getChildren().add(menuDataTreeItem);
|
||||
});
|
||||
menuList.add(management);
|
||||
}
|
||||
|
||||
return menuList;
|
||||
|
||||
}
|
||||
|
||||
public static void createUser(User user) {
|
||||
|
||||
}
|
||||
|
||||
public static void updateUser(User user) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,7 @@ import java.io.IOException;
|
|||
*/
|
||||
public class AlertUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 警告弹窗
|
||||
*/
|
||||
|
|
@ -87,4 +88,18 @@ public class AlertUtils {
|
|||
});
|
||||
|
||||
}
|
||||
|
||||
public static void alert(String title, FXMLLoader loader, Stage primaryStage){
|
||||
try {
|
||||
Scene scene = new Scene(loader.load());
|
||||
Stage dialogStage = new Stage();
|
||||
dialogStage.setTitle(title);
|
||||
dialogStage.initModality(Modality.WINDOW_MODAL);
|
||||
dialogStage.initOwner(primaryStage);
|
||||
dialogStage.setScene(scene);
|
||||
dialogStage.showAndWait();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package com.zhangmeng.online.exam.ui.utils;
|
||||
|
||||
import com.zhangmeng.online.exam.ui.api.form.RoleForm;
|
||||
import com.zhangmeng.online.exam.ui.api.form.UserForm;
|
||||
import com.zhangmeng.online.exam.ui.api.form.base.Form;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author zm
|
||||
* @date 2025/3/31 15:48
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class FxUtils {
|
||||
|
||||
public final static double DEFAULT_WIDTH = 1280;
|
||||
public final static double DEFAULT_HEIGHT = 720;
|
||||
|
||||
public static void alert(String title, Parent node, Stage primaryStage) {
|
||||
Form form = (Form) node;
|
||||
if (form instanceof UserForm) {
|
||||
form = new UserForm(true);
|
||||
}
|
||||
if (form instanceof RoleForm) {
|
||||
form = new RoleForm();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(form);
|
||||
Stage dialogStage = new Stage();
|
||||
dialogStage.setTitle(title);
|
||||
dialogStage.setResizable(false);
|
||||
dialogStage.initModality(Modality.WINDOW_MODAL);
|
||||
dialogStage.initOwner(primaryStage);
|
||||
dialogStage.setScene(scene);
|
||||
dialogStage.showAndWait();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import cn.hutool.core.io.FileUtil;
|
|||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.zhangmeng.online.exam.ui.service.UserService;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -18,6 +19,7 @@ import java.util.Map;
|
|||
*/
|
||||
public class HttpUtils<T> {
|
||||
|
||||
|
||||
public static Map<String, Object> USER_INFO = new HashMap<>();
|
||||
|
||||
public static <T> T GET(String url, Class<T> clazz) {
|
||||
|
|
@ -26,20 +28,20 @@ public class HttpUtils<T> {
|
|||
}
|
||||
|
||||
public static String GET(String url) {
|
||||
url = url + "?token=" + USER_INFO.get("token");
|
||||
url = url + "?token=" + UserService.getCurrentUser().getToken();
|
||||
return HttpUtil.get(url, CharsetUtil.CHARSET_UTF_8);
|
||||
}
|
||||
|
||||
public static String GET(String url, Map<String, Object> params) {
|
||||
|
||||
Object token = USER_INFO.get("token");
|
||||
String token = UserService.getCurrentUser().getToken();
|
||||
params.put("token",token);
|
||||
return HttpUtil.get(url, params);
|
||||
}
|
||||
|
||||
public static String POST(String url, Map<String, Object> params) {
|
||||
HashMap<String, Object> paramMap = new HashMap<>(params);
|
||||
Object token = USER_INFO.get("token");
|
||||
String token = UserService.getCurrentUser().getToken();
|
||||
paramMap.put("token",token);
|
||||
return HttpUtil.post(url, paramMap);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
|
||||
<BorderPane xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="com.zhangmeng.online.exam.ui.controller.MainController">
|
||||
<top>
|
||||
<HBox spacing="10" alignment="CENTER_RIGHT" style="-fx-padding: 5;">
|
||||
<Label fx:id="userLabel"/>
|
||||
<Button text="退出" onAction="#handleLogout"/>
|
||||
</HBox>
|
||||
</top>
|
||||
|
||||
<left>
|
||||
<TreeView fx:id="menuTree" prefWidth="200"/>
|
||||
</left>
|
||||
|
||||
<center>
|
||||
<TabPane fx:id="contentTabPane" tabClosingPolicy="ALL_TABS"/>
|
||||
</center>
|
||||
</BorderPane>
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
|
||||
|
||||
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fmxl.RoleForm">
|
||||
<children>
|
||||
<Label layoutX="135.0" layoutY="84.0" text="类型:" />
|
||||
<Label layoutX="130.0" layoutY="145.0" text="角色名称:" />
|
||||
<Label layoutX="123.0" layoutY="209.0" text="角色描述:" />
|
||||
<ChoiceBox layoutX="234.0" layoutY="80.0" prefHeight="23.0" prefWidth="229.0" />
|
||||
<TextField layoutX="234.0" layoutY="141.0" prefHeight="23.0" prefWidth="229.0" />
|
||||
<TextField layoutX="234.0" layoutY="205.0" prefHeight="23.0" prefWidth="229.0" />
|
||||
<Button layoutX="267.0" layoutY="289.0" mnemonicParsing="false" text="保存" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
|
||||
<VBox spacing="10" xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="com.zhangmeng.online.exam.ui.controller.UserEditController">
|
||||
<padding>
|
||||
<Insets top="10" right="10" bottom="10" left="10"/>
|
||||
</padding>
|
||||
|
||||
<GridPane hgap="10" vgap="10">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints minWidth="80" prefWidth="100"/>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
</columnConstraints>
|
||||
|
||||
<!-- 用户名 -->
|
||||
<Label text="用户名:" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
|
||||
<TextField fx:id="usernameField" GridPane.rowIndex="0" GridPane.columnIndex="1"/>
|
||||
|
||||
<!-- 姓名 -->
|
||||
<Label text="姓名:" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
|
||||
<TextField fx:id="nameField" GridPane.rowIndex="1" GridPane.columnIndex="1"/>
|
||||
|
||||
<!-- 密码 -->
|
||||
<Label text="密码:" GridPane.rowIndex="2" GridPane.columnIndex="0"/>
|
||||
<PasswordField fx:id="passwordField" GridPane.rowIndex="2" GridPane.columnIndex="1"/>
|
||||
|
||||
<!-- 邮箱 -->
|
||||
<Label text="邮箱:" GridPane.rowIndex="3" GridPane.columnIndex="0"/>
|
||||
<TextField fx:id="emailField" GridPane.rowIndex="3" GridPane.columnIndex="1"/>
|
||||
|
||||
<!-- 状态 -->
|
||||
<Label text="状态:" GridPane.rowIndex="4" GridPane.columnIndex="0"/>
|
||||
<ComboBox fx:id="statusComboBox" GridPane.rowIndex="4" GridPane.columnIndex="1"/>
|
||||
|
||||
<!-- 角色 -->
|
||||
<Label text="角色:" GridPane.rowIndex="5" GridPane.columnIndex="0"/>
|
||||
<ListView fx:id="roleListView" prefHeight="100" GridPane.rowIndex="5" GridPane.columnIndex="1"/>
|
||||
</GridPane>
|
||||
|
||||
<HBox spacing="10" alignment="CENTER_RIGHT">
|
||||
<Button text="保存" onAction="#handleSave" defaultButton="true"/>
|
||||
<Button text="取消" onAction="#handleCancel" cancelButton="true"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
|
||||
<VBox spacing="10" xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="com.zhangmeng.online.exam.ui.controller.UserListController">
|
||||
<padding>
|
||||
<Insets top="10" right="10" bottom="10" left="10"/>
|
||||
</padding>
|
||||
<children>
|
||||
<HBox spacing="10" alignment="CENTER_LEFT">
|
||||
<TextField fx:id="searchField" promptText="输入关键字搜索..." HBox.hgrow="ALWAYS"/>
|
||||
<Button text="搜索" onAction="#handleSearch"/>
|
||||
<Region HBox.hgrow="ALWAYS"/>
|
||||
<Button fx:id="addButton" text="添加用户" onAction="#handleAdd"/>
|
||||
</HBox>
|
||||
<TableView fx:id="userTable" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn fx:id="idColumn" text="ID" prefWidth="50"/>
|
||||
<TableColumn fx:id="usernameColumn" text="用户名" prefWidth="100"/>
|
||||
<TableColumn fx:id="nameColumn" text="姓名" prefWidth="100"/>
|
||||
<TableColumn fx:id="emailColumn" text="邮箱" prefWidth="150"/>
|
||||
<TableColumn fx:id="statusColumn" text="状态" prefWidth="80"/>
|
||||
<TableColumn fx:id="actionColumn" text="操作" prefWidth="150"/>
|
||||
</columns>
|
||||
</TableView>
|
||||
</children>
|
||||
</VBox>
|
||||
Loading…
Reference in New Issue