试卷添加试题

master
qmstyle 2025-03-20 16:15:53 +08:00
parent 07d045c305
commit 87bd0dca14
6 changed files with 399 additions and 18 deletions

View File

@ -146,13 +146,17 @@ public class PaperDataLoad implements DataLoad {
String id = map.get("id").getValue();
// AlertUtils.alert_msg("组卷正在开发中..." + id);
ContextMenu parentPopup = group_volumes.getParentPopup();
IndexPage indexPage = (IndexPage)parentPopup.getStyleableParent();
IndexPage indexPage = (IndexPage) parentPopup.getStyleableParent();
Stage stage = (Stage) indexPage.getScene().getWindow();
PaperViewComponent paperViewComponent = new PaperViewComponent(new PaperViewComponentCallBackImpl());
Map<String, Object> context = new HashMap<>();
context.put("id", id);
PaperViewComponent paperViewComponent = new PaperViewComponent(new PaperViewComponentCallBackImpl(),context);
paperViewComponent.setPrefWidth(1200);
paperViewComponent.setPrefHeight(649);
AlertUtils.alert("组卷",paperViewComponent,1200,649,stage,true);
AlertUtils.alert("组卷", paperViewComponent, 1200, 649, stage, true);
});
@ -164,4 +168,34 @@ public class PaperDataLoad implements DataLoad {
AlertUtils.alert_msg("搜索功能正在开发中..." + JSON.toJSONString(searchText));
return null;
}
public ApiUtils.DataView loadChooseQuestionData(Map<String, Object> context,Integer pageNum, Integer pageSize) {
Map<String, Object> params = new HashMap<>();
params.put("pageNum", pageNum.toString());
params.put("pageSize", pageSize.toString());
params.put("id", context.get("id"));
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");
List<Map<String, SimpleStringProperty>> userMapList = new ArrayList<>();
for (Object datum : data) {
JSONObject question = (JSONObject) datum;
Map<String, SimpleStringProperty> userMap = new HashMap<>();
userMap.put("序号", new SimpleStringProperty(question.getString("id")));
userMap.put("题目", new SimpleStringProperty(question.getString("name")));
userMap.put("题目类型", new SimpleStringProperty(question.getString("type")));
userMap.put("所属学科", new SimpleStringProperty(question.getString("subject")));
userMap.put("分值", new SimpleStringProperty(question.getString("score")));
userMap.put("id", new SimpleStringProperty(question.getString("id")));
userMap.put("score", new SimpleStringProperty(question.getString("score")));
userMap.put("type", new SimpleStringProperty(question.getString("type")));
userMapList.add(userMap);
}
ApiUtils.DataView dataView = new ApiUtils.DataView(Arrays.asList("序号", "题目", "题目类型","所属学科", "分值"), userMapList).setDataLoad(this).setPageNum(pageNum).setPageSize(pageSize).setTotal(total);
dataView.setDataLoad(this);
return dataView;
}
}

View File

@ -39,9 +39,13 @@ public class QuestionDataLoad implements DataLoad {
userMap.put("题目", new SimpleStringProperty(permission.getString("name")));
userMap.put("题目类型", new SimpleStringProperty(permission.getString("type")));
userMap.put("所属学科", new SimpleStringProperty(permission.getString("subject")));
userMap.put("分值", new SimpleStringProperty(permission.getString("score")));
userMap.put("id", new SimpleStringProperty(permission.getString("id")));
userMap.put("score", new SimpleStringProperty(permission.getString("score")));
userMap.put("type", new SimpleStringProperty(permission.getString("type")));
questionMapList.add(userMap);
}
return new ApiUtils.DataView(Arrays.asList("序号", "题目", "题目类型", "所属学科"), questionMapList).setDataLoad(this).setPageNum(pageNum).setPageSize(pageSize).setTotal(total);
return new ApiUtils.DataView(Arrays.asList("序号", "题目", "题目类型", "所属学科", "分值"), questionMapList).setDataLoad(this).setPageNum(pageNum).setPageSize(pageSize).setTotal(total);
}

View File

@ -0,0 +1,165 @@
package com.zhangmeng.online.exam.ui.components;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
/**
* @author zm
* @date 2025/3/20 11:26
* @version: 1.0
*/
public class PaperResultHeaderComponent extends HBox {
private Button commitBtn;//提交按钮
private SimpleStringProperty SINGLE_CHOICE_SCORE = new SimpleStringProperty("单选题分数0");//单选题分数
private SimpleStringProperty MULTIPLE_CHOICE_SCORE = new SimpleStringProperty("多选题分数0");//多选题分数
private SimpleStringProperty JUDGMENT_SCORE = new SimpleStringProperty("判断题分数0");//判断题分数
private SimpleStringProperty NUMERICAL_SCORE = new SimpleStringProperty("计算题分数0");//计算题分数
private SimpleStringProperty SHORT_ANSWER_SCORE = new SimpleStringProperty("简答题分数0");//简答题分数
private SimpleStringProperty Fill_IN_THE_BLANKS = new SimpleStringProperty();//填空题分数
private SimpleStringProperty ANSWER_SCORE = new SimpleStringProperty("答题总分0");//答题总分
public PaperResultHeaderComponent(double spacing) {
super();
this.setSpacing(spacing);
Label label = new Label("");
label.setPadding(new Insets(5, 0, 0, 0));
label.textProperty().bindBidirectional(SINGLE_CHOICE_SCORE);
//
Label label2 = new Label();
label2.setPadding(new Insets(5, 0, 0, 0));
label2.textProperty().bindBidirectional(MULTIPLE_CHOICE_SCORE);
Label label3 = new Label();
label3.setPadding(new Insets(5, 0, 0, 0));
label3.textProperty().bindBidirectional(JUDGMENT_SCORE);
Label label4 = new Label();
label4.setPadding(new Insets(5, 0, 0, 0));
label4.textProperty().bindBidirectional(NUMERICAL_SCORE);
Label label5 = new Label();
label5.setPadding(new Insets(5, 0, 0, 0));
label5.textProperty().bindBidirectional(SHORT_ANSWER_SCORE);
Label label6 = new Label();
label6.setPadding(new Insets(5, 0, 0, 0));
label6.textProperty().bindBidirectional(ANSWER_SCORE);
commitBtn = new Button("提交");
this.getChildren().add(label);
this.getChildren().add(label2);
this.getChildren().add(label3);
this.getChildren().add(label4);
this.getChildren().add(label5);
this.getChildren().add(label6);
this.getChildren().add(commitBtn);
}
public Button getCommitBtn() {
return commitBtn;
}
public void setCommitBtn(Button commitBtn) {
this.commitBtn = commitBtn;
}
public String getSINGLE_CHOICE_SCORE() {
return SINGLE_CHOICE_SCORE.get();
}
public SimpleStringProperty SINGLE_CHOICE_SCOREProperty() {
return SINGLE_CHOICE_SCORE;
}
public void setSINGLE_CHOICE_SCORE(String SINGLE_CHOICE_SCORE) {
this.SINGLE_CHOICE_SCORE.set(SINGLE_CHOICE_SCORE);
}
public String getMULTIPLE_CHOICE_SCORE() {
return MULTIPLE_CHOICE_SCORE.get();
}
public SimpleStringProperty MULTIPLE_CHOICE_SCOREProperty() {
return MULTIPLE_CHOICE_SCORE;
}
public void setMULTIPLE_CHOICE_SCORE(String MULTIPLE_CHOICE_SCORE) {
this.MULTIPLE_CHOICE_SCORE.set(MULTIPLE_CHOICE_SCORE);
}
public String getJUDGMENT_SCORE() {
return JUDGMENT_SCORE.get();
}
public SimpleStringProperty JUDGMENT_SCOREProperty() {
return JUDGMENT_SCORE;
}
public void setJUDGMENT_SCORE(String JUDGMENT_SCORE) {
this.JUDGMENT_SCORE.set(JUDGMENT_SCORE);
}
public String getNUMERICAL_SCORE() {
return NUMERICAL_SCORE.get();
}
public SimpleStringProperty NUMERICAL_SCOREProperty() {
return NUMERICAL_SCORE;
}
public void setNUMERICAL_SCORE(String NUMERICAL_SCORE) {
this.NUMERICAL_SCORE.set(NUMERICAL_SCORE);
}
public String getSHORT_ANSWER_SCORE() {
return SHORT_ANSWER_SCORE.get();
}
public SimpleStringProperty SHORT_ANSWER_SCOREProperty() {
return SHORT_ANSWER_SCORE;
}
public void setSHORT_ANSWER_SCORE(String SHORT_ANSWER_SCORE) {
this.SHORT_ANSWER_SCORE.set(SHORT_ANSWER_SCORE);
}
public String getANSWER_SCORE() {
return ANSWER_SCORE.get();
}
public SimpleStringProperty ANSWER_SCOREProperty() {
return ANSWER_SCORE;
}
public void setANSWER_SCORE(String ANSWER_SCORE) {
this.ANSWER_SCORE.set(ANSWER_SCORE);
}
public String getFill_IN_THE_BLANKS() {
return Fill_IN_THE_BLANKS.get();
}
public SimpleStringProperty fill_IN_THE_BLANKSProperty() {
return Fill_IN_THE_BLANKS;
}
public void setFill_IN_THE_BLANKS(String fill_IN_THE_BLANKS) {
this.Fill_IN_THE_BLANKS.set(fill_IN_THE_BLANKS);
}
}

View File

@ -5,8 +5,12 @@ import com.zhangmeng.online.exam.ui.api.DataLoad;
import com.zhangmeng.online.exam.ui.components.callBack.PaperViewComponentCallBack;
import com.zhangmeng.online.exam.ui.utils.AlertUtils;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
@ -22,32 +26,57 @@ import javafx.scene.paint.Paint;
import javafx.util.Callback;
import org.casic.javafx.control.PaginationPicker;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
*
*
* @author zm
* @date 2025/3/19 12:22
* @version: 1.0
*/
public class PaperViewComponent extends SplitPane {
private static final double Default_Width = 20;
//附加信息
private Map<String, Object> context = new HashMap<>();
private VBox vbox;
private VBox chooseVbox;
private PaperViewComponentCallBack callBack;
private TableView<Map<String, SimpleStringProperty>> questionTable;
private final ObservableList<Map<String, SimpleStringProperty>> questionTable_data = FXCollections.observableArrayList();
private TableColumn<Map<String, SimpleStringProperty>, String> chooseColumn;
private TableView<Map<String, SimpleStringProperty>> chooseTable;
//已选题目列表
private final ObservableList<Map<String, SimpleStringProperty>> chooseTable_data = FXCollections.observableArrayList();
private SimpleIntegerProperty SINGLE_CHOICE_SCORE = new SimpleIntegerProperty();//单选题分数
private SimpleIntegerProperty MULTIPLE_CHOICE_SCORE = new SimpleIntegerProperty();//多选题分数
private SimpleIntegerProperty JUDGMENT_SCORE = new SimpleIntegerProperty();//判断题分数
private SimpleIntegerProperty NUMERICAL_SCORE = new SimpleIntegerProperty();//计算题分数
private SimpleIntegerProperty SHORT_ANSWER_SCORE = new SimpleIntegerProperty();//简答题分数
private SimpleIntegerProperty Fill_IN_THE_BLANKS = new SimpleIntegerProperty();//填空题分数
private SimpleIntegerProperty ANSWER_SCORE = new SimpleIntegerProperty();//答题总分
private PaperResultHeaderComponent hBox;
public PaperViewComponent(PaperViewComponentCallBack callBack) {
super();
setCallBack(callBack);
@ -59,7 +88,23 @@ public class PaperViewComponent extends SplitPane {
this.setDividerPositions(0.5);
this.getItems().add(vbox);
this.getItems().add(chooseTable);
this.getItems().add(chooseVbox);
}
public PaperViewComponent(PaperViewComponentCallBack callBack, Map<String, Object> context) {
super();
setContext(context);
setCallBack(callBack);
initQuestionTable();
initChooseTable();
this.setOrientation(Orientation.VERTICAL);
this.setDividerPositions(0.5);
this.getItems().add(vbox);
this.getItems().add(chooseVbox);
}
private void initQuestionTable() {
@ -84,7 +129,7 @@ public class PaperViewComponent extends SplitPane {
column.setCellValueFactory(new MapValueFactory(col));
// 启用单元格编辑‌:ml-citation{ref="4,5" data="citationList"}
column.setCellFactory(TextFieldTableCell.forTableColumn());
column.prefWidthProperty().bind(questionTable.widthProperty().divide(columns.size()).subtract(40));
column.prefWidthProperty().bind(questionTable.widthProperty().divide(columns.size()).subtract(Default_Width));
questionTable.getColumns().add(column);
});
@ -132,7 +177,7 @@ public class PaperViewComponent extends SplitPane {
};
}
});
addColumn.prefWidthProperty().bind(questionTable.widthProperty().divide(columns.size()+2).subtract(50));
addColumn.prefWidthProperty().bind(questionTable.widthProperty().divide(columns.size() + 2).subtract(50));
questionTable.getColumns().add(addColumn);
questionTable_data.addAll(dataView.getDataList());
@ -167,18 +212,26 @@ public class PaperViewComponent extends SplitPane {
}
});
vbox.setPadding(new Insets(5));
vbox.getChildren().addAll(hBox,questionTable, paginationPicker);
vbox.getChildren().addAll(hBox, questionTable, paginationPicker);
}
private void initChooseTable() {
chooseVbox = new VBox(5);
chooseVbox.setStyle("-fx-border-width: 1px; -fx-border-color: #e53030; -fx-border-style: solid;");
chooseVbox.setAlignment(Pos.CENTER_LEFT);
chooseVbox.prefHeightProperty().bind(this.heightProperty().divide(2));
chooseVbox.prefWidthProperty().bind(this.widthProperty());
ApiUtils.DataView dataView = callBack.loadChooseQuestionData(ApiUtils.PAGE_NUM, ApiUtils.PAGE_SIZE);
ApiUtils.DataView dataView = callBack.loadChooseQuestionData(context, ApiUtils.PAGE_NUM, ApiUtils.PAGE_SIZE);
chooseTable = new TableView<>();
chooseTable.setItems(chooseTable_data);
// chooseTable.setEditable(true);
chooseTable.prefHeightProperty().bind(this.heightProperty().divide(2));
chooseTable.prefWidthProperty().bind(this.widthProperty());
chooseTable.prefHeightProperty().bind(chooseVbox.heightProperty());
chooseTable.prefWidthProperty().bind(chooseVbox.widthProperty());
List<String> columns = dataView.getKeys().stream().filter(key -> !key.equals("id")).toList();
@ -188,7 +241,7 @@ public class PaperViewComponent extends SplitPane {
column.setCellValueFactory(new MapValueFactory(col));
// 启用单元格编辑‌:ml-citation{ref="4,5" data="citationList"}
column.setCellFactory(TextFieldTableCell.forTableColumn());
column.prefWidthProperty().bind(chooseTable.widthProperty().divide(columns.size()).subtract(40));
column.prefWidthProperty().bind(chooseTable.widthProperty().divide(columns.size()).subtract(Default_Width));
chooseTable.getColumns().add(column);
});
@ -236,9 +289,11 @@ public class PaperViewComponent extends SplitPane {
};
}
});
addColumn.prefWidthProperty().bind(chooseTable.widthProperty().divide(columns.size()+2).subtract(50));
addColumn.prefWidthProperty().bind(chooseTable.widthProperty().divide(columns.size() + 2).subtract(50));
chooseTable.getColumns().add(addColumn);
chooseTable_data.addAll(dataView.getDataList());
//初始化一个分页
PaginationPicker paginationPicker = new PaginationPicker();
paginationPicker.setTotal(dataView.getTotal());//设置总数据量默认0
@ -256,9 +311,91 @@ public class PaperViewComponent extends SplitPane {
}
});
hBox = new PaperResultHeaderComponent(15);
hBox.getCommitBtn().setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (chooseTable_data.size() <= 0) {
AlertUtils.alert_msg("请先选择试题!");
return;
}
callBack.commitChooseQuestion(context, chooseTable_data);
chooseTable_data.clear();
questionTable_data.clear();
new Thread(() -> {
chooseTable_data.addAll(callBack.loadChooseQuestionData(context, ApiUtils.PAGE_NUM, ApiUtils.PAGE_SIZE).getDataList());
questionTable_data.addAll(callBack.loadQuestionData(ApiUtils.PAGE_NUM, ApiUtils.PAGE_SIZE).getDataList());
}).start();
}
});
chooseVbox.setPadding(new Insets(5));
chooseVbox.getChildren().addAll(hBox, chooseTable, paginationPicker);
chooseTable_data.addListener(new ListChangeListener<>() {
@Override
public void onChanged(Change<? extends Map<String, SimpleStringProperty>> change) {
//计算分值
scoreFlush((ObservableList<Map<String, SimpleStringProperty>>) change.getList());
}
});
initScore();
}
private void scoreFlush(ObservableList<Map<String, SimpleStringProperty>> changeList) {
//初始化分值
SINGLE_CHOICE_SCORE.set(0);
MULTIPLE_CHOICE_SCORE.set(0);
JUDGMENT_SCORE.set(0);
NUMERICAL_SCORE.set(0);
SHORT_ANSWER_SCORE.set(0);
Fill_IN_THE_BLANKS.set(0);
reloadData(changeList);
}
private void reloadData(List<Map<String, SimpleStringProperty>> changeList) {
for (Map<String, SimpleStringProperty> chooseTableDatum : changeList) {
int score = Integer.parseInt(chooseTableDatum.get("score").get());
SimpleStringProperty type = chooseTableDatum.get("type");
switch (type.get()) {
case "单选题" -> SINGLE_CHOICE_SCORE.set(SINGLE_CHOICE_SCORE.get() + score);
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());
}
}
//计算总分
ANSWER_SCORE.set(
SINGLE_CHOICE_SCORE.get()
+ MULTIPLE_CHOICE_SCORE.get()
+ JUDGMENT_SCORE.get()
+ NUMERICAL_SCORE.get()
+ SHORT_ANSWER_SCORE.get()
+ Fill_IN_THE_BLANKS.get()
);
hBox.setSINGLE_CHOICE_SCORE("单选题分数:" + SINGLE_CHOICE_SCORE.get());
hBox.setMULTIPLE_CHOICE_SCORE("多选题分数:" + MULTIPLE_CHOICE_SCORE.get());
hBox.setJUDGMENT_SCORE("判断题分数:" + JUDGMENT_SCORE.get());
hBox.setNUMERICAL_SCORE("计算题分数:" + NUMERICAL_SCORE.get());
hBox.setSHORT_ANSWER_SCORE("简答题分数:" + SHORT_ANSWER_SCORE.get());
hBox.setFill_IN_THE_BLANKS("填空题分数:" + Fill_IN_THE_BLANKS.get());
hBox.setANSWER_SCORE("答题总分:" + ANSWER_SCORE.get());
}
private void initScore() {
reloadData(chooseTable_data);
}
public TableView<Map<String, SimpleStringProperty>> getQuestionTable() {
@ -300,4 +437,21 @@ public class PaperViewComponent extends SplitPane {
public void setVbox(VBox vbox) {
this.vbox = vbox;
}
public VBox getChooseVbox() {
return chooseVbox;
}
public void setChooseVbox(VBox chooseVbox) {
this.chooseVbox = chooseVbox;
}
public Map<String, Object> getContext() {
return context;
}
public void setContext(Map<String, Object> context) {
this.context = context;
}
}

View File

@ -2,6 +2,7 @@ package com.zhangmeng.online.exam.ui.components.callBack;
import com.zhangmeng.online.exam.ui.api.ApiUtils;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.ObservableList;
import java.util.List;
import java.util.Map;
@ -14,7 +15,10 @@ import java.util.Map;
public interface PaperViewComponentCallBack {
ApiUtils.DataView loadQuestionData(int pageNum, int pageSize);
ApiUtils.DataView loadChooseQuestionData(int pageNum, int pageSize);
ApiUtils.DataView loadChooseQuestionData(Map<String, Object> context,int pageNum, int pageSize);
ApiUtils.DataView searchQuestionData(String searchText, int pageNum, int pageSize);
void commitChooseQuestion(Map<String, Object> context, ObservableList<Map<String, SimpleStringProperty>> chooseTableData);
}

View File

@ -1,11 +1,17 @@
package com.zhangmeng.online.exam.ui.components.callBack;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhangmeng.online.exam.ui.api.ApiUtils;
import com.zhangmeng.online.exam.ui.api.DataLoad;
import com.zhangmeng.online.exam.ui.api.model.PaperDataLoad;
import com.zhangmeng.online.exam.ui.api.model.QuestionDataLoad;
import com.zhangmeng.online.exam.ui.utils.AlertUtils;
import com.zhangmeng.online.exam.ui.utils.HttpUtils;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.ObservableList;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -22,9 +28,9 @@ public class PaperViewComponentCallBackImpl implements PaperViewComponentCallBac
}
@Override
public ApiUtils.DataView loadChooseQuestionData(int pageNum, int pageSize) {
DataLoad dataLoad = new QuestionDataLoad();
return dataLoad.loadData(pageNum, pageSize);
public ApiUtils.DataView loadChooseQuestionData(Map<String, Object> context,int pageNum, int pageSize) {
PaperDataLoad dataLoad = new PaperDataLoad();
return dataLoad.loadChooseQuestionData(context,pageNum, pageSize);
}
@Override
@ -32,4 +38,18 @@ public class PaperViewComponentCallBackImpl implements PaperViewComponentCallBac
DataLoad dataLoad = new PaperDataLoad();
return dataLoad.searchData(Map.of("searchText", searchText), pageNum, pageSize);
}
@Override
public void commitChooseQuestion(Map<String, Object> context, ObservableList<Map<String, SimpleStringProperty>> chooseTableData) {
String id = context.get("id").toString();
List<String> ids = chooseTableData.stream().map(chooseTableDatum -> chooseTableDatum.get("id").get()).toList();
Map<String, Object> map = Map.of("id", id, "ids", JSONObject.toJSONString(ids));
String result = HttpUtils.POST(ApiUtils.API_URL + "/paper/chooseQuestion/save", map);
JSONObject jsonObject = JSON.parseObject(result);
if (jsonObject.getIntValue("code") == 200) {
AlertUtils.alert_msg("保存成功!");
} else {
AlertUtils.alert_warning("保存失败!");
}
}
}