2025年3月20日18:18:38
parent
87bd0dca14
commit
eeebf4bcb1
|
|
@ -1,11 +1,9 @@
|
||||||
package com.zhangmeng.online.exam.ui.admin;
|
package com.zhangmeng.online.exam.ui.admin;
|
||||||
|
|
||||||
|
import com.zhangmeng.online.exam.ui.components.ExamComponent;
|
||||||
import com.zhangmeng.online.exam.ui.components.ShortAnswerComponent;
|
import com.zhangmeng.online.exam.ui.components.ShortAnswerComponent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.Label;
|
|
||||||
import javafx.scene.control.PasswordField;
|
|
||||||
import javafx.scene.control.TextField;
|
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import javafx.stage.Window;
|
import javafx.stage.Window;
|
||||||
|
|
@ -104,7 +102,8 @@ public class LoginPage extends AnchorPane {
|
||||||
window.close();
|
window.close();
|
||||||
|
|
||||||
Stage stage = new Stage();
|
Stage stage = new Stage();
|
||||||
IndexPage shortAnswerComponent = new IndexPage();
|
// IndexPage shortAnswerComponent = new IndexPage();
|
||||||
|
ExamComponent shortAnswerComponent = new ExamComponent();
|
||||||
scene = new Scene(shortAnswerComponent, 1280, 720);
|
scene = new Scene(shortAnswerComponent, 1280, 720);
|
||||||
stage.setScene(scene);
|
stage.setScene(scene);
|
||||||
stage.setTitle("在线考试系统");
|
stage.setTitle("在线考试系统");
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,10 @@ public class ApiUtils {
|
||||||
return tableView.getSelectionModel().getSelectedItem();
|
return tableView.getSelectionModel().getSelectedItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void submitAnswer(Map<String, Object> context) {
|
||||||
|
System.out.println(context);
|
||||||
|
}
|
||||||
|
|
||||||
public static class DataView {
|
public static class DataView {
|
||||||
|
|
||||||
private List<String> keys;
|
private List<String> keys;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.zhangmeng.online.exam.ui.api.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zm
|
||||||
|
* @date 2025/3/20 16:31
|
||||||
|
* @version: 1.0
|
||||||
|
*/
|
||||||
|
public class ExamDataLoad {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.zhangmeng.online.exam.ui.components;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.zhangmeng.online.exam.ui.api.ApiUtils;
|
||||||
|
import com.zhangmeng.online.exam.ui.utils.HttpUtils;
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
import javafx.beans.value.WritableValue;
|
||||||
|
import javafx.css.StyleableProperty;
|
||||||
|
import javafx.scene.AccessibleRole;
|
||||||
|
import javafx.scene.control.ScrollPane;
|
||||||
|
import javafx.scene.layout.FlowPane;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 考试组件
|
||||||
|
*
|
||||||
|
* @author zm
|
||||||
|
* @date 2025/3/20 16:29
|
||||||
|
* @version: 1.0
|
||||||
|
*/
|
||||||
|
public class ExamComponent extends ScrollPane {
|
||||||
|
|
||||||
|
private VBox vBox;
|
||||||
|
|
||||||
|
public ExamComponent() {
|
||||||
|
this.vBox = new VBox(5);
|
||||||
|
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("pageNum", ApiUtils.PAGE_NUM);
|
||||||
|
params.put("pageSize", ApiUtils.PAGE_SIZE);
|
||||||
|
params.put("id", 1);
|
||||||
|
String userListData = HttpUtils.GET(ApiUtils.API_URL + "/paper/chooseQuestion/list", params);
|
||||||
|
JSONObject jsonObject = JSON.parseObject(userListData);
|
||||||
|
JSONArray data = jsonObject.getJSONArray("data");
|
||||||
|
int total = jsonObject.getIntValue("total");
|
||||||
|
int index = 1;
|
||||||
|
for (Object datum : data) {
|
||||||
|
JSONObject question = (JSONObject) datum;
|
||||||
|
String type = question.getString("type");
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case "单选题" -> {
|
||||||
|
String list = question.getString("options");
|
||||||
|
List<Map> maps = JSONArray.parseArray(list, Map.class);
|
||||||
|
String correctAnswer = null;
|
||||||
|
List<Map<String,Object>> optionList = new ArrayList<>();
|
||||||
|
for (Map map : maps) {
|
||||||
|
boolean isAnswer = (boolean) map.get("isAnswer");
|
||||||
|
|
||||||
|
Map<String,Object> option = new HashMap<>();
|
||||||
|
option.put("id", map.get("id"));
|
||||||
|
option.put("text",map.get("name").toString()+ map.get("content").toString());
|
||||||
|
option.put("isAnswer",isAnswer);
|
||||||
|
optionList.add(option);
|
||||||
|
}
|
||||||
|
SingleChoiceComponent singleChoiceComponent = new SingleChoiceComponent(index + "." + question.getString("name"), optionList);
|
||||||
|
singleChoiceComponent.setCorrectAnswer(correctAnswer);
|
||||||
|
Map<String,Object> context = new HashMap<>();
|
||||||
|
context.put("question_id", question.getString("id"));
|
||||||
|
context.put("paper_id",1);
|
||||||
|
singleChoiceComponent.setContext(context);
|
||||||
|
this.vBox.getChildren().add(singleChoiceComponent);
|
||||||
|
index ++;
|
||||||
|
}
|
||||||
|
// case "多选题" -> MULTIPLE_CHOICE_SCORE.set(MULTIPLE_CHOICE_SCORE.get() + score);
|
||||||
|
// case "判断题" -> JUDGMENT_SCORE.set(JUDGMENT_SCORE.get() + score);
|
||||||
|
// case "计算题" -> NUMERICAL_SCORE.set(NUMERICAL_SCORE.get() + score);
|
||||||
|
// case "填空题" -> Fill_IN_THE_BLANKS.set(Fill_IN_THE_BLANKS.get() + score);
|
||||||
|
// case "简答题" -> SHORT_ANSWER_SCORE.set(SHORT_ANSWER_SCORE.get() + score);
|
||||||
|
// default -> throw new IllegalStateException("Unexpected value: " + type.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setContent(vBox);
|
||||||
|
this.setFitToWidth(true);
|
||||||
|
this.setFitToHeight(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.zhangmeng.online.exam.ui.components;
|
package com.zhangmeng.online.exam.ui.components;
|
||||||
|
|
||||||
|
import com.zhangmeng.online.exam.ui.api.ApiUtils;
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
|
@ -7,17 +9,18 @@ import javafx.scene.control.RadioButton;
|
||||||
import javafx.scene.control.ToggleGroup;
|
import javafx.scene.control.ToggleGroup;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* .radio-button {
|
* .radio-button {
|
||||||
* -fx-font-size: 14px;
|
* -fx-font-size: 14px;
|
||||||
* -fx-text-fill: #333;
|
* -fx-text-fill: #333;
|
||||||
* }
|
* }
|
||||||
* .correct { -fx-text-fill: green; }
|
* .correct { -fx-text-fill: green; }
|
||||||
* .wrong { -fx-text-fill: red; }
|
* .wrong { -fx-text-fill: red; }
|
||||||
*
|
* <p>
|
||||||
* 单选题组件
|
* 单选题组件
|
||||||
*
|
*
|
||||||
* @author zm
|
* @author zm
|
||||||
|
|
@ -26,16 +29,30 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class SingleChoiceComponent extends VBox {
|
public class SingleChoiceComponent extends VBox {
|
||||||
|
|
||||||
private final String correctAnswer = "B"; // 预设正确答案
|
private Map<String,Object> context = new HashMap<>();
|
||||||
|
|
||||||
public SingleChoiceComponent(String question, List<String> options) {
|
public Map<String, Object> getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContext(Map<String, Object> context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String correctAnswer = null; // 预设正确答案
|
||||||
|
|
||||||
|
private int number_of_responses = 0;//作答次数
|
||||||
|
|
||||||
|
private final SimpleStringProperty result_answer = new SimpleStringProperty(); // 最终答案
|
||||||
|
|
||||||
|
public SingleChoiceComponent(String question, List<Map<String, Object>> options) {
|
||||||
|
|
||||||
// 创建题目组件
|
// 创建题目组件
|
||||||
Label questionLabel = new Label(question);
|
Label questionLabel = new Label(question);
|
||||||
this.getChildren().add(questionLabel);
|
this.getChildren().add(questionLabel);
|
||||||
ToggleGroup answerGroup = new ToggleGroup(); // 单选按钮组:ml-citation{ref="1,2" data="citationList"}
|
ToggleGroup answerGroup = new ToggleGroup(); // 单选按钮组:ml-citation{ref="1,2" data="citationList"}
|
||||||
// 创建选项按钮
|
// 创建选项按钮
|
||||||
for (String option : options) {
|
for (Map<String, Object> option : options) {
|
||||||
RadioButton optionBtn = createRadioButton(option, answerGroup);
|
RadioButton optionBtn = createRadioButton(option, answerGroup);
|
||||||
this.getChildren().add(optionBtn);
|
this.getChildren().add(optionBtn);
|
||||||
}
|
}
|
||||||
|
|
@ -45,11 +62,59 @@ public class SingleChoiceComponent extends VBox {
|
||||||
Label resultLabel = new Label();
|
Label resultLabel = new Label();
|
||||||
|
|
||||||
// 设置提交事件
|
// 设置提交事件
|
||||||
submitBtn.setOnAction(e -> {
|
// submitBtn.setOnAction(e -> {
|
||||||
RadioButton selected = (RadioButton) answerGroup.getSelectedToggle();
|
// RadioButton selected = (RadioButton) answerGroup.getSelectedToggle();
|
||||||
|
// if (number_of_responses == 0){
|
||||||
|
// if (selected != null) {
|
||||||
|
// String answer = selected.getText().substring(0,1);
|
||||||
|
// resultLabel.setText(answer.equals(correctAnswer) ? "✅ 回答正确" : "❌ 正确答案:" + correctAnswer);
|
||||||
|
//
|
||||||
|
// if (answer.equals(correctAnswer)){
|
||||||
|
// resultLabel.setStyle("-fx-text-fill: #2ecc71;");
|
||||||
|
// }else{
|
||||||
|
// resultLabel.setStyle("-fx-text-fill: #e74c3c;");
|
||||||
|
// }
|
||||||
|
// number_of_responses++;
|
||||||
|
// } else {
|
||||||
|
// resultLabel.setText("⚠ 请先选择答案");
|
||||||
|
// }
|
||||||
|
// }else {
|
||||||
|
// resultLabel.setText("⚠ 请勿重复提交");
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// answerGroup.selectedToggleProperty().addListener((ov, old_value, new_value) -> {
|
||||||
|
// RadioButton selected = (RadioButton) new_value;
|
||||||
|
// if (number_of_responses == 0){
|
||||||
|
// if (selected != null) {
|
||||||
|
// String answer = selected.getText().substring(0,1);
|
||||||
|
// resultLabel.setText(answer.equals(correctAnswer) ? "✅ 回答正确" : "❌ 正确答案:" + correctAnswer);
|
||||||
|
//
|
||||||
|
// if (answer.equals(correctAnswer)){
|
||||||
|
// resultLabel.setStyle("-fx-text-fill: #2ecc71;");
|
||||||
|
// }else{
|
||||||
|
// resultLabel.setStyle("-fx-text-fill: #e74c3c;");
|
||||||
|
// }
|
||||||
|
// number_of_responses++;
|
||||||
|
// } else {
|
||||||
|
// resultLabel.setText("⚠ 请先选择答案");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
answerGroup.selectedToggleProperty().addListener((ov, old_value, new_value) -> {
|
||||||
|
RadioButton selected = (RadioButton) new_value;
|
||||||
if (selected != null) {
|
if (selected != null) {
|
||||||
String answer = selected.getText().substring(0,1);
|
String answer = selected.getText().substring(0, 1);
|
||||||
resultLabel.setText(answer.equals(correctAnswer) ? "✅ 回答正确" : "❌ 正确答案:" + correctAnswer);
|
result_answer.set(answer);
|
||||||
|
number_of_responses++;
|
||||||
|
// resultLabel.setText("你的选择:"+ result_answer.get());
|
||||||
|
// resultLabel.setStyle("-fx-text-fill: #2ecc71;");
|
||||||
|
String id = (String) selected.getUserData();
|
||||||
|
context.put("option_id", id);
|
||||||
|
//提交数据
|
||||||
|
ApiUtils.submitAnswer(context, result_answer.get());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
resultLabel.setText("⚠ 请先选择答案");
|
resultLabel.setText("⚠ 请先选择答案");
|
||||||
}
|
}
|
||||||
|
|
@ -58,15 +123,23 @@ public class SingleChoiceComponent extends VBox {
|
||||||
// 布局容器
|
// 布局容器
|
||||||
this.setSpacing(10);
|
this.setSpacing(10);
|
||||||
this.setPadding(new Insets(15));
|
this.setPadding(new Insets(15));
|
||||||
this.getChildren().addAll( submitBtn, resultLabel);
|
this.getChildren().addAll(resultLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 封装单选按钮创建方法:ml-citation{ref="2,3" data="citationList"}
|
// 封装单选按钮创建方法:ml-citation{ref="2,3" data="citationList"}
|
||||||
private RadioButton createRadioButton(String text, ToggleGroup group) {
|
private RadioButton createRadioButton(Map<String, Object> option, ToggleGroup group) {
|
||||||
RadioButton rb = new RadioButton(text);
|
RadioButton rb = new RadioButton(option.get("text").toString());
|
||||||
rb.setToggleGroup(group);
|
rb.setToggleGroup(group);
|
||||||
rb.setPadding(new Insets(5));
|
rb.setPadding(new Insets(5));
|
||||||
|
rb.setUserData(option.get("id"));
|
||||||
return rb;
|
return rb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCorrectAnswer() {
|
||||||
|
return correctAnswer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCorrectAnswer(String correctAnswer) {
|
||||||
|
this.correctAnswer = correctAnswer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue