Compare commits

...

5 Commits

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -9,7 +9,6 @@
<module name="attendance" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel target="17" />
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">

@ -1,14 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AliAccessStaticViaInstance" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliArrayNamingShouldHaveBracket" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliControlFlowStatementWithoutBraces" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliDeprecation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliEqualsAvoidNull" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliLongLiteralsEndingWithLowercaseL" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliMissingOverrideAnnotation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliWrapperTypeEquality" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MapOrSetKeyShouldOverrideHashCodeEquals" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliControlFlowStatementWithoutBraces" enabled="true" level="WEAK WARNING" enabled_by_default="true" editorAttributes="INFO_ATTRIBUTES" />
</profile>
</component>

@ -6,11 +6,6 @@
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="http://mirrors.cloud.tencent.com/nexus/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
@ -21,5 +16,10 @@
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
</component>
</project>

@ -8,7 +8,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="corretto-17 (2)" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="corretto-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -1,124 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

@ -1,19 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="3b22332f-54e5-44db-aa06-c42dcb64501b" name="更改" comment="">
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/AttendanceApplication.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/config/SecurityConfig.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/controller/RollCallController.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/controller/StudentController.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/controller/TeacherController.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/entity/PointsRequest.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/entity/RollCallResponse.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/entity/RollCallSettings.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/entity/Student.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/entity/Teacher.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/mapper/StudentMapper.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/mapper/TeacherMapper.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/service/RollCallService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/service/StudentService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/service/TeacherService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/service/impl/RollCallServiceImpl.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/service/impl/StudentServiceImpl.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/service/impl/TeacherServiceImpl.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/attendance/util/JWTUtil.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/resources/application.properties" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/java/com/example/attendance/AttendanceApplicationTests.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/java/com/example/attendance/PasswordEncryptor.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/java/com/example/attendance/RollCallServiceImplTest.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/java/com/example/attendance/StudentServiceImplTest.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/java/com/example/attendance/TeacherServiceImplTest.java" beforeDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 3
}</component>
<component name="ProjectId" id="2n7TontcBHYq0FZUtB4aOJMP8nL" />
<component name="ProjectViewState">
<option name="openDirectoriesWithSingleClick" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
&quot;git-widget-placeholder&quot;: &quot;main&quot;,
&quot;last_opened_file_path&quot;: &quot;C:/Users/onelastkiss/Desktop/项目/bigbigmarket&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}</component>
<component name="RunManager">
<configuration default="true" type="JetRunConfigurationType">
<module name="BACKEND_ATTENDANCE" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="KotlinStandaloneScriptRunConfigurationType">
<module name="BACKEND_ATTENDANCE" />
<option name="filePath" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="默认任务">
<changelist id="3b22332f-54e5-44db-aa06-c42dcb64501b" name="更改" comment="" />
<created>1728323291653</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1728323291653</updated>
<workItem from="1728323292792" duration="28000" />
<workItem from="1728372981142" duration="128000" />
<workItem from="1728379806368" duration="345000" />
<workItem from="1728386733302" duration="673000" />
<workItem from="1728402818365" duration="864000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>

@ -47,6 +47,16 @@ public class StudentController {
return ResponseEntity.ok(students);
}
/**
*
* @return
*/
@GetMapping("/names")
public ResponseEntity<String[]> getAllStudentNames() {
String[] studentNames = studentService.getAllStudentNames();
return ResponseEntity.ok(studentNames);
}
//添加学生信息
@PostMapping
public ResponseEntity<String> addStudent(@RequestBody Student student) {

@ -0,0 +1,15 @@
package com.example.attendance.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class RollCallSettings {
private String rollCallMode; // 点名("点名")或提问("提问")
private String triggerRandomEvent; // 触发("触发")或不触发("不触发")随机事件
private String wheelOfFortune; // 开启("是")或关闭("否")命运轮盘
}

@ -46,4 +46,11 @@ public interface StudentMapper {
*/
@Select("SELECT * FROM student ORDER BY points DESC LIMIT #{size} OFFSET #{offset}")
List<Student> findStudentsByRanking(@Param("offset") int offset, @Param("size") int size);
/**
*
* @return
*/
@Select("SELECT name FROM student")
String[] findAllStudentNames();
}

@ -19,4 +19,5 @@ public interface StudentService {
void update(Student student);
void delete(Long id);
String[] getAllStudentNames();
}

@ -6,7 +6,6 @@ import com.example.attendance.entity.Student;
import com.example.attendance.service.RollCallService;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
import java.util.Random;
@ -16,11 +15,11 @@ public class RollCallServiceImpl implements RollCallService {
@Override
public RollCallResponse startRollCall(List<Student> students, RollCallSettings settings) {
// 1. 根据设定选择点名或提问模式
String mode = settings.isRollCall() ? "点名" : "提问";
String mode = "点名".equals(settings.getRollCallMode()) ? "点名" : "提问";
System.out.println("当前模式:" + mode);
// 2. 处理命运轮盘 (所有人概率相等)
if (settings.isWheelOfFortune()) {
if ("是".equals(settings.getWheelOfFortune())) {
return handleWheelOfFortune(students);
}
@ -32,7 +31,7 @@ public class RollCallServiceImpl implements RollCallService {
response.setPoints(selectedStudent.getPoints());
// 4. 判断是否触发随机事件
if (settings.isTriggerRandomEvent()) {
if ("触发".equals(settings.getTriggerRandomEvent())) {
response.setMessage("触发了随机事件: " + triggerRandomEvent());
} else {
response.setMessage("没有触发随机事件," + selectedStudent.getName() + " 被点了!");

@ -98,6 +98,7 @@ public class StudentServiceImpl implements StudentService {
* @param studentNumber
* @param pointsDelta
*/
@Override
public void adjustPoints(String studentNumber, BigDecimal pointsDelta) {
Student student = studentMapper.findByStudentNumber(studentNumber);
if (student == null) {
@ -114,6 +115,7 @@ public class StudentServiceImpl implements StudentService {
* @param size
* @return
*/
@Override
public List<Student> getStudentRanking(int page, int size) {
int offset = page * size;
return studentMapper.findStudentsByRanking(offset, size);
@ -148,4 +150,13 @@ public class StudentServiceImpl implements StudentService {
public void delete(Long id) {
studentMapper.delete(id);
}
/**
*
* @return
*/
@Override
public String[] getAllStudentNames() {
return studentMapper.findAllStudentNames();
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 MiB

After

Width:  |  Height:  |  Size: 27 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/点名.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>点点小助手</title>
<script type="module" crossorigin src="/assets/index-Cb5FnDWH.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-B1hDzaLh.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 649 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1727709759865" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6581" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M485.568 906.496c-0.64-0.192-145.088 10.368-209.216-16.256-86.528-35.968-117.184-62.592-117.184-79.488 0-15.936-2.944-98.112 77.248-123.2a4319.36 4319.36 0 0 1 155.264-43.136 25.216 25.216 0 0 0 22.08-24.832V541.888a24.064 24.064 0 0 0-7.68-17.664c-69.248-66.56-97.728-131.456-97.728-243.584 0-53.312 14.656-91.008 39.296-119.744 26.496-31.104 68.032-46.912 123.264-46.912 159.104 0 169.408 128.384 169.408 171.392a291.072 291.072 0 0 1-26.56 122.048c-13.056 28.544-26.624 44.736-26.752 45.12a24.256 24.256 0 0 0 3.776 35.2 26.88 26.88 0 0 0 36.672-3.648c2.56-3.072 65.088-77.696 65.088-198.72 0-65.024-16.832-109.376-52.544-150.72C600.256 88.448 541.76 64 470.976 64 335.808 64 256.256 140.416 256.256 280.704c0 60.864 8.192 104.256 25.024 148.928a340.48 340.48 0 0 0 80.256 122.368v46.784c-36.928 6.72-73.408 15.552-109.312 26.368-39.232 12.16-70.848 25.536-93.824 40.256-34.176 21.632-51.456 117.76-51.456 145.344 0 45.76 48.64 83.968 149.056 125.504 67.712 28.032 213.12 17.664 215.872 18.368l6.848 1.024a25.92 25.92 0 0 0 25.28-18.496 24.704 24.704 0 0 0-18.432-30.656z" p-id="6582" fill="#8755f2"></path><path d="M937.024 515.776a26.624 26.624 0 0 0-37.376 4.16c-9.152 11.456-199.808 266.624-228.224 268.928-27.712 2.432-122.752-90.112-122.752-90.112a26.496 26.496 0 0 0-36.224 4.032 26.56 26.56 0 0 0 1.856 36.48c10.304 9.664 101.056 82.048 123.072 98.304l25.6 18.816c5.12 3.264 10.752 5.376 16.576 4.736a23.68 23.68 0 0 0 17.536-9.152c6.208-7.36 35.52-41.344 35.776-41.792l208.448-257.216a26.56 26.56 0 0 0-4.288-37.184z" p-id="6583" fill="#8755f2"></path></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/点名.svg">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

@ -0,0 +1,8 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,22 @@
{
"name": "name-nacing-system",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.7.7",
"element-plus": "^2.8.4",
"element-ui": "^2.15.14",
"vue": "^3.4.29",
"vue-router": "^4.3.3"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.5",
"vite": "^5.3.1"
}
}

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1727709759865" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6581" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M485.568 906.496c-0.64-0.192-145.088 10.368-209.216-16.256-86.528-35.968-117.184-62.592-117.184-79.488 0-15.936-2.944-98.112 77.248-123.2a4319.36 4319.36 0 0 1 155.264-43.136 25.216 25.216 0 0 0 22.08-24.832V541.888a24.064 24.064 0 0 0-7.68-17.664c-69.248-66.56-97.728-131.456-97.728-243.584 0-53.312 14.656-91.008 39.296-119.744 26.496-31.104 68.032-46.912 123.264-46.912 159.104 0 169.408 128.384 169.408 171.392a291.072 291.072 0 0 1-26.56 122.048c-13.056 28.544-26.624 44.736-26.752 45.12a24.256 24.256 0 0 0 3.776 35.2 26.88 26.88 0 0 0 36.672-3.648c2.56-3.072 65.088-77.696 65.088-198.72 0-65.024-16.832-109.376-52.544-150.72C600.256 88.448 541.76 64 470.976 64 335.808 64 256.256 140.416 256.256 280.704c0 60.864 8.192 104.256 25.024 148.928a340.48 340.48 0 0 0 80.256 122.368v46.784c-36.928 6.72-73.408 15.552-109.312 26.368-39.232 12.16-70.848 25.536-93.824 40.256-34.176 21.632-51.456 117.76-51.456 145.344 0 45.76 48.64 83.968 149.056 125.504 67.712 28.032 213.12 17.664 215.872 18.368l6.848 1.024a25.92 25.92 0 0 0 25.28-18.496 24.704 24.704 0 0 0-18.432-30.656z" p-id="6582" fill="#8755f2"></path><path d="M937.024 515.776a26.624 26.624 0 0 0-37.376 4.16c-9.152 11.456-199.808 266.624-228.224 268.928-27.712 2.432-122.752-90.112-122.752-90.112a26.496 26.496 0 0 0-36.224 4.032 26.56 26.56 0 0 0 1.856 36.48c10.304 9.664 101.056 82.048 123.072 98.304l25.6 18.816c5.12 3.264 10.752 5.376 16.576 4.736a23.68 23.68 0 0 0 17.536-9.152c6.208-7.36 35.52-41.344 35.776-41.792l208.448-257.216a26.56 26.56 0 0 0-4.288-37.184z" p-id="6583" fill="#8755f2"></path></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,26 @@
<template>
<div>
<router-view/>
</div>
</template>
<style>
/* 让页面铺满整个屏幕,不出现滚动条 */
html,
body,
#app {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
</style>
<script>
export default {
name: "Layout",
}
</script>

@ -0,0 +1,121 @@
.login-register-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-image: linear-gradient(to right, rgb(219, 219, 245), #f4dfe3);
}
.form-box {
background: rgba(211, 197, 252, 1);
padding: 100px 110px;
padding-top: 15px;
border-radius: 40px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
width: 350px;
}
h2 {
text-align: center;
color: #FFFFFF;
margin-bottom: 30px;
font-size: 45px;
}
.tab-switch {
display: flex;
margin-bottom: 20px;
}
.tab-switch span {
margin-right: 25px;
font-size: 22px;
padding: 3px 7px;
border-radius: 3px;
cursor: pointer;
color: #FFFFFF;
}
.tab-switch span.active {
border-bottom: 4px solid #FFFFFF;
}
.input-group {
position: relative;
display: flex;
align-items: center;
width: 100%;
padding: 10px 0px;
border-radius: 20px;
box-shadow: 0px 0px 10px 0px #D5E8FF;
background-color: rgba(243, 243, 243, 0.5);
border: 1px solid #FFFFFF;
margin-top: 20px;
}
.input-group input:focus {
outline: none;
/* box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.5); */
}
.input-icon {
width: 25px;
height: 25px;
margin-left: 15px;
margin-right: 5px;
}
.placeholder {
color: #FFFFFF;
}
input {
flex: 1;
height: 100%;
border: none;
background: transparent;
padding: 0 10px;
color: #615EF8;
font-size: 16px;
}
.forgot-password {
text-align: right;
margin-top: 15px;
}
.forgot-password a {
color: #FFFFFF;
text-decoration: none;
}
.submit-btn {
width: 100%;
padding: 12px 0;
margin-top: 15px;
background-color: #8755F2;
color: #FFFFFF;
border-radius: 20px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s;
box-shadow: 0px 0px 10px 0px #D5E8FF;
border: 1px solid #FFFFFF;
}
.submit-btn:hover {
background-color: #6231F5;
}
/* 隐藏默认的密码切换图标 */
input[type="password"]::-ms-reveal,
input[type="password"]::-ms-clear,
input[type="password"]::-webkit-contacts-auto-fill-button,
input[type="password"]::-webkit-credentials-auto-fill-button {
display: none !important;
}
/* 对于Chrome浏览器 */
input[type="password"]::-webkit-inner-spin-button,
input[type="password"]::-webkit-outer-spin-button,
input[type="password"]::-webkit-search-cancel-button {
-webkit-appearance: none;
margin: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

@ -0,0 +1,21 @@
// 引入createApp用于创建应用
import { createApp } from 'vue'
// 引入App.vue文件
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// new Vue({
// el: '#app',
// render: h => h(App)
// });
const app = createApp(App)
app.use(router)
app.use(ElementPlus)
app.mount('#app')

@ -0,0 +1,38 @@
import { createRouter, createWebHistory} from 'vue-router'
// 引入路由组件
import login from '@/views/login2.vue'
import home from '@/views/home.vue'
import importFile from '@/views/importFile.vue'
import ruleSetting from '@/views/ruleSetting.vue'
// 创建路由器
const router = createRouter({
// 路由器的工作模式
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
// name: 'home',
component: login
},
{
path:'/home',
component: home,
children:[
{
path:'importFile',
component: importFile
},
{
path:'ruleSetting',
component: ruleSetting
}
]
}
]
})
export default router

@ -0,0 +1,18 @@
// 存储、获取、删除token的文件
// 定义 setToken 函数,用于将 token 存储到 localStorage
export function setToken(token) {
localStorage.setItem('authToken', token);
}
// 定义 getToken 函数,用于从 localStorage 获取 token
export function getToken() {
return localStorage.getItem('authToken');
}
// 定义 removeToken 函数,用于从 localStorage 删除 token
export function removeToken() {
localStorage.removeItem('authToken');
}

@ -0,0 +1,89 @@
// axiosConfig.js
import axios from 'axios';
import {getToken} from '@/token/auth' // 注意这里使用了解构赋值来导入getToken函数
// 创建axios实例
const service = axios.create({
baseURL: 'http://example.com/api', // 配置基础URL
timeout: 5000, // 请求超时时间
});
// 请求拦截器
service.interceptors.request.use(
config => {
// 在发送请求之前做些什么
const token = getToken(); // 获取token的方式取决于你的应用
if (token) {
config.headers['Authorization'] = `Bearer ${token}`; // 设置token
}
return config;
},
error => {
// 对请求错误做些什么
console.error('Request Error:', error);
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
response => {
// 对响应数据做点什么
const res = response.data;
// 你可以根据实际情况在这里添加一些通用的响应处理逻辑
// 例如,根据返回的状态码判断请求是否成功
if (res.code !== 200) {
// 业务错误处理,比如弹窗提示等
return Promise.reject(new Error(res.message || 'Error'));
} else {
return res;
}
},
error => {
// 对响应错误做点什么
if (error.response) {
// 请求已发出但服务器响应的状态码不在2xx的范围
console.error('Error status:', error.response.status);
console.error('Error data:', error.response.data);
} else if (error.request) {
// 请求已发出,但没有收到响应
console.error('Error request:', error.request);
} else {
// 在设置请求时触发错误
console.error('Error message:', error.message);
}
return Promise.reject(error);
}
);
export default service;
// 使用
// 导入封装好的axios实例
// import axios from './axiosConfig';
// 登录方法
// methods: {
// async login() {
// try {
// const response = await axios.post('/api/login', {
// username: this.username,
// password: this.password
// });
// // 假设token在响应的data字段中
// const token = response.data.token;
// // 存储token
// setToken(token);
// // 登录成功后的操作,比如跳转到主页
// this.$router.push('/home');
// } catch (error) {
// // 处理登录错误
// console.error('Login Error:', error);
// }
// }
// }

@ -0,0 +1,80 @@
<template>
<div class="home">
<div class="content">
<!-- 展示区 -->
<div class="leftIcon">
<RouterView></RouterView>
</div>
<!-- 导航栏 -->
<div class="select">
<div @click="gotoImpt" class="selectItem">
导入文件
</div>
<div class="selectItem">
开始点名
</div>
<div @click="gotoRule" class="selectItem">
规则设置
</div>
<div class="selectItem">
查看排行
</div>
</div>
</div>
</div>
</template>
<script>
import { RouterLink, RouterView } from 'vue-router';
export default {
data() {
return {
}
},
methods: {
gotoImpt(){
this.$router.push('/home/importFile')
},
gotoRule() {
this.$router.push('/home/ruleSetting')
}
}
}
</script>
<style scoped>
.home {
background-image: url('../assets/image/bgcImg.png'); /* 图片路径 */
width:100%;
height:100%;
position:fixed;
background-size:100% 100%;
}
.content {
height:100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 120px;
}
.leftIcon {
width: 700px;
height: 800px;
/* background-color: red; */
}
.selectItem {
padding: 25px 130px;
border-radius: 50px;
background-color: #A182FF;
color: #FFFFFF;
font-size: 35px;
font-weight: bold;
margin-bottom: 65px;
cursor: pointer;
text-decoration: none;
}
.selectItem:hover {
background-color: #6231F5;
}
</style>

@ -0,0 +1,206 @@
<template>
<div class="imptFile">
<!-- 头部 -->
<div class="header">
<div>导入学生名单</div>
<img src="../assets/image/close.png" alt="" class="icon" @click="close">
</div>
<div style="border: 1.5px solid #C8C1C1;"></div>
<!-- 上传文件 -->
<el-upload
ref="uploadRef"
class="upload-demo"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
:auto-upload="false"
:limit="1"
accept=".xlsx, .xls"
:on-exceed="handleExceed"
>
<div style="font-size: 30px; color: #7D7878;">选择文件</div>
<input placeholder="请选择上传的文件" class="inputFile" />
<!-- <template #trigger> -->
<el-button type="primary" color="#A182FF" class="btn">选取文件</el-button>
<!-- </template> -->
<!-- 按钮下面放置文件区 -->
<!-- <el-button class="ml-3" type="success" @click="submitUpload">
upload to server
</el-button> -->
<template #tip>
<div class="el-upload__tip">
请上传Excel文件文件大小不超过500KB
</div>
</template>
</el-upload>
<!-- 下载模板 -->
<a
class="download"
href="后端提供的下载URL"
download="student-template.xlsx"
@click="onDownload"
>
模板下载
</a>
<!-- 模板示例 -->
<div>
<div style="color: #8755F2; font-size: 28px; margin: 30px 0 0 40px;">模板示例</div>
<div style="display: flex; justify-content: center; margin-top:10px;">
<img src="../assets/image/muban.png" alt="" style="height: 250px;">
</div>
</div>
<!-- 底部 -->
<div class="bottom">
<div style="display: flex;">
<div class="confirm" @click="submitUpload"></div>
<div class="cancel" @click="close"></div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { genFileId } from 'element-plus'
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
import router from '@/router';
const uploadRef = ref<UploadInstance>()
//
const handleExceed: UploadProps['onExceed'] = (files) => {
uploadRef.value!.clearFiles()
const file = files[0] as UploadRawFile
file.uid = genFileId()
uploadRef.value!.handleStart(file)
}
//
const submitUpload = () => {
uploadRef.value!.submit()
}
//
const onDownload = (event: MouseEvent) => {
//
//
// <a>href
event.preventDefault();
// 使fetchhref
window.open("后端提供的下载URL", '_blank');
}
function close() {
router.push('/home')
}
</script>
<style scoped>
.imptFile{
position: relative;
background-color: #fff;
border-radius: 40px;
height: 100%;
padding-top: 10px;
box-shadow: 5px 10px 10px 5px rgba(2, 2, 2, 0.1);
overflow: hidden;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 60px;
font-size: 35px;
font-weight: bold;
}
.icon {
width: 45px;
cursor: pointer;
}
.icon:hover {
transform: scale(1.3);
}
.upload-demo {
margin-top: 35px;
padding: 0 20px;
}
.inputFile {
height: 60px;
width: 300px;
font-size: 23px;
margin-left: 20px;
border-radius: 10px;
border: 1.5px solid #272636;
padding-left: 20px;
}
.inputFile::placeholder {
padding-left: 0;
}
.btn {
height: 70px;
border-radius: 10px;
padding: 10px;
font-size: 30px;
margin-left: 30px;
color: #fff;
}
.btn:hover {
color: #fff;
transform: scale(1.1);
}
.el-upload__tip {
font-size: 23px;
margin: 25px 0 25px 70px;
}
.download{
color: #8755F2;
font-size: 28px;
margin: 20px 0 0 40px;
cursor: pointer;
text-decoration: none;
}
.download:hover {
color: #6231F5;
text-decoration: underline;
}
.bottom{
position: absolute;
display: flex; align-items: center; justify-content: right;
bottom: 0;
width: 100%;
padding: 30px 30px;
background-color: #EBE4FF;
}
.cancel {
width: auto;
border-radius: 5px;
padding: 20px 35px;
margin-right: 70px;
font-size: 28px;
background-color: #fff;
color: #A182FF;
cursor: pointer;
}
.cancel:hover {
background-color: #dfdede;
}
.confirm{
width: auto;
border-radius: 5px;
padding: 20px 35px;
margin-right: 30px;
font-size: 28px;
background-color: #A182FF;
color: #fff;
cursor: pointer;
}
.confirm:hover {
background-color: #6231F5;
}
</style>

@ -0,0 +1,187 @@
<template>
<div class="login-register-container">
<div class="form-box">
<h2>让我们开始点名</h2>
<div class="tab-switch">
<span
:class="{ active: activeTab === 'login' }"
@click="switchTab('login')"
>
登录
</span>
<span
:class="{ active: activeTab === 'register' }"
@click="switchTab('register')"
>
注册
</span>
</div>
<!-- 登录表单 -->
<form v-if="activeTab === 'login'" @submit.prevent="handleLogin">
<div class="input-group">
<img src="../assets/image/person.png" alt="" class="input-icon">
<input
v-model="loginForm.phone"
type="text"
placeholder="请输入您的手机号"
placeholder-class="placeholder"
>
</div>
<div class="input-group">
<img src="../assets/image/password.png" alt="" class="input-icon">
<input
v-model="loginForm.password"
:type="showPassword ? 'text' : 'password'"
placeholder="请输入您的密码"
>
<img src="../assets/image/eye.png"
v-if="showPassword"
class="input-icon"
@click="togglePasswordVisibility"
style="cursor: pointer;margin-right: 15px;"
>
<img src="../assets/image/eyeClose.png"
v-if="!showPassword"
class="input-icon"
@click="togglePasswordVisibility"
style="cursor: pointer;margin-right: 15px;"
>
</div>
<div class="forgot-password">
<a href="#">忘记密码?</a>
</div>
<button type="submit" class="submit-btn"> </button>
</form>
<!-- 注册表单 -->
<form v-else @submit.prevent="handleRegister">
<div class="input-group">
<img src="../assets/image/person.png" alt="" class="input-icon">
<input
v-model="registerForm.phone"
type="text"
placeholder="请输入您的手机号"
>
</div>
<div class="input-group">
<img src="../assets/image/password.png" alt="" class="input-icon">
<input
v-model="registerForm.password"
:type="showPassword ? 'text' : 'password'"
placeholder="请输入您的密码"
>
<img src="../assets/image/eye.png"
v-if="showPassword"
class="input-icon"
@click="togglePasswordVisibility"
style="cursor: pointer;margin-right: 15px;"
>
<img src="../assets/image/eyeClose.png"
v-if="!showPassword"
class="input-icon"
@click="togglePasswordVisibility"
style="cursor: pointer;margin-right: 15px;"
>
</div>
<div class="input-group">
<img src="../assets/image/password.png" alt="" class="input-icon">
<input
v-model="registerForm.confirmPassword"
:type="showConfirmPassword ? 'text' : 'password'"
placeholder="再次确认密码"
>
<img src="../assets/image/eye.png"
v-if="showPassword"
class="input-icon"
@click="togglePasswordVisibility"
style="cursor: pointer;margin-right: 15px;"
>
<img src="../assets/image/eyeClose.png"
v-if="!showPassword"
class="input-icon"
@click="togglePasswordVisibility"
style="cursor: pointer;margin-right: 15px;"
>
</div>
<button type="submit" class="submit-btn" style="margin-top: 25px;">注册</button>
</form>
</div>
</div>
</template>
<script>
import axios from '@/utils/axiosConfig';
import {setToken} from '@/token/auth'
export default {
data() {
return {
activeTab: 'login',
showPassword: false,
showConfirmPassword: false,
loginForm: {
phone: '',
password: ''
},
registerForm: {
phone: '',
password: '',
confirmPassword: ''
}
}
},
methods: {
switchTab(tab) {
this.activeTab = tab;
},
togglePasswordVisibility() {
this.showPassword = !this.showPassword;
},
//
async handleLogin() {
try {
const response = await axios.post('/teacher/login', {
username: this.loginForm.phone,
password: this.loginForm.password
});
// tokendata
const token = response.data.token;
// token
setToken(token);
//
this.$router.push('/home');
} catch (error) {
//
console.error('Login Error:', error);
}
},
//
async handleRegister() {
if (this.registerForm.password !== this.registerForm.confirmPassword) {
alert('两次输入的密码不一致');
return;
}
try {
//
const response = await axios.post('/teacher/register', {
username: this.registerForm.phone,
password: this.registerForm.password,
});
//
console.log('注册成功', response);
} catch (error) {
//
console.error('注册失败', error);
}
}
}
}
</script>
<style scoped>
@import '../assets/css/login.css'
</style>

@ -0,0 +1,192 @@
<template>
<div class="imptFile">
<!-- 头部 -->
<div class="header">
<div>规则设置</div>
<img src="../assets/image/close.png" alt="" class="icon" @click="close">
</div>
<div style="border: 1.5px solid #C8C1C1;"></div>
<!-- 问题 -->
<el-form :model="form" label-position="top">
<el-form-item label="进行点名 or 提问 ">
<el-radio-group v-model="form.nameOrQuestion">
<el-radio label="点名">点名</el-radio>
<el-radio label="提问">提问</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否触发随机事件 ">
<el-radio-group v-model="form.triggerRandomEvent">
<el-radio label="触发">触发</el-radio>
<el-radio label="不触发">不触发</el-radio>
</el-radio-group>
</el-form-item>
<!-- 最后一个问题 -->
<el-tooltip
content="今天众生平等!所有人被抽到的概率相等"
placement="bottom-start"
effect="dark"
>
<div class="lastQues">是否开启&quot;命运轮盘&quot; </div>
</el-tooltip>
<el-radio-group v-model="form.enableFateWheel" class="lastOpt">
<el-radio label="是"></el-radio>
<el-radio label="否"></el-radio>
</el-radio-group>
</el-form>
<!-- 底部 -->
<div class="bottom">
<div style="display: flex;">
<div class="confirm" @click="confirmSetting"></div>
<div class="cancel" @click="close"></div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import router from '@/router';
import { ref } from 'vue'
import { ElTooltip } from 'element-plus'
const form = ref({
nameOrQuestion: '点名',
triggerRandomEvent: '触发',
enableFateWheel: '否'
})
const confirmSetting = () => {
// ,
const data = {
nameOrQuestion: form.value.nameOrQuestion,
triggerRandomEvent: form.value.triggerRandomEvent,
enableFateWheel: form.value.enableFateWheel,
}
// form
console.log(form.value.nameOrQuestion)
// API
console.log('发送到后端的数据:', data)
}
function close() {
router.push('/home')
}
</script>
<style scoped>
.imptFile{
position: relative;
background-color: #fff;
border-radius: 40px;
height: 100%;
padding-top: 10px;
box-shadow: 5px 10px 10px 5px rgba(2, 2, 2, 0.1);
overflow: hidden;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 60px;
font-size: 35px;
font-weight: bold;
}
.icon {
width: 45px;
cursor: pointer;
}
.icon:hover {
transform: scale(1.3);
}
.bottom{
position: absolute;
display: flex; align-items: center; justify-content: right;
bottom: 0;
width: 100%;
padding: 30px 30px;
background-color: #EBE4FF;
}
.cancel {
width: auto;
border-radius: 5px;
padding: 20px 35px;
margin-right: 70px;
font-size: 28px;
background-color: #fff;
color: #A182FF;
cursor: pointer;
}
.cancel:hover {
background-color: #dfdede;
}
.confirm{
width: auto;
border-radius: 5px;
padding: 20px 35px;
margin-right: 30px;
font-size: 28px;
background-color: #A182FF;
color: #fff;
cursor: pointer;
}
.confirm:hover {
background-color: #6231F5;
}
/* add */
.el-form-item {
margin: 50px 0 0 60px;
}
.el-radio {
margin: 45px 80px;
margin-bottom: 0;
}
/* 最后一个问题 */
.lastQues {
margin: 50px 0 0 60px;
font-size: 35px; /* 调整为你想要的大小 */
font-weight: bold;
color: #7D7878;
cursor: pointer;
}
.lastOpt{
margin-left: 60px;
}
:deep(.el-form-item__label) {
font-size: 35px; /* 调整为你想要的大小 */
font-weight: bold;
color: #7D7878;
}
/* 如果你也想改变输入框内的文字大小 */
:deep(.el-radio__label) {
color: #8755F2;
font-size: 35px;font-weight: bold;
}
:deep(.el-radio__inner) {
width: 20px; /* 调整单选按钮的宽度 */
height: 20px; /* 调整单选按钮的高度 */
border-color: #8755F2;font-weight: bold;
}
/* 改变选中时的颜色 */
/* 单选框 */
:deep(.el-radio__input.is-checked .el-radio__inner) {
border-color: #6231F5;
background: #6231F5;
}
/* 选项文字 */
:deep(.el-radio__input.is-checked+.el-radio__label) {
color: #6231F5;
}
</style>

@ -0,0 +1,16 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})

@ -1,15 +0,0 @@
package com.example.attendance.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class RollCallSettings {
private boolean isRollCall; // 点名(true)或提问(false)
private boolean triggerRandomEvent; // 是否触发随机事件
private boolean wheelOfFortune; // 是否开启命运轮盘
}

@ -1,13 +0,0 @@
package com.example.attendance;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AttendanceApplicationTests {
@Test
void contextLoads() {
}
}

@ -1,117 +0,0 @@
package com.example.attendance;
import com.example.attendance.entity.RollCallResponse;
import com.example.attendance.entity.RollCallSettings;
import com.example.attendance.entity.Student;
import com.example.attendance.service.impl.RollCallServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class RollCallServiceImplTest {
@InjectMocks
private RollCallServiceImpl rollCallService;
private List<Student> students;
private RollCallSettings settings;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
// 模拟学生列表
students = Arrays.asList(
createStudent("1", "Alice", 50),
createStudent("2", "Bob", 90),
createStudent("3", "Charlie", 30)
);
// 初始化点名设置
settings = new RollCallSettings();
settings.setRollCall(true);
settings.setTriggerRandomEvent(false);
settings.setWheelOfFortune(false);
}
// 测试正常点名模式
@Test
void testStartRollCall_NormalMode() {
RollCallResponse response = rollCallService.startRollCall(students, settings);
// 控制台输出
System.out.println("Test: Normal Mode");
System.out.println("Student ID: " + response.getStudentId());
System.out.println("Message: " + response.getMessage());
assertNotNull(response);
assertNotNull(response.getStudentId());
assertTrue(response.getMessage().contains("没有触发随机事件"));
}
// 测试提问模式
@Test
void testStartRollCall_QuestionMode() {
settings.setRollCall(false); // 设置为提问模式
RollCallResponse response = rollCallService.startRollCall(students, settings);
// 控制台输出
System.out.println("Test: Question Mode");
System.out.println("Student ID: " + response.getStudentId());
System.out.println("Message: " + response.getMessage());
assertNotNull(response);
assertNotNull(response.getStudentId());
assertTrue(response.getMessage().contains("没有触发随机事件"));
}
// 测试命运轮盘模式
@Test
void testStartRollCall_WheelOfFortune() {
settings.setWheelOfFortune(true); // 开启命运轮盘
RollCallResponse response = rollCallService.startRollCall(students, settings);
// 控制台输出
System.out.println("Test: Wheel of Fortune Mode");
System.out.println("Student ID: " + response.getStudentId());
System.out.println("Message: " + response.getMessage());
assertNotNull(response);
assertNotNull(response.getStudentId());
assertTrue(response.getMessage().contains("命运轮盘"));
}
// 测试触发随机事件
@Test
void testStartRollCall_TriggerRandomEvent() {
settings.setTriggerRandomEvent(true); // 触发随机事件
RollCallResponse response = rollCallService.startRollCall(students, settings);
// 控制台输出
System.out.println("Test: Random Event Triggered");
System.out.println("Student ID: " + response.getStudentId());
System.out.println("Message: " + response.getMessage());
assertNotNull(response);
assertNotNull(response.getStudentId());
assertTrue(response.getMessage().contains("触发了随机事件"));
}
// 辅助方法,创建学生
private Student createStudent(String id, String name, int points) {
Student student = new Student();
student.setStudentNumber(id);
student.setName(name);
student.setPoints(BigDecimal.valueOf(points));
return student;
}
}

@ -1,7 +0,0 @@
spring.application.name=attendance
spring.datasource.url=jdbc:mysql://localhost:3306/roll_call_system
spring.datasource.username=root
spring.datasource.password=123456789jk
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

@ -1,3 +0,0 @@
artifactId=attendance
groupId=com.example
version=0.0.1-SNAPSHOT

@ -1,13 +0,0 @@
com\example\attendance\entity\RandomEvent.class
com\example\attendance\mapper\StudentMapper.class
com\example\attendance\AttendanceApplication.class
com\example\attendance\entity\RollCallRecord.class
com\example\attendance\service\StudentService.class
com\example\attendance\entity\Student.class
com\example\attendance\dto\RollCallResultDTO.class
com\example\attendance\controller\RollCallController.class
com\example\attendance\mapper\RollCallRecordMapper.class
com\example\attendance\dto\StudentDTO.class
com\example\attendance\service\RollCallService.class
com\example\attendance\controller\StudentController.class
com\example\attendance\mapper\RandomEventMapper.class

@ -1,24 +0,0 @@
D:\attendance\src\main\java\com\example\attendance\controller\RollCallController.java
D:\attendance\src\main\java\com\example\attendance\service\StudentService.java
D:\attendance\src\main\java\com\example\attendance\util\JWTUtil.java
D:\attendance\src\main\java\com\example\attendance\entity\RandomEvent.java
D:\attendance\src\main\java\com\example\attendance\service\TeacherService.java
D:\attendance\src\main\java\com\example\attendance\controller\TeacherController.java
D:\attendance\src\main\java\com\example\attendance\dto\StudentExcelDTO.java
D:\attendance\src\main\java\com\example\attendance\service\impl\TeacherServiceImpl.java
D:\attendance\src\main\java\com\example\attendance\dto\RollCallRequestDTO.java
D:\attendance\src\main\java\com\example\attendance\entity\Student.java
D:\attendance\src\main\java\com\example\attendance\service\impl\StudentServiceImpl.java
D:\attendance\src\main\java\com\example\attendance\service\RollCallService.java
D:\attendance\src\main\java\com\example\attendance\config\SecurityConfig.java
D:\attendance\src\main\java\com\example\attendance\dto\StudentDTO.java
D:\attendance\src\main\java\com\example\attendance\entity\Teacher.java
D:\attendance\src\main\java\com\example\attendance\listener\StudentExcelListener.java
D:\attendance\src\main\java\com\example\attendance\entity\RollCallRecord.java
D:\attendance\src\main\java\com\example\attendance\mapper\TeacherMapper.java
D:\attendance\src\main\java\com\example\attendance\mapper\RollCallRecordMapper.java
D:\attendance\src\main\java\com\example\attendance\mapper\StudentMapper.java
D:\attendance\src\main\java\com\example\attendance\controller\StudentController.java
D:\attendance\src\main\java\com\example\attendance\dto\RollCallResultDTO.java
D:\attendance\src\main\java\com\example\attendance\AttendanceApplication.java
D:\attendance\src\main\java\com\example\attendance\mapper\RandomEventMapper.java

@ -1,2 +0,0 @@
com\example\attendance\AttendanceApplicationTests.class
com\example\attendance\StudentServiceTest.class

@ -1,3 +0,0 @@
D:\attendance\src\test\java\com\example\attendance\StudentServiceTest.java
D:\attendance\src\test\java\com\example\attendance\AttendanceApplicationTests.java
D:\attendance\src\test\java\com\example\attendance\RollCallServiceTest.java

@ -1,5 +0,0 @@
# Created at 2024-09-16T22:12:25.978
Boot Manifest-JAR contains absolute paths in classpath 'D:\attendance\target\test-classes'
Hint: <argLine>-Djdk.net.URLClassPath.disableClassPathURLCheck=true</argLine>
'other' has different root

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save