完成了用户管理界面,测试界面,测试记录,排行榜,以及权限控制,并最终美化了界面

This commit is contained in:
2026-01-04 04:09:57 +08:00
parent 6cb9a8f864
commit d0d1c6aab0
34 changed files with 2503 additions and 606 deletions

View File

@@ -1,26 +0,0 @@
package backend.controller.interfaces;
/**
* 登录控制器接口,用于处理用户登录和注册相关的业务逻辑
*/
public interface LoginController {
// AuthService authService;
//getter/setter
/**
* 处理用户登录请求
* @param username 用户名
* @param password 密码
*/
public void handleLogin(String username, String password);
/**
* 处理用户注册请求
* @param username 用户名
* @param password 密码
* @param email 邮箱地址
*/
public void handleRegister(String username, String password, String email);
}

View File

@@ -1,33 +0,0 @@
package backend.controller.interfaces;
import backend.service.interfaces.DataQueryService;
/**
* 查询控制器接口
* 定义了数据查询和管理的相关操作接口
*/
public interface QueryController {
// DataQueryService dataService;
//getter/setter
/**
* 显示所有数据项
* 该方法用于获取并展示系统中的全部数据记录
*/
void displayAll();
/**
* 根据关键字搜索数据
* @param keyword 搜索关键字,用于匹配数据项的标题、描述等字段
*/
void searchData(String keyword);
/**
* 添加新的数据项
* @param title 数据项标题
* @param desc 数据项描述
* @param category 数据项分类
* @param userId 用户ID标识数据项的创建者
*/
void addDataItem(String title, String desc, String category, int userId);
}

View File

@@ -1,33 +0,0 @@
package backend.controller.interfaces;
import backend.service.interfaces.UserService;
/**
* 用户控制器接口
* 定义了用户管理相关的核心操作方法
*/
public interface UserController {
// UserService userService;
//getter/setter
/**
* 显示指定用户的详细信息
* @param id 用户ID
*/
void showUserInfo(int id);
/**
* 列出所有用户信息
* @param adminId 管理员ID用于权限验证
*/
void listAllUsers(int adminId);
/**
* 更新用户角色
* @param targetId 目标用户ID
* @param newRole 新的角色名称
* @param adminId 执行操作的管理员ID
*/
void updateRole(int targetId, String newRole, int adminId);
}

View File

@@ -0,0 +1,160 @@
package backend.dao;
import backend.model.Charts;
import backend.utils.DBConnectionPool;
import backend.utils.DBHelper;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class ChartsDao {
List<Charts> commonResultSet(ResultSet rs) throws SQLException {
List<Charts> chartsPoList = new ArrayList<>();
while(rs.next()){
Charts charts = new Charts();
charts.setUserid(rs.getInt("userid"));
charts.setCount(rs.getInt("count"));
charts.setScore(rs.getInt("score"));
chartsPoList.add(charts);
}
return chartsPoList;
}
public List<Charts> findAll() {
List<Charts> chartsPoList = new ArrayList<>();
Connection conn = DBHelper.getInstance().getConnection();
String sql = "select userid,count,score from charts";
try {
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Charts charts = new Charts();
charts.setUserid(rs.getInt("userid"));
charts.setCount(rs.getInt("count"));
charts.setScore(rs.getInt("score"));
chartsPoList.add(charts);
}
rs.close();
stmt.close();
} catch (SQLException e) {
System.out.println("查询所有用户失败: " + e.getMessage());
}
return chartsPoList;
}
public Charts findById(int userid) {
Connection conn = DBHelper.getInstance().getConnection();
Charts chartsPo = null;
if(conn==null)
return null;
String sql = "select userid,count,score from charts where userid = ?";
try {
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1,userid);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
chartsPo = new Charts();
chartsPo.setUserid(rs.getInt("userid"));
chartsPo.setCount(rs.getInt("count"));
chartsPo.setScore(rs.getInt("score"));
}
rs.close();
stmt.close();
} catch (SQLException e) {
System.out.println("查询用户失败: " + e.getMessage());
}
return chartsPo;
}
public boolean insertCharts(Charts charts) {
Connection conn = DBHelper.getInstance().getConnection();
int row = 0;
if(conn==null)
return false;
//查找是否已存在
String findSql = "select * from charts where userid = ?";
try{
PreparedStatement stmt = conn.prepareStatement(findSql);
stmt.setInt(1,charts.getUserid());
ResultSet rs = stmt.executeQuery();
if(rs.next()){
return false;
}
rs.close();
} catch (SQLException e) {
System.out.println("查找用户失败: " + e.getMessage());
}
String sql = "insert into charts (userid,count,score) values (?,?,?)";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1,charts.getUserid());
stmt.setInt(2,charts.getCount());
stmt.setInt(3,charts.getScore());
row = stmt.executeUpdate();
stmt.close();
DBConnectionPool.releaseConnection(conn);
} catch (SQLException e) {
System.out.println("添加用户失败: " + e.getMessage());
}
return row > 0;
}
public boolean updateCharts(Charts charts) {
Connection conn = DBHelper.getInstance().getConnection();
Charts oldCharts = findById(charts.getUserid());
int row = 0;
if(conn==null)
return false;
String sql = "update charts set count = ?,score = ? where userid = ?";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1,oldCharts.getCount()+1);
stmt.setInt(2,oldCharts.getScore()+charts.getScore());
stmt.setInt(3,charts.getUserid());
row = stmt.executeUpdate();
stmt.close();
} catch (SQLException e) {
System.out.println("更新用户失败: " + e.getMessage());
}
return row > 0;
}
public boolean deleteCharts(int userid) {
Connection conn = DBHelper.getInstance().getConnection();
String sql = "delete from charts where userid = ?";
int row = 0;
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1,userid);
row = stmt.executeUpdate() ;
} catch (SQLException e) {
System.out.println("删除用户失败: " + e.getMessage());
}
return row>0;
}
public List<Charts> sortByScoreUp() {
List<Charts> chartsPoList = new ArrayList<>();
List<Charts> list = findAll();
for(int i = 0; i < list.size() - 1; i++) {
for(int j = i + 1; j < list.size(); j++) {
if(list.get(i).getScore() < list.get(j).getScore()) {
Charts temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}
}
return list;
}
public List<Charts> sortByScoreDown() {
List<Charts> chartsPoList = new ArrayList<>();
List<Charts> list = findAll();
for(int i = 0; i < list.size() - 1; i++) {
for(int j = i + 1; j < list.size(); j++) {
if(list.get(i).getScore() > list.get(j).getScore()) {
Charts temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}
}
return list;
}
}

View File

@@ -1,9 +1,11 @@
package backend.dao.impl;
package backend.dao;
import backend.model.Questions;
import backend.model.TestRecord;
import backend.utils.DBConnectionPool;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class QuestionsDao {
List<Questions> commonResultSet(ResultSet rs) throws SQLException{
@@ -41,6 +43,44 @@ public class QuestionsDao {
}
return questionPoList;
}
public Questions getById(Integer id) {
Connection conn = DBConnectionPool.getConnection();
if (conn == null)
return null;
Questions questionPo = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = conn.prepareStatement("select id,name,description,answer,frequency from questions where id = ?");
stmt.setInt(1, id);
rs = stmt.executeQuery();
if (rs.next()) { // 检查是否有数据
questionPo = new Questions();
questionPo.setId(rs.getInt("id"));
questionPo.setName(rs.getString("name"));
questionPo.setDescription(rs.getString("description"));
questionPo.setAnswer(rs.getString("answer"));
questionPo.setFrequency(rs.getInt("frequency"));
}
} catch (SQLException e) {
System.out.println("数据库异常:" + e.getMessage());
} finally {
// 释放资源
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
} catch (SQLException e) {
System.out.println("资源释放异常:" + e.getMessage());
}
DBConnectionPool.releaseConnection(conn);
}
return questionPo;
}
public List<Questions> getByCondition(Integer frequency,String key) {
List<Questions> questionPoList = null;
//1. 从连接池中拿到连接
@@ -147,6 +187,37 @@ public class QuestionsDao {
}
public Questions getRandomQuestion() {
List<Questions> questionPoList = getAll();
Random random = new Random();
//生成随机索引
int index = random.nextInt(questionPoList.size());
return questionPoList.get(index);
}
public Questions getByName(String name) {
Questions questionPo = null;
//1. 从连接池中拿到连接
Connection conn = DBConnectionPool.getConnection();
if(conn==null)
return null;
//2. 创建Statement对象
String sql = "select id,name,description,answer,frequency from questions where name = ?";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, name);
ResultSet rs = stmt.executeQuery();
questionPo = commonResultSet(rs).get(0);
rs.close();
stmt.close();
} catch(SQLException e){
System.out.println("数据库异常:"+ e.getMessage());
} finally {
DBConnectionPool.releaseConnection(conn);
}
return questionPo;
}
// public static void main(String[] args) {
// WordDao wordDao = new WordDao();
// //查询

View File

@@ -0,0 +1,163 @@
package backend.dao;
import backend.model.TestRecord;
import backend.utils.DBConnectionPool;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class TestRecordDao {
List<TestRecord> commonResultSet(ResultSet rs) throws SQLException{
List<TestRecord> testRecordPoList = new ArrayList<>();
while(rs.next()){
TestRecord testRecord = new TestRecord();
testRecord.setId(rs.getInt("id"));
testRecord.setUserId(rs.getInt("userId"));
testRecord.setQuestionId(rs.getInt("questionId"));
testRecord.setScore(rs.getInt("score"));
testRecord.setAnswer(rs.getString("answer"));
testRecord.setTime(rs.getDate("time"));
testRecordPoList.add(testRecord);
}
return testRecordPoList;
}
public List<TestRecord> getAll() {
List<TestRecord> testRecordPoList = new ArrayList<>();
//1. 从连接池中拿到连接
Connection conn = DBConnectionPool.getConnection();
if(conn==null)
return null;
//2. 创建Statement对象
String sql = "select id,userId,questionId,score,answer,time from testRecord";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
testRecordPoList=commonResultSet(rs);
rs.close();
stmt.close();
} catch(SQLException e){
System.out.println("数据库异常:"+ e.getMessage());
}
finally {
DBConnectionPool.releaseConnection(conn);
}
return testRecordPoList;
}
public List<TestRecord> getByUserId(Integer userId) {
List<TestRecord> testRecordPoList = new ArrayList<>();
//1. 从连接池中拿到连接
Connection conn = DBConnectionPool.getConnection();
if(conn==null)
return null;
//2. 创建Statement对象
String sql = "select id,userId,questionId,score,answer,time from testRecord where userId = ?";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, userId);
ResultSet rs = stmt.executeQuery();
testRecordPoList=commonResultSet(rs);
rs.close();
stmt.close();
} catch(SQLException e){
System.out.println("数据库异常:"+ e.getMessage());
} finally {
DBConnectionPool.releaseConnection(conn);
}
return testRecordPoList;
}
public List<TestRecord> getByQuestionId(Integer questionId) {
List<TestRecord> testRecordPoList = new ArrayList<>();
//1. 从连接池中拿到连接
Connection conn = DBConnectionPool.getConnection();
if(conn==null)
return null;
//2. 创建Statement对象
String sql = "select id,userId,questionId,score,answer,time from testRecord where questionId = ?";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, questionId);
ResultSet rs = stmt.executeQuery();
testRecordPoList=commonResultSet(rs);
rs.close();
stmt.close();
}
catch(SQLException e){
System.out.println("数据库异常:"+ e.getMessage());
} finally {
DBConnectionPool.releaseConnection(conn);
}
return testRecordPoList;
}
public List<TestRecord> getByUserIdAndQuestionId(Integer userId, Integer questionId) {
List<TestRecord> testRecordPoList = new ArrayList<>();
//1. 从连接池中拿到连接
Connection conn = DBConnectionPool.getConnection();
if(conn==null)
return null;
//2. 创建Statement对象
String sql = "select id,userId,questionId,score,answer,time from testRecord where userId = ? and questionId = ?";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, userId);
stmt.setInt(2, questionId);
ResultSet rs = stmt.executeQuery();
testRecordPoList = commonResultSet(rs);
rs.close();
stmt.close();
} catch(SQLException e){
System.out.println("数据库异常:"+ e.getMessage());
} finally {
DBConnectionPool.releaseConnection(conn);
}
return testRecordPoList;
}
public boolean insert(TestRecord testRecord){
int row = 0;
//1. 从连接池中拿到连接
Connection conn = DBConnectionPool.getConnection();
if(conn==null)
return false;
//2. 创建Statement对象
String sql = "insert into testRecord(userId,questionId,score,answer,time) values(?,?,?,?,?)";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, testRecord.getUserId());
stmt.setInt(2, testRecord.getQuestionId());
stmt.setInt(3, testRecord.getScore());
stmt.setString(4, testRecord.getAnswer());
stmt.setDate(5, testRecord.getTime());
row = stmt.executeUpdate();
stmt.close();
} catch(SQLException e){
System.out.println("数据库异常:"+ e.getMessage());
} finally {
DBConnectionPool.releaseConnection(conn);
}
return row > 0;
}
public boolean delete(Integer id){
int row = 0;
//1. 从连接池中拿到连接
Connection conn = DBConnectionPool.getConnection();
if(conn==null)
return false;
//2. 创建Statement对象
String sql = "delete from testRecord where id = ?";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, id);
row = stmt.executeUpdate();
stmt.close();
} catch(SQLException e){
System.out.println("数据库异常:"+ e.getMessage());
} finally {
DBConnectionPool.releaseConnection(conn);
}
return row > 0;
}
}

View File

@@ -1,57 +1,74 @@
package backend.dao.impl;
package backend.dao;
import backend.dao.interfaces.UserDaoIF;
import backend.model.User;
import backend.service.AuthService;
import backend.utils.DBConnectionPool;
import backend.utils.DBHelper;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class UserDao implements UserDaoIF {
public class UserDao {
List<User> commonResultSet(ResultSet rs) throws SQLException{
List<User> userPoList = new ArrayList<>();
while(rs.next()){
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setRole(rs.getString("role"));
user.setEmail(rs.getString("email"));
user.setCreatedAt(rs.getDate("createdAt"));
userPoList.add(user);
}
return userPoList;
}
@Override
public User findByUsername(String username) {
User user = null;
//1. 从连接池中创建数据库连接
Connection conn = DBHelper.getInstance().getConnection();
//2. 创建Statement对象
String sql = "select username,password,role,email,createdAt from USER where username = ?";
String sql = "select id,username,password,role,email,createdAt from USER where username = ?";
try {
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, username);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setRole(rs.getString("role"));
user.setEmail(rs.getString("email"));
user.setCreatedAt(String.valueOf(rs.getTimestamp("createdAt")));
user.setCreatedAt(rs.getDate("createdAt"));
}
} catch (SQLException e) {
System.out.println("查询用户失败: " + e.getMessage());
}
return user;
}
@Override
public User findById(int id) {
User user = null;
//1. 从连接池中创建数据库连接
Connection conn = DBHelper.getInstance().getConnection();
//2. 创建Statement对象
String sql = "select username,password,role,email,createdAt from USER where id = ?";
String sql = "select id,username,password,role,email,createdAt from USER where id = ?";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1,id);
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setRole(rs.getString("role"));
user.setEmail(rs.getString("email"));
user.setCreatedAt(String.valueOf(rs.getTimestamp("createdAt")));
user.setCreatedAt(rs.getDate("createdAt"));
}
}catch (SQLException e) {
System.out.println("查询用户失败: " + e.getMessage());
@@ -59,12 +76,11 @@ public class UserDao implements UserDaoIF {
return user;
}
@Override
public int addUser(User user) {
public boolean addUser(User user) {
Connection conn = DBHelper.getInstance().getConnection();
int row=0;
if(conn==null)
return 0;
return false;
String sql = "insert into USER (username,password,role,email,createdAt) values (?,?,?,?,?)";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
@@ -79,15 +95,14 @@ public class UserDao implements UserDaoIF {
} catch (SQLException e) {
System.out.println("添加用户失败: " + e.getMessage());
}
return row;
return row>0;
}
@Override
public int updateUser(User user) {
public boolean updateUser(User user) {
Connection conn = DBHelper.getInstance().getConnection();
int row = 0;
if(conn==null)
return 0;
return false;
String sql = "update USER set username = ?,password = ?,role = ?,email = ?,createdAt = ? where id = ?";
try{
@@ -100,15 +115,15 @@ public class UserDao implements UserDaoIF {
stmt.setInt(6,user.getId());
row = stmt.executeUpdate();
stmt.close();
DBConnectionPool.releaseConnection(conn);
} catch (SQLException e) {
System.out.println("更新用户失败: " + e.getMessage());
}finally {
DBConnectionPool.releaseConnection(conn);
}
return row;
return row>0;
}
@Override
public int deleteUser(int id) {
public boolean deleteUser(int id) {
Connection conn = DBHelper.getInstance().getConnection();
String sql = "delete from USER where id = ?";
int row = 0;
@@ -119,11 +134,11 @@ public class UserDao implements UserDaoIF {
} catch (SQLException e) {
System.out.println("删除用户失败: " + e.getMessage());
}
return row;
return row>0;
}
@Override
public List<User> findAll() {
List<User> userPoList = new ArrayList<>();
Connection conn = DBHelper.getInstance().getConnection();
String sql = "select id,username,password,role,email,createdAt from USER";
try {
@@ -136,12 +151,53 @@ public class UserDao implements UserDaoIF {
user.setPassword(rs.getString("password"));
user.setRole(rs.getString("role"));
user.setEmail(rs.getString("email"));
user.setCreatedAt(String.valueOf(rs.getTimestamp("createdAt")));
return List.of(user);
user.setCreatedAt(rs.getDate("createdAt"));
userPoList.add(user);
}
}catch (SQLException e) {
System.out.println("查询所有用户失败: " + e.getMessage());
}
return List.of();
return userPoList;
}
public List<User> findByCondition(String role, String key) {
List<User> userPoList = null;
//1. 从连接池中拿到连接
Connection conn = DBConnectionPool.getConnection();
if(conn==null)
return null;
//2. 创建Statement对象
String sql = "select id,username,password,role,email,createdAt from USER where username like ?";
if(role != null)
sql += " and role = ?";
try{
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, "%"+key+"%");
if(role != null)
stmt.setString(2, role);
ResultSet rs = stmt.executeQuery();
userPoList =commonResultSet(rs);
rs.close();
stmt.close();
}catch(SQLException e){
System.out.println("数据库异常:"+ e.getMessage());
}finally {
DBConnectionPool.releaseConnection(conn);
}
return userPoList;
}
public static void main(String[] args) {
UserDao userDao = new UserDao();
AuthService authService = new AuthService();
User user= userDao.findById(2);
System.out.println(user.getRole());
user.setRole("admin");
System.out.println(user.getRole());
userDao.updateUser(user);
System.out.println(userDao.findById(2).getRole());
}
}

View File

@@ -1,51 +0,0 @@
package backend.dao.interfaces;
import backend.model.DataItem;
import java.util.*;
import java.sql.*;
/**
* 数据项DAO接口提供数据项的增删改查操作
*/
public interface DataItemDao {
/**
* 根据ID查找数据项
* @param id 数据项ID
* @return 找到的数据项对象如果未找到则返回null
*/
DataItem findById(int id);
/**
* 查找所有数据项
* @return 包含所有数据项的列表
*/
List<DataItem> findAll();
/**
* 根据关键字搜索数据项
* @param keyword 搜索关键字
* @return 匹配关键字的数据项列表
*/
List<DataItem> searchByKeyword(String keyword);
/**
* 添加数据项
* @param item 要添加的数据项对象
* @return 添加成功返回true失败返回false
*/
boolean addItem(DataItem item);
/**
* 更新数据项
* @param item 包含更新信息的数据项对象
* @return 更新成功返回true失败返回false
*/
boolean updateItem(DataItem item);
/**
* 删除数据项
* @param id 要删除的数据项ID
* @return 删除成功返回true失败返回false
*/
boolean deleteItem(int id);
}

View File

@@ -1,28 +0,0 @@
package backend.dao.interfaces;
import backend.model.QueryRecord;
import java.util.*;
/**
* 查询记录数据访问接口
* 定义了对查询记录进行持久化操作的方法
*/
public interface QueryRecordDao {
/**
* 添加查询记录
* 将指定的查询记录保存到数据存储中
*
* @param record 要添加的查询记录对象不能为null
* @return 添加成功返回true否则返回false
*/
boolean addRecord(QueryRecord record);
/**
* 根据用户ID查找查询记录
* 返回指定用户的所有查询记录列表
*
* @param userId 用户唯一标识符
* @return 查询记录列表,如果未找到则返回空列表
*/
List<QueryRecord> findByUserId(int userId);
}

View File

@@ -1,52 +0,0 @@
package backend.dao.interfaces;
import backend.model.User;
import java.util.*;
/**
* 用户数据访问接口
* 定义了用户相关的数据库操作方法
*/
public interface UserDaoIF {
/**
* 根据用户名查找用户
* @param username 用户名
* @return 查找到的用户对象如果未找到则返回null
*/
User findByUsername(String username);
/**
* 根据用户ID查找用户
* @param id 用户ID
* @return 查找到的用户对象如果未找到则返回null
*/
User findById(int id);
/**
* 添加新用户
* @param user 要添加的用户对象
* @return 添加成功返回true失败返回false
*/
int addUser(User user);
/**
* 更新用户信息
* @param user 包含更新信息的用户对象
* @return 更新成功返回true失败返回false
*/
int updateUser(User user);
/**
* 删除用户
* @param id 要删除的用户ID
* @return 删除成功返回true失败返回false
*/
int deleteUser(int id);
/**
* 查找所有用户
* @return 包含所有用户对象的列表
*/
List<User> findAll();
}

View File

@@ -0,0 +1,40 @@
package backend.model;
public class Charts {
private int userid;
private int count;
private int score;
public Charts() {
}
public Charts(int userid, int count, int score) {
this.userid = userid;
this.count = count;
this.score = score;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}

View File

@@ -0,0 +1,71 @@
package backend.model;
import java.sql.*;
public class TestRecord {
private int id;
private int userId;
private int questionId;
private int score;
private String answer;
private Date time;
public TestRecord() {
}
public TestRecord(int id, int userId, int questionId, int score, String answer, Date time) {
this.id = id;
this.userId = userId;
this.questionId = questionId;
this.score = score;
this.answer = answer;
this.time = time;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getQuestionId() {
return questionId;
}
public void setQuestionId(int questionId) {
this.questionId = questionId;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}

View File

@@ -85,9 +85,6 @@ public class User {
* @param role 用户角色,可选值为"admin"或"user"
*/
public void setRole(String role) {
if(this.getUsername().equals("admin"))
this.role = "admin";
else
this.role = role;
}
@@ -114,15 +111,12 @@ public class User {
*
* @param createdAt 用户创建时间
*/
public void setCreatedAt(String createdAt) {
try {
long timestamp = Long.parseLong(createdAt);
this.createdAt = new Date(timestamp);
} catch (NumberFormatException e) {
// 如果不是有效的时间戳,可以设置为当前日期或处理异常
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public void setCreatedAt() {
this.createdAt = new Date(System.currentTimeMillis());
}
}
/**
@@ -176,7 +170,8 @@ public void setCreatedAt(String createdAt) {
* @return 用户创建时间
*/
public Date getCreatedAt() {
return Date.valueOf(String.valueOf(createdAt));
return createdAt;
}
}

View File

@@ -0,0 +1,20 @@
package backend.model.enums;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class ScoreKey {
public static final Map<Integer,Integer> SCORE_MAP = new HashMap<>();
static{
SCORE_MAP.put(0,5);
SCORE_MAP.put(1,10);
SCORE_MAP.put(2,20);
SCORE_MAP.put(3,50);
}
public static Integer getScoreByKey(Integer key) {
return SCORE_MAP.getOrDefault(key, 0);
}
}

View File

@@ -0,0 +1,85 @@
package backend.service;
import backend.dao.UserDao;
import backend.model.enums.LoginStatus;
import backend.model.User;
import java.util.List;
import java.util.Vector;
public class AuthService {
private UserDao userDao = new UserDao();
public boolean addUser(User user) {
return userDao.addUser(user);
}
public boolean deleteUser(int id) {
return userDao.deleteUser(id);
}
public LoginStatus login(User user) {
User dbUser = userDao.findByUsername(user.getUsername());
if(dbUser==null)
return LoginStatus.USER_NOT_FOUND;
if(dbUser.getUsername().equals(user.getUsername())&&dbUser.getPassword().equals(user.getPassword()))
return LoginStatus.SUCCESS;
else if (!dbUser.getUsername().equals(user.getUsername())) {
return LoginStatus.USER_NOT_FOUND;
}
return LoginStatus.PASSWORD_ERROR;
}
public LoginStatus register(User user) {
User dbAccount = userDao.findByUsername(user.getUsername());
if(dbAccount!=null)
return LoginStatus.REGISTER_FAILED;
//点击注册按钮后的事件
if(userDao.addUser(user))
return LoginStatus.REGISTER_SUCCESS;
else
return LoginStatus.REGISTER_FAILED;
}
public boolean updateUser(User user) {
return userDao.updateUser(user);
}
private Vector<Vector<String>> commonHandler(List<User> usersList){
//加工数据 把数据库查到的List转成Vector<Vector<>>
Vector<Vector<String>> usersData = new Vector<>();
if(usersList != null) {
for (User usersPo : usersList) {
Vector<String> row = new Vector<>();
row.add(String.valueOf(usersPo.getId()));
row.add(usersPo.getUsername());
row.add(usersPo.getRole());
row.add(usersPo.getEmail());
row.add(String.valueOf(usersPo.getCreatedAt()));
usersData.add(row);
}
}
return usersData;
}
public Vector<Vector<String>> getAll(){
//从数据库中获取所有用户
List<User> usersList = userDao.findAll();
//把List转成表格所需的格式
return commonHandler(usersList);
//返回给前端
}
public Vector<Vector<String>> getByCondition(String role, String key){
//从数据库中获取所有用户
List<User> usersList = userDao.findByCondition(role,key);
//把List转成表格所需的格式
return commonHandler(usersList);
//返回给前端
}
public static void main(String[] args) {
UserDao userDao = new UserDao();
AuthService authService = new AuthService();
Vector<Vector<String>> users= authService.commonHandler(userDao.findAll());
System.out.println(users);
}
}

View File

@@ -0,0 +1,52 @@
package backend.service;
import backend.dao.ChartsDao;
import backend.dao.QuestionsDao;
import backend.dao.UserDao;
import backend.model.Charts;
import java.util.*;
public class ChartsService {
private ChartsDao chartsDao = new ChartsDao();
private UserDao userDao = new UserDao();
public Vector<Vector<String>> commonHandler(List<Charts> chartsList){
Vector<Vector<String>> chartsData = new Vector<>();
if(chartsList != null) {
int i = 1;
for (Charts chartsPo : chartsList) {
Vector<String> row = new Vector<>();
row.add(String.valueOf(i++));
row.add(String.valueOf(userDao.findById(chartsPo.getUserid()).getUsername()));
row.add(String.valueOf(chartsPo.getCount()));
row.add(String.valueOf(chartsPo.getScore()));
chartsData.add(row);
}
}
return chartsData;
}
public Vector<Vector<String>> getAll(){
List<Charts> chartsList = chartsDao.findAll();
return commonHandler(chartsList);
}
public Vector<Vector<String>> sortByScoreUp(){
List<Charts> chartsList = chartsDao.sortByScoreUp();
return commonHandler(chartsList);
}
public Vector<Vector<String>> sortByScoreDown(){
List<Charts> chartsList = chartsDao.sortByScoreDown();
return commonHandler(chartsList);
}
public boolean updateCharts(Charts charts){
return chartsDao.updateCharts(charts);
}
public boolean deleteCharts(int userid){
return chartsDao.deleteCharts(userid);
}
public boolean insertCharts(Charts charts){
return chartsDao.insertCharts(charts);
}
}

View File

@@ -1,14 +1,16 @@
package backend.service.impl;
package backend.service;
import backend.dao.impl.QuestionsDao;
import backend.dao.QuestionsDao;
import backend.model.Questions;
import backend.model.enums.GlobalData;
import java.util.HashSet;
import java.util.List;
import java.util.Vector;
public class QuestionsService {
private QuestionsDao questionsDao = new QuestionsDao();
private static HashSet<Questions> questionsSet = new HashSet<>();
private Vector<Vector<String>> commonHandler(List<Questions> questionsList){
//加工数据 把数据库查到的List转成Vector<Vector<>>
Vector<Vector<String>> questionsData = new Vector<>();
@@ -26,7 +28,7 @@ public class QuestionsService {
return questionsData;
}
public Vector<Vector<String>> getAll(){
//从数据库中获取所有单词
//从数据库中获取所有题目
List<Questions> questionsList = questionsDao.getAll();
//把List转成表格所需的格式
return commonHandler(questionsList);
@@ -34,7 +36,7 @@ public class QuestionsService {
}
public Vector<Vector<String>> getByCondition(Integer frequency,String key){
//从数据库中获取所有单词
//从数据库中获取所有题目
List<Questions> wordPoList = questionsDao.getByCondition(frequency,key);
//把List转成表格所需的格式
return commonHandler(wordPoList);
@@ -48,4 +50,20 @@ public class QuestionsService {
public boolean update(Questions question){
return questionsDao.update(question);
}
public Questions getRandomQuestion() {
//使用红黑树实现的集合防止重复刷同一个题
if(questionsSet.isEmpty()) {
Questions question = questionsDao.getRandomQuestion();
questionsSet.add(question);
return question;
}
while(true) {
Questions question = questionsDao.getRandomQuestion();
if(!questionsSet.contains(question)) {
questionsSet.add(question);
return question;
}
}
}
}

View File

@@ -0,0 +1,78 @@
package backend.service;
import backend.dao.QuestionsDao;
import backend.dao.TestRecordDao;
import backend.dao.UserDao;
import backend.model.Charts;
import backend.model.TestRecord;
import java.util.*;
public class TestRecordService {
private TestRecordDao testRecordDao = new TestRecordDao();
private UserDao userDao = new UserDao();
private QuestionsDao questionsDao = new QuestionsDao();
private Vector<Vector<String>> commonHandler(List<TestRecord> testRecordList){
//加工数据 把数据库查到的List转成Vector<Vector<>>
Vector<Vector<String>> testRecordData = new Vector<>();
if(testRecordList != null) {
for (TestRecord testRecordPo : testRecordList) {
Vector<String> row = new Vector<>();
row.add(String.valueOf(testRecordPo.getId()));
row.add(String.valueOf(userDao.findById(testRecordPo.getUserId()).getUsername()));
row.add(String.valueOf(questionsDao.getById(testRecordPo.getQuestionId()).getName()));
row.add(String.valueOf(testRecordPo.getScore()));
row.add(testRecordPo.getAnswer());
row.add(String.valueOf(testRecordPo.getTime()));
testRecordData.add(row);
}
}
return testRecordData;
}
//获取所有记录 用于管理员
public Vector<Vector<String>> getAll(){
//从数据库中获取所有记录
List<TestRecord> testRecordList = testRecordDao.getAll();
//把List转成表格所需的格式
return commonHandler(testRecordList);
//返回给前端
}
//获取指定用户的所有记录 用于用户和管理员
public Vector<Vector<String>> getByUserId(Integer userId){
//从数据库中获取所有记录
List<TestRecord> testRecordList = testRecordDao.getByUserId(userId);
//把List转成表格所需的格式
return commonHandler(testRecordList);
//返回给前端
}
//获取指定题目的所有记录 用于管理员和 用户
public Vector<Vector<String>> getByQuestionId(Integer questionId){
//从数据库中获取所有记录
List<TestRecord> testRecordList = testRecordDao.getByQuestionId(questionId);
//把List转成表格所需的格式
return commonHandler(testRecordList);
//返回给前端
}
//获取指定用户指定题目的所有记录 用于用户和管理员
public Vector<Vector<String>> getByUserIdAndQuestionId(Integer userId, Integer questionId){
//从数据库中获取所有记录
List<TestRecord> testRecordList = testRecordDao.getByUserIdAndQuestionId(userId, questionId);
//把List转成表格所需的格式
return commonHandler(testRecordList);
//返回给前端
}
public boolean insert(TestRecord testRecord){
//插入新的记录的同时,更新排行榜
ChartsService chartsService = new ChartsService();
Charts charts = new Charts();
charts.setUserid(testRecord.getUserId());
charts.setScore(testRecord.getScore());
chartsService.updateCharts(charts);
return testRecordDao.insert(testRecord);
}
public boolean delete(Integer id){
return testRecordDao.delete(id);
}
}

View File

@@ -1,43 +0,0 @@
package backend.service.impl;
import backend.dao.impl.UserDao;
import backend.model.enums.LoginStatus;
import backend.model.User;
import backend.utils.impl.*;
public class AuthService {
private UserDao userDao = new UserDao();
public LoginStatus login(User user) {
User dbUser = userDao.findByUsername(user.getUsername());
if(dbUser==null)
return LoginStatus.USER_NOT_FOUND;
if(dbUser.getUsername().equals(user.getUsername())&&dbUser.getPassword().equals(user.getPassword()))
return LoginStatus.SUCCESS;
else if (!dbUser.getUsername().equals(user.getUsername())) {
return LoginStatus.USER_NOT_FOUND;
}
return LoginStatus.PASSWORD_ERROR;
}
public LoginStatus register(User user) {
User dbAccount = userDao.findByUsername(user.getUsername());
if(dbAccount!=null)
return LoginStatus.REGISTER_FAILED;
//点击注册按钮后的事件
int row = userDao.addUser(user);
if(row>0)
return LoginStatus.REGISTER_SUCCESS;
else
return LoginStatus.REGISTER_FAILED;
}
public boolean hasPermission(int userId, String requiredRole) {
UserDao userDao = new UserDao();
User user = userDao.findById(userId);
if (user != null) {
return user.getRole().equals(requiredRole);
}
return false;
}
}

View File

@@ -1,49 +0,0 @@
package backend.service.interfaces;
import backend.model.DataItem;
import backend.model.QueryRecord;
import backend.model.User;
import java.util.*;
/**
* 数据查询服务接口
* 提供数据项的增删改查功能
*/
public interface DataQueryService {
/**
* 查询所有数据项
* @return 包含所有数据项的列表
*/
List<DataItem> queryAll();
/**
* 根据关键字搜索数据项
* @param keyword 搜索关键字
* @return 匹配关键字的数据项列表
*/
List<DataItem> search(String keyword);
/**
* 添加数据项
* @param item 要添加的数据项对象
* @param userId 执行操作的用户ID
* @return 添加成功返回true失败返回false
*/
boolean addDataItem(DataItem item, int userId);
/**
* 更新数据项
* @param item 要更新的数据项对象
* @param userId 执行操作的用户ID
* @return 更新成功返回true失败返回false
*/
boolean updateDataItem(DataItem item, int userId);
/**
* 删除数据项
* @param id 要删除的数据项ID
* @param userId 执行操作的用户ID
* @return 删除成功返回true失败返回false
*/
boolean deleteDataItem(int id, int userId);
}

View File

@@ -1,33 +0,0 @@
package backend.service.interfaces;
import backend.model.User;
import java.util.*;
/**
* 用户服务接口
* 定义了用户相关的业务操作方法
*/
public interface UserService {
/**
* 根据用户ID获取用户信息
* @param id 用户ID
* @return 用户对象如果未找到则返回null
*/
User getUserInfo(int id);
/**
* 列出所有用户信息
* @param requesterId 请求者用户ID用于权限验证
* @return 用户列表
*/
List<User> listAllUsers(int requesterId);
/**
* 更新用户角色权限
* @param targetId 目标用户ID
* @param newRole 新的角色权限
* @param adminId 管理员用户ID
* @return 操作是否成功
*/
boolean updateUserRole(int targetId, String newRole, int adminId);//用户权限
}

View File

@@ -1,8 +1,8 @@
package backend.utils.impl;
package backend.utils;
import java.util.Random;
public class CaptchaUtils implements backend.utils.interfaces.CaptchaUtils{
public class CaptchaUtils{
/**
* 字符集常量包含大小写字母和数字
*/

View File

@@ -1,4 +1,4 @@
package backend.utils.impl;
package backend.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

View File

@@ -1,41 +0,0 @@
package backend.utils.interfaces;
import java.util.Random;
/**
* 验证码工具类接口
* 提供验证码的生成和验证功能
*/
public interface CaptchaUtils {
/**
* 字符集常量,包含大小写字母和数字
*/
static final String CHAR_SET="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
/**
* 验证码长度常量默认为4位
*/
static final int CAPTCHA_LENGTH=4;
/**
* 私有构造函数,防止实例化
*/
//private CaptchaUtils();
/**
* 生成随机验证码
*
* @return 生成的验证码字符串
*/
//static String generateCaptcha();
/**
* 验证用户输入的验证码是否正确
*
* @param inputCaptcha 用户输入的验证码
* @param systemCaptcha 系统生成的验证码
* @return 验证结果正确返回true错误返回false
*/
//static boolean verifyCaptcha(String inputCaptcha,String systemCaptcha);
}

View File

@@ -1,24 +0,0 @@
package backend.utils.interfaces;
/**
* 密码工具接口,提供密码加密和验证功能
*/
public interface PasswordUtil {
/**
* 对明文密码进行加密处理
*
* @param plainText 需要加密的明文密码字符串
* @return 加密后的密码字符串
*/
//static String encrypt(String plainText);
/**
* 验证明文密码与已加密密码是否匹配
*
* @param plainText 明文密码字符串
* @param hashed 已加密的密码字符串
* @return 如果匹配返回true否则返回false
*/
//static boolean verify(String plainText, String hashed);
}

View File

@@ -1,21 +0,0 @@
package backend.utils.interfaces;
/**
* 角色工具类接口,提供角色判断功能
*/
public interface RoleUtil {
/**
* 判断给定的角色是否为管理员角色
* @param role 待判断的角色字符串
* @return 如果是管理员角色返回true否则返回false
*/
//static boolean isAdmin(String role);
/**
* 判断给定的角色是否为普通用户角色
* @param role 待判断的角色字符串
* @return 如果是普通用户角色返回true否则返回false
*/
//static boolean isUser(String role);
}

View File

@@ -1,7 +1,7 @@
package view;
import backend.model.Questions;
import backend.service.impl.QuestionsService;
import backend.service.QuestionsService;
import javax.swing.*;
import java.awt.*;
@@ -17,6 +17,12 @@ public class EditQuestionDialog extends JDialog{
private Questions question;
private QuestionsService questionsService = new QuestionsService();
// 颜色常量定义
private static final Color PRIMARY_COLOR = new Color(70, 130, 180); // 钢蓝色
private static final Color BACKGROUND_COLOR = new Color(248, 249, 250); // 浅灰色背景
private static final Color BORDER_COLOR = new Color(220, 220, 220); // 边框颜色
private static final Color HIGHLIGHT_COLOR = new Color(255, 255, 204); // 高亮背景
public EditQuestionDialog(int type, Questions question) {
this.type = type;
this.question = question;
@@ -58,16 +64,30 @@ public class EditQuestionDialog extends JDialog{
dispose();
});
}
private void initView(){
setSize(400,300);
setSize(400, 350);
setLocationRelativeTo(null);//居中
add(initPanel());
setLayout(new BorderLayout());
// 创建顶部标题面板
JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
titlePanel.setBackground(PRIMARY_COLOR);
JLabel titleLabel = new JLabel(type == 0 ? "添加题目" : "编辑题目");
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
titleLabel.setForeground(Color.WHITE);
titlePanel.add(titleLabel);
add(titlePanel, BorderLayout.NORTH);
// 添加主内容面板
add(initPanel(), BorderLayout.CENTER);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setModal(true);//设置模态
if(type==0)
setTitle("添加");
setTitle("添加题");
else{
setTitle("修改问题");
setTitle("编辑题目");
nameTextField.setText(question.getName());
descriptionTextField.setText(question.getDescription());
answerTextField.setText(question.getAnswer());
@@ -79,31 +99,102 @@ public class EditQuestionDialog extends JDialog{
//显示界面
setVisible(true);
}
private JPanel initPanel(){
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(5,2));
//第一行 单词
mainPanel.add(new JLabel("问题"));
JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.setBackground(BACKGROUND_COLOR);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
// 第一行 - 问题
gbc.gridx = 0; gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
mainPanel.add(new JLabel("问题:"), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
nameTextField = new JTextField();
mainPanel.add(nameTextField);
//第二行 定义
mainPanel.add(new JLabel("描述"));
nameTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
nameTextField.setPreferredSize(new Dimension(200, 25));
mainPanel.add(nameTextField, gbc);
// 第二行 - 描述
gbc.gridx = 0; gbc.gridy = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
mainPanel.add(new JLabel("描述:"), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
descriptionTextField = new JTextField();
mainPanel.add(descriptionTextField);
//第三行 例句
mainPanel.add(new JLabel("答案"));
descriptionTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
descriptionTextField.setPreferredSize(new Dimension(200, 25));
mainPanel.add(descriptionTextField, gbc);
// 第三行 - 答案
gbc.gridx = 0; gbc.gridy = 2;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
mainPanel.add(new JLabel("答案:"), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
answerTextField = new JTextField();
mainPanel.add(answerTextField);
//第四行 频率
mainPanel.add(new JLabel("频率"));
answerTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
answerTextField.setPreferredSize(new Dimension(200, 25));
mainPanel.add(answerTextField, gbc);
// 第四行 - 频率
gbc.gridx = 0; gbc.gridy = 3;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
mainPanel.add(new JLabel("频率:"), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
frequencyCombobox = new JComboBox<>(new String[]{"未指定","低频","中频","高频"});
mainPanel.add(frequencyCombobox);
//第五行 按钮
frequencyCombobox.setFont(new Font("微软雅黑", Font.PLAIN, 12));
frequencyCombobox.setPreferredSize(new Dimension(200, 25));
mainPanel.add(frequencyCombobox, gbc);
// 第五行 - 按钮
gbc.gridx = 0; gbc.gridy = 4;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.CENTER;
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 0));
buttonPanel.setBackground(BACKGROUND_COLOR);
saveButton = new JButton("保存");
cancelButton = new JButton("取消");
mainPanel.add(saveButton);
mainPanel.add(cancelButton);
// 设置按钮样式
setButtonStyle(saveButton);
setButtonStyle(cancelButton);
buttonPanel.add(saveButton);
buttonPanel.add(cancelButton);
mainPanel.add(buttonPanel, gbc);
// 添加边距
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
return mainPanel;
}
// 设置按钮样式
private void setButtonStyle(JButton button) {
button.setFont(new Font("微软雅黑", Font.BOLD, 14));
button.setPreferredSize(new Dimension(80, 30));
button.setBackground(PRIMARY_COLOR);
button.setForeground(Color.WHITE);
button.setFocusPainted(false);
button.setBorder(BorderFactory.createRaisedBevelBorder());
}
}

View File

@@ -0,0 +1,192 @@
package view;
import javax.swing.*;
import backend.model.User;
import backend.service.AuthService;
import java.awt.*;
public class EditUserDialog extends JDialog {
private JTextField nameTextField;
private JTextField emailTextField;
private JComboBox roleCombobox;
private JButton saveButton;
private JButton cancelButton;
private int type;
private User user;
private AuthService userService = new AuthService();
// 颜色常量定义
private static final Color PRIMARY_COLOR = new Color(70, 130, 180); // 钢蓝色
private static final Color BACKGROUND_COLOR = new Color(248, 249, 250); // 浅灰色背景
private static final Color BORDER_COLOR = new Color(220, 220, 220); // 边框颜色
private static final Color HIGHLIGHT_COLOR = new Color(255, 255, 204); // 高亮背景
public EditUserDialog(int type, User user) {
this.type = type;
this.user = user;
initView();
}
public void initListener(){
saveButton.addActionListener(e->{
String name = nameTextField.getText().trim();
String email = emailTextField.getText().trim();
if(name.equals("")|| email.equals("")) {
JOptionPane.showMessageDialog(this, "请填写完整!");
return;
}
User userPo = new User();
userPo.setUsername(name);
userPo.setEmail(email);
Integer index= roleCombobox.getSelectedIndex();
userPo.setRole(index==0 ? "user":"admin");
String message;
boolean res;
if(type==0) {
userPo.setPassword("123456");
userPo.setCreatedAt();
res = userService.addUser(userPo);
message = "添加";
}
else{
userPo.setCreatedAt(user.getCreatedAt());
userPo.setPassword(user.getPassword());
userPo.setId(user.getId());
res = userService.updateUser(userPo);
message = "修改";
}
if(res)
dispose();
else
JOptionPane.showMessageDialog(this, message+"失败");
});
cancelButton.addActionListener(e->{
dispose();
});
}
private void initView(){
setSize(400, 300);
setLocationRelativeTo(null);//居中
setLayout(new BorderLayout());
// 创建顶部标题面板
JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
titlePanel.setBackground(PRIMARY_COLOR);
JLabel titleLabel = new JLabel(type == 0 ? "添加用户" : "编辑用户");
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
titleLabel.setForeground(Color.WHITE);
titlePanel.add(titleLabel);
add(titlePanel, BorderLayout.NORTH);
// 添加主内容面板
add(initPanel(), BorderLayout.CENTER);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setModal(true);//设置模态
if(type==0)
setTitle("添加用户");
else{
setTitle("编辑用户");
nameTextField.setText(user.getUsername());
emailTextField.setText(user.getEmail());
roleCombobox.setSelectedIndex(user.getRole().equals("admin")? 1:0);
}
//细节:要先初始化监听器,再初始化界面
//初始化监听器
initListener();
//显示界面
setVisible(true);
}
private JPanel initPanel(){
JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.setBackground(BACKGROUND_COLOR);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
// 第一行 - 用户名
gbc.gridx = 0; gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
mainPanel.add(new JLabel("用户名:"), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
nameTextField = new JTextField();
nameTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
nameTextField.setPreferredSize(new Dimension(200, 25));
mainPanel.add(nameTextField, gbc);
// 第二行 - 邮箱
gbc.gridx = 0; gbc.gridy = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
mainPanel.add(new JLabel("邮箱:"), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
emailTextField = new JTextField();
emailTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
emailTextField.setPreferredSize(new Dimension(200, 25));
mainPanel.add(emailTextField, gbc);
// 第三行 - 权限
gbc.gridx = 0; gbc.gridy = 2;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
mainPanel.add(new JLabel("权限:"), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
roleCombobox = new JComboBox<>(new String[]{"user","admin"});
roleCombobox.setFont(new Font("微软雅黑", Font.PLAIN, 12));
roleCombobox.setPreferredSize(new Dimension(200, 25));
mainPanel.add(roleCombobox, gbc);
// 第四行 - 按钮
gbc.gridx = 0; gbc.gridy = 3;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.CENTER;
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 0));
buttonPanel.setBackground(BACKGROUND_COLOR);
saveButton = new JButton("保存");
cancelButton = new JButton("取消");
// 设置按钮样式
setButtonStyle(saveButton);
setButtonStyle(cancelButton);
buttonPanel.add(saveButton);
buttonPanel.add(cancelButton);
mainPanel.add(buttonPanel, gbc);
// 添加边距
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
return mainPanel;
}
// 设置按钮样式
private void setButtonStyle(JButton button) {
button.setFont(new Font("微软雅黑", Font.BOLD, 14));
button.setPreferredSize(new Dimension(80, 30));
button.setBackground(PRIMARY_COLOR);
button.setForeground(Color.WHITE);
button.setFocusPainted(false);
button.setBorder(BorderFactory.createRaisedBevelBorder());
}
// public static void main(String[] args) {
// new EditUserDialog(0,null);
// }
}

View File

@@ -1,11 +1,639 @@
package view;
import backend.dao.QuestionsDao;
import backend.dao.UserDao;
import backend.model.Charts;
import backend.model.Questions;
import backend.model.TestRecord;
import backend.model.enums.ScoreKey;
import backend.service.ChartsService;
import backend.service.QuestionsService;
import backend.service.TestRecordService;
import javax.swing.*;
public class ExamPanel extends JPanel{
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.sql.Date;
import java.util.Vector;
public class ExamPanel extends JPanel {
private QuestionsService questionsService = new QuestionsService();
private Questions currentQuestion;
private JButton startButton;
private JButton submitButton;
private JButton nextButton;
private JButton exitButton;
private JLabel questionLabel;
private JLabel descriptionLabel;
private JLabel progressLabel;
private JTextField answerTextField;
private JMenuBar menuBar;
private String role = MainFrame.role;
private int userId = MainFrame.userId;
// 颜色常量定义
private static final Color PRIMARY_COLOR = new Color(70, 130, 180); // 钢蓝色
private static final Color BACKGROUND_COLOR = new Color(248, 249, 250); // 浅灰色背景
private static final Color BORDER_COLOR = new Color(220, 220, 220); // 边框颜色
private static final Color HIGHLIGHT_COLOR = new Color(255, 255, 204); // 高亮背景
public ExamPanel() {
initializeComponents();
initView();
initListener();
}
private void initView(){
add(new JLabel("考试管理"));
// 初始化所有UI组件
private void initializeComponents() {
// 题目标题标签
questionLabel = new JLabel("点击开始测试获取题目");
questionLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
questionLabel.setForeground(new Color(50, 50, 50));
questionLabel.setHorizontalAlignment(JLabel.CENTER);
questionLabel.setVerticalAlignment(JLabel.TOP);
// 题目描述标签
descriptionLabel = new JLabel("描述将在这里显示");
descriptionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
descriptionLabel.setForeground(new Color(100, 100, 100));
descriptionLabel.setHorizontalAlignment(JLabel.CENTER);
descriptionLabel.setVerticalAlignment(JLabel.TOP);
// 进度标签
progressLabel = new JLabel("题目进度: 0/0");
progressLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
progressLabel.setForeground(new Color(120, 120, 120));
progressLabel.setHorizontalAlignment(JLabel.RIGHT);
// 答案输入框
answerTextField = new JTextField(20);
answerTextField.setFont(new Font("微软雅黑", Font.PLAIN, 14));
answerTextField.setHorizontalAlignment(JLabel.CENTER);
answerTextField.setPreferredSize(new Dimension(250, 35));
// 初始化按钮
startButton = new JButton("开始测试");
submitButton = new JButton("提交");
nextButton = new JButton("下一题");
exitButton = new JButton("退出");
// 设置按钮样式
setButtonStyle(startButton);
setButtonStyle(submitButton);
setButtonStyle(nextButton);
setButtonStyle(exitButton);
// 隐藏非初始按钮
submitButton.setVisible(false);
nextButton.setVisible(false);
exitButton.setVisible(false);
}
// 设置按钮样式
private void setButtonStyle(JButton button) {
button.setFont(new Font("微软雅黑", Font.BOLD, 14));
button.setPreferredSize(new Dimension(100, 35));
button.setBackground(PRIMARY_COLOR);
button.setForeground(Color.WHITE);
button.setFocusPainted(false);
button.setBorder(BorderFactory.createRaisedBevelBorder());
}
private void initView() {
setLayout(new BorderLayout());
setBackground(BACKGROUND_COLOR);
// 创建顶部工具栏
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.setBackground(PRIMARY_COLOR);
topPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
JLabel titleLabel = new JLabel("测试管理");
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
titleLabel.setForeground(Color.WHITE);
topPanel.add(titleLabel, BorderLayout.WEST);
topPanel.add(progressLabel, BorderLayout.EAST);
topPanel.add(initMenuBar(), BorderLayout.CENTER);
add(topPanel, BorderLayout.NORTH);
// 创建中央内容面板
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
centerPanel.setBackground(BACKGROUND_COLOR);
centerPanel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
// 添加初始显示内容
centerPanel.add(Box.createVerticalGlue());
// 题目展示区域
JPanel questionPanel = new JPanel(new BorderLayout());
questionPanel.setBackground(Color.WHITE);
questionPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(BORDER_COLOR, 1),
BorderFactory.createEmptyBorder(20, 20, 20, 20)
));
questionPanel.setMaximumSize(new Dimension(600, 300));
questionPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
questionPanel.add(questionLabel, BorderLayout.CENTER);
questionPanel.add(descriptionLabel, BorderLayout.SOUTH);
centerPanel.add(questionPanel);
centerPanel.add(Box.createVerticalStrut(20));
// 答案输入区域
JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5));
inputPanel.setBackground(BACKGROUND_COLOR);
inputPanel.add(new JLabel("请输入答案: "));
inputPanel.add(answerTextField);
centerPanel.add(inputPanel);
centerPanel.add(Box.createVerticalStrut(15));
// 按钮区域
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 5));
buttonPanel.setBackground(BACKGROUND_COLOR);
buttonPanel.add(startButton);
buttonPanel.add(submitButton);
buttonPanel.add(nextButton);
buttonPanel.add(exitButton);
centerPanel.add(buttonPanel);
centerPanel.add(Box.createVerticalGlue());
add(centerPanel, BorderLayout.CENTER);
// 更新按钮可见性
updateButtonVisibility();
}
private void updateButtonVisibility() {
startButton.setVisible(true);
submitButton.setVisible(false);
nextButton.setVisible(false);
exitButton.setVisible(false);
}
private void showQuestion() {
// 更新按钮可见性
startButton.setVisible(false);
submitButton.setVisible(true);
nextButton.setVisible(false);
exitButton.setVisible(false);
// 更新进度显示
progressLabel.setText("题目进度: 1/1");
// 重新验证和重绘界面
revalidate();
repaint();
}
private void showNextQuestionOption() {
// 更新按钮可见性
startButton.setVisible(false);
submitButton.setVisible(false);
nextButton.setVisible(true);
exitButton.setVisible(true);
// 重新验证和重绘界面
revalidate();
repaint();
}
private void initListener() {
startButton.addActionListener(e -> {
// 获取随机题目并显示
currentQuestion = questionsService.getRandomQuestion();
if (currentQuestion != null) {
//在排行榜中创建角色(若没有)
ChartsService chartsService = new ChartsService();
Charts charts = new Charts();
charts.setUserid(userId);
chartsService.insertCharts(charts);
updateQuestionDisplay();
showQuestion();
} else {
JOptionPane.showMessageDialog(this,
"没有可用的题目", "错误", JOptionPane.ERROR_MESSAGE);
}
});
submitButton.addActionListener(e -> handleAnswerSubmission());
// 为 nextButton 和 exitButton 添加监听器
if (nextButton != null) {
nextButton.addActionListener(e -> {
currentQuestion = questionsService.getRandomQuestion();
if (currentQuestion != null) {
updateQuestionDisplay();
showQuestion();
} else {
JOptionPane.showMessageDialog(this,
"没有更多题目", "提示", JOptionPane.INFORMATION_MESSAGE);
}
});
}
if (exitButton != null) {
exitButton.addActionListener(e -> {
int choice = JOptionPane.showConfirmDialog(
this,
"确定要退出测试吗?",
"确认退出",
JOptionPane.YES_NO_OPTION
);
if (choice == JOptionPane.YES_OPTION) {
resetToInitialState();
}
});
}
// 为菜单项添加监听器
JMenu testMenu = (JMenu) menuBar.getMenu(0);
JMenuItem testContentItem = testMenu.getItem(0);
testContentItem.addActionListener(e -> {
resetToInitialState();
});
JMenu recordMenu = (JMenu) menuBar.getMenu(1);
JMenuItem recordItem = recordMenu.getItem(0);
recordItem.addActionListener(e -> {
initRecordView();
});
JMenu chartMenu = (JMenu) menuBar.getMenu(2);
JMenuItem chartItem = chartMenu.getItem(0);
chartItem.addActionListener(e -> {
// 这里可以添加排行榜页面的切换逻辑
initRankView();
});
}
private void updateQuestionDisplay() {
if (currentQuestion != null) {
questionLabel.setText(currentQuestion.getName());
descriptionLabel.setText(currentQuestion.getDescription());
answerTextField.setText("");
}
}
private void handleAnswerSubmission() {
int user=userId, questionId= currentQuestion.getId(), score=0;
if (currentQuestion == null) {
JOptionPane.showMessageDialog(this,
"请先开始测试", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
String userAnswer = answerTextField.getText().trim();
if (userAnswer.isEmpty()) {
JOptionPane.showMessageDialog(this,
"请输入答案", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
if (userAnswer.equalsIgnoreCase(currentQuestion.getAnswer())) {
// 答案正确时高亮输入框
answerTextField.setBackground(HIGHLIGHT_COLOR);
JOptionPane.showMessageDialog(this,
"答案正确!", "正确", JOptionPane.INFORMATION_MESSAGE);
answerTextField.setBackground(Color.WHITE);
score= ScoreKey.getScoreByKey(currentQuestion.getFrequency());
showNextQuestionOption();
} else {
// 答案错误时改变输入框颜色
answerTextField.setBackground(new Color(255, 220, 220)); // 淡红色
int choice = JOptionPane.showConfirmDialog(
this,
"答案错误,正确答案是:" + currentQuestion.getAnswer() + "\n是否重新尝试",
"错误",
JOptionPane.YES_NO_OPTION
);
if (choice == JOptionPane.NO_OPTION) {
answerTextField.setBackground(Color.WHITE);
showNextQuestionOption();
} else {
// 清空输入框,允许重新尝试
answerTextField.setText("");
answerTextField.setBackground(Color.WHITE);
}
}
// 保存测试记录
TestRecord testRecord = new TestRecord();
testRecord.setUserId(user);
testRecord.setQuestionId(questionId);
testRecord.setScore(score);
testRecord.setAnswer(userAnswer);
testRecord.setTime(new Date(System.currentTimeMillis()));
TestRecordService testRecordService = new TestRecordService();
testRecordService.insert(testRecord);
}
private void resetToInitialState() {
// 重置所有组件状态
questionLabel.setText("点击开始测试获取题目");
descriptionLabel.setText("描述将在这里显示");
answerTextField.setText("");
answerTextField.setBackground(Color.WHITE);
// 重置按钮状态
updateButtonVisibility();
// 重置进度
progressLabel.setText("题目进度: 0/0");
revalidate();
repaint();
}
private JMenuBar initMenuBar() {
menuBar = new JMenuBar();
menuBar.setBackground(PRIMARY_COLOR);
JMenu testMenu = new JMenu("测试内容");
testMenu.setForeground(Color.WHITE);
testMenu.add(new JMenuItem("开始测试"));
menuBar.add(testMenu);
JMenu recordMenu = new JMenu("测试记录");
recordMenu.setForeground(Color.WHITE);
if(role.equals("user"))
recordMenu.add(new JMenuItem("我的记录"));
else
recordMenu.add(new JMenuItem("查看所有记录"));
menuBar.add(recordMenu);
JMenu chartMenu = new JMenu("排行榜");
chartMenu.setForeground(Color.WHITE);
chartMenu.add(new JMenuItem("查看排行榜"));
menuBar.add(chartMenu);
return menuBar;
}
private void initRecordView() {
// 清空当前面板
removeAll();
setLayout(new BorderLayout());
// 创建顶部查询面板
JPanel queryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
queryPanel.setBackground(PRIMARY_COLOR);
queryPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
// 添加查询输入框和按钮
JLabel userLabel = new JLabel("用户:");
userLabel.setForeground(Color.WHITE);
JTextField userIdField = new JTextField(8);
userIdField.setPreferredSize(new Dimension(80, 25));
JLabel questionLabel = new JLabel("题目:");
questionLabel.setForeground(Color.WHITE);
JTextField questionIdField = new JTextField(8);
questionIdField.setPreferredSize(new Dimension(80, 25));
JButton searchButton = new JButton("查询");
setButtonStyle(searchButton);
JButton resetButton = new JButton("重置");
setButtonStyle(resetButton);
queryPanel.add(userLabel);
queryPanel.add(userIdField);
queryPanel.add(questionLabel);
queryPanel.add(questionIdField);
queryPanel.add(searchButton);
queryPanel.add(resetButton);
// 创建表格展示面板
JPanel tablePanel = new JPanel(new BorderLayout());
tablePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 初始化表格
String[] columnNames = {"记录ID", "用户名", "题目", "得分", "答案", "时间"};
DefaultTableModel tableModel = new DefaultTableModel(columnNames, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false; // 表格不可编辑
}
};
JTable recordTable = new JTable(tableModel);
recordTable.setFont(new Font("微软雅黑", Font.PLAIN, 12));
recordTable.getTableHeader().setFont(new Font("微软雅黑", Font.BOLD, 13));
recordTable.getTableHeader().setBackground(PRIMARY_COLOR);
recordTable.getTableHeader().setForeground(Color.WHITE);
recordTable.setSelectionBackground(new Color(176, 224, 230));
recordTable.setRowHeight(25);
// 设置列宽
recordTable.getColumnModel().getColumn(0).setPreferredWidth(60); // 记录ID
recordTable.getColumnModel().getColumn(1).setPreferredWidth(100); // 用户名
recordTable.getColumnModel().getColumn(2).setPreferredWidth(200); // 题目
recordTable.getColumnModel().getColumn(3).setPreferredWidth(60); // 得分
recordTable.getColumnModel().getColumn(4).setPreferredWidth(150); // 答案
recordTable.getColumnModel().getColumn(5).setPreferredWidth(120); // 时间
JScrollPane scrollPane = new JScrollPane(recordTable);
scrollPane.setPreferredSize(new Dimension(700, 400));
tablePanel.add(scrollPane, BorderLayout.CENTER);
// 添加到主面板
add(queryPanel, BorderLayout.NORTH);
add(tablePanel, BorderLayout.CENTER);
// 查询按钮事件处理
searchButton.addActionListener(e -> {
UserDao userDao = new UserDao();
QuestionsDao questionsDao = new QuestionsDao();
String userIdText = userIdField.getText().trim();
String questionIdText = questionIdField.getText().trim();
TestRecordService testRecordService = new TestRecordService();
Vector<Vector<String>> records;
try {
if (!userIdText.isEmpty() && !questionIdText.isEmpty()) {
userIdText = String.valueOf(userDao.findByUsername(userIdField.getText().trim()).getId());
questionIdText = String.valueOf(questionsDao.getByName(questionIdField.getText().trim()).getId());
// 同时查询用户ID和题目ID
Integer userId = Integer.parseInt(userIdText);
Integer questionId = Integer.parseInt(questionIdText);
records = testRecordService.getByUserIdAndQuestionId(userId, questionId);
} else if (!userIdText.isEmpty()) {
// 只查询用户ID
userIdText = String.valueOf(userDao.findByUsername(userIdField.getText().trim()).getId());
Integer userId = Integer.parseInt(userIdText);
records = testRecordService.getByUserId(userId);
} else if (!questionIdText.isEmpty()) {
// 只查询题目ID
questionIdText = String.valueOf(questionsDao.getByName(questionIdField.getText().trim()).getId());
Integer questionId = Integer.parseInt(questionIdText);
records = testRecordService.getByQuestionId(questionId);
} else {
// 查询所有记录(根据角色权限)
if (role.equals("user")) {
records = testRecordService.getByUserId(this.userId);
} else {
records = testRecordService.getAll();
}
}
// 清空表格
tableModel.setRowCount(0);
// 添加数据到表格
for (Vector<String> record : records) {
tableModel.addRow(record);
}
// 如果没有找到记录,显示提示
if (records.isEmpty()) {
JOptionPane.showMessageDialog(this, "没有找到匹配的记录", "提示", JOptionPane.INFORMATION_MESSAGE);
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(this, "请输入有效的数字ID", "错误", JOptionPane.ERROR_MESSAGE);
}
});
// 重置按钮事件处理
resetButton.addActionListener(e -> {
userIdField.setText("");
questionIdField.setText("");
// 根据角色加载默认数据
TestRecordService testRecordService = new TestRecordService();
Vector<Vector<String>> records;
if (role.equals("user")) {
records = testRecordService.getByUserId(this.userId);
} else {
records = testRecordService.getAll();
}
// 清空表格
tableModel.setRowCount(0);
// 添加数据到表格
for (Vector<String> record : records) {
tableModel.addRow(record);
}
});
// 初始加载数据
SwingUtilities.invokeLater(() -> {
TestRecordService testRecordService = new TestRecordService();
Vector<Vector<String>> records;
if (role.equals("user")) {
records = testRecordService.getByUserId(this.userId);
} else {
records = testRecordService.getAll();
}
// 添加数据到表格
for (Vector<String> record : records) {
tableModel.addRow(record);
}
});
revalidate();
repaint();
}
private void initRankView() {
// 清空当前面板
removeAll();
setLayout(new BorderLayout());
// 创建顶部控制面板
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
controlPanel.setBackground(PRIMARY_COLOR);
controlPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
JButton sortByScoreUpButton = new JButton("按分数升序");
JButton sortByScoreDownButton = new JButton("按分数降序");
setButtonStyle(sortByScoreUpButton);
setButtonStyle(sortByScoreDownButton);
controlPanel.add(sortByScoreUpButton);
controlPanel.add(sortByScoreDownButton);
// 创建表格展示面板
JPanel tablePanel = new JPanel(new BorderLayout());
tablePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 初始化表格
String[] columnNames = {"排名", "用户名", "答题次数", "总得分"};
DefaultTableModel tableModel = new DefaultTableModel(columnNames, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false; // 表格不可编辑
}
};
JTable rankTable = new JTable(tableModel);
rankTable.setFont(new Font("微软雅黑", Font.PLAIN, 12));
rankTable.getTableHeader().setFont(new Font("微软雅黑", Font.BOLD, 13));
rankTable.getTableHeader().setBackground(PRIMARY_COLOR);
rankTable.getTableHeader().setForeground(Color.WHITE);
rankTable.setSelectionBackground(new Color(176, 224, 230));
rankTable.setRowHeight(25);
// 设置列宽
rankTable.getColumnModel().getColumn(0).setPreferredWidth(60); // 排名
rankTable.getColumnModel().getColumn(1).setPreferredWidth(120); // 用户名
rankTable.getColumnModel().getColumn(2).setPreferredWidth(100); // 答题次数
rankTable.getColumnModel().getColumn(3).setPreferredWidth(100); // 总得分
JScrollPane scrollPane = new JScrollPane(rankTable);
scrollPane.setPreferredSize(new Dimension(600, 400));
tablePanel.add(scrollPane, BorderLayout.CENTER);
// 添加到主面板
add(controlPanel, BorderLayout.NORTH);
add(tablePanel, BorderLayout.CENTER);
// 加载默认数据(升序)
loadRankData(tableModel, true);
// 按分数升序按钮事件
sortByScoreUpButton.addActionListener(e -> {
loadRankData(tableModel, true);
});
// 按分数降序按钮事件
sortByScoreDownButton.addActionListener(e -> {
loadRankData(tableModel, false);
});
revalidate();
repaint();
}
private void loadRankData(DefaultTableModel tableModel, boolean isAscending) {
ChartsService chartsService = new ChartsService();
Vector<Vector<String>> rankData;
if (isAscending) {
rankData = chartsService.sortByScoreUp();
} else {
rankData = chartsService.sortByScoreDown();
}
// 清空表格
tableModel.setRowCount(0);
// 添加数据到表格
for (Vector<String> rankItem : rankData) {
tableModel.addRow(rankItem);
}
}
}

View File

@@ -1,8 +1,9 @@
package view;
import backend.dao.UserDao;
import backend.model.enums.LoginStatus;
import backend.model.User;
import backend.service.impl.AuthService;
import backend.utils.impl.CaptchaUtils;
import backend.service.AuthService;
import backend.utils.CaptchaUtils;
import javax.swing.*;
import java.awt.*;
@@ -18,11 +19,15 @@ public class LoginFrame extends JFrame{
private JButton loginButton;//登录按钮
private JButton registerButton;//注册按钮
private AuthService authService = new AuthService();
private LoginStatus flag;
private UserDao userDao = new UserDao();
protected static String loginRole;
protected static int userId;
public LoginStatus Flag(){
return this.flag;
}
// 颜色常量定义
private static final Color PRIMARY_COLOR = new Color(70, 130, 180); // 钢蓝色
private static final Color BACKGROUND_COLOR = new Color(248, 249, 250); // 浅灰色背景
private static final Color BORDER_COLOR = new Color(220, 220, 220); // 边框颜色
private static final Color HIGHLIGHT_COLOR = new Color(255, 255, 204); // 高亮背景
public LoginFrame() {
//初始化界面
@@ -33,19 +38,22 @@ public class LoginFrame extends JFrame{
passwordField.setText("123456");
captchaTextField.setText(captchaLabel.getText());
}
private void initView(){
//1.设置标题
setTitle("登录");
setTitle("中医药知识测试系统 - 登录");
//2.设置点击关闭时的动作
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//3.中间层容器
//3.设置窗口背景色
getContentPane().setBackground(BACKGROUND_COLOR);
//4.中间层容器
add(initPanel());
//4.不允许窗口改变大小
//5.不允许窗口改变大小
setResizable(false);
//5.自动调整窗口大小 居中显示
pack();//自动调整窗口大小
setLocationRelativeTo(null);//剧中
//6.显示窗口
//6.设置窗口大小 居中显示
setSize(400, 350);
setLocationRelativeTo(null);
//7.显示窗口
setVisible(true);
}
@@ -76,6 +84,10 @@ public class LoginFrame extends JFrame{
account.setPassword(password);
LoginStatus loginStatus = authService.login(account);
if(loginStatus == LoginStatus.SUCCESS) {
//记录登陆角色的权限
account=userDao.findByUsername(username);
loginRole = account.getRole();
userId = account.getId();
//进入主界面
new MainFrame();
this.dispose();
@@ -102,23 +114,134 @@ public class LoginFrame extends JFrame{
private JPanel initPanel(){
mainPanel = new JPanel();
GridLayout gridLayout = new GridLayout(6,1,10,10);
mainPanel.setLayout(gridLayout);
//第1层 空白面板 占用
mainPanel.add(new JPanel());
//第2层 账号面板
mainPanel.add(initAcountPanel());
//第3层 密码面板
mainPanel.add(initPasswordPanel());
//第4层 验证码面板
mainPanel.add(initCaptchaPanel());
//第5层 按钮面板
mainPanel.add(initButtonPanel());
//第6层 空白面板 占用
mainPanel = new JPanel(new BorderLayout());
mainPanel.setBackground(BACKGROUND_COLOR);
// 创建顶部标题面板
JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
titlePanel.setBackground(PRIMARY_COLOR);
JLabel titleLabel = new JLabel("中医药知识测试系统");
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
titleLabel.setForeground(Color.WHITE);
titlePanel.add(titleLabel);
mainPanel.add(titlePanel, BorderLayout.NORTH);
// 创建中央登录表单面板
JPanel formPanel = new JPanel(new GridBagLayout());
formPanel.setBackground(BACKGROUND_COLOR);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
// 第1行 - 标题
gbc.gridx = 0; gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.CENTER;
JLabel formTitleLabel = new JLabel("用户登录");
formTitleLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
formTitleLabel.setForeground(PRIMARY_COLOR);
formPanel.add(formTitleLabel, gbc);
// 第2行 - 用户名
gbc.gridx = 0; gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.anchor = GridBagConstraints.WEST;
JLabel usernameLabel = new JLabel("用户名:");
usernameLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
formPanel.add(usernameLabel, gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
usernameTextField = new JTextField(15);
usernameTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
usernameTextField.setPreferredSize(new Dimension(200, 25));
formPanel.add(usernameTextField, gbc);
// 第3行 - 密码
gbc.gridx = 0; gbc.gridy = 2;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.WEST;
JLabel passwordLabel = new JLabel("密 码:");
passwordLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
formPanel.add(passwordLabel, gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
passwordField = new JPasswordField(15);
passwordField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
passwordField.setPreferredSize(new Dimension(200, 25));
formPanel.add(passwordField, gbc);
// 第4行 - 验证码
gbc.gridx = 0; gbc.gridy = 3;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.WEST;
JLabel captchaLabel = new JLabel("验证码:");
captchaLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
formPanel.add(captchaLabel, gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
JPanel captchaPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
captchaPanel.setBackground(BACKGROUND_COLOR);
captchaTextField = new JTextField(8);
captchaTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
captchaTextField.setPreferredSize(new Dimension(80, 25));
captchaPanel.add(captchaTextField);
this.captchaLabel = new JLabel(CaptchaUtils.generateCaptcha());
this.captchaLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
this.captchaLabel.setBackground(Color.WHITE);
this.captchaLabel.setOpaque(true);
this.captchaLabel.setBorder(BorderFactory.createLineBorder(BORDER_COLOR));
this.captchaLabel.setPreferredSize(new Dimension(80, 25));
this.captchaLabel.setHorizontalAlignment(JLabel.CENTER);
captchaPanel.add(this.captchaLabel);
formPanel.add(captchaPanel, gbc);
// 第5行 - 按钮
gbc.gridx = 0; gbc.gridy = 4;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.CENTER;
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 0));
buttonPanel.setBackground(BACKGROUND_COLOR);
loginButton = new JButton("登录");
registerButton = new JButton("注册");
// 设置按钮样式
setButtonStyle(loginButton);
setButtonStyle(registerButton);
buttonPanel.add(loginButton);
buttonPanel.add(registerButton);
formPanel.add(buttonPanel, gbc);
// 添加边距
formPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
mainPanel.add(formPanel, BorderLayout.CENTER);
return mainPanel;
}
// 设置按钮样式
private void setButtonStyle(JButton button) {
button.setFont(new Font("微软雅黑", Font.BOLD, 14));
button.setPreferredSize(new Dimension(80, 30));
button.setBackground(PRIMARY_COLOR);
button.setForeground(Color.WHITE);
button.setFocusPainted(false);
button.setBorder(BorderFactory.createRaisedBevelBorder());
}
private JPanel initAcountPanel(){
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1,4,10,0));
@@ -199,7 +322,3 @@ public class LoginFrame extends JFrame{
});
}
}

View File

@@ -3,6 +3,7 @@ package view;
import backend.model.Questions;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@@ -11,40 +12,60 @@ public class MainFrame extends JFrame{
private JMenuBar menuBar;
private JMenu questionsMenu;
private JMenu examMenu;
private JMenu userMenu;
protected static String role = LoginFrame.loginRole;
protected static int userId = LoginFrame.userId;
// 颜色常量定义
private static final Color PRIMARY_COLOR = new Color(70, 130, 180); // 钢蓝色
private static final Color BACKGROUND_COLOR = new Color(248, 249, 250); // 浅灰色背景
private static final Color BORDER_COLOR = new Color(220, 220, 220); // 边框颜色
private static final Color HIGHLIGHT_COLOR = new Color(255, 255, 204); // 高亮背景
public MainFrame(){
initView();
initListener();
}
private void initView(){
//1.设置标题
setTitle("主界面");
setTitle("中医药知识测试系统");
//2.设置点击关闭时的动作
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//3.中间层容器
//3.设置窗口背景色
getContentPane().setBackground(BACKGROUND_COLOR);
//4.中间层容器
add(initPanel());
//4.不允许窗口改变大小
//5.不允许窗口改变大小
setResizable(false);
//5.自动调整窗口大小 居中显示
setSize(600,600);
//pack()//自动调整窗口大小
//6.设置窗口大小 居中显示
setSize(800, 600);
setLocationRelativeTo(null);
//6.注册监听器
initListener();
//7.显示窗口
setVisible(true);
}
private void initListener(){
questionsMenu.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
mainPanel.removeAll();
mainPanel.add(new QuestionsPanel());
mainPanel.revalidate();
mainPanel.repaint();
}
});
if(role.equals("admin")) {
questionsMenu.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
mainPanel.removeAll();
mainPanel.add(new QuestionsPanel());
mainPanel.revalidate();
mainPanel.repaint();
}
});
userMenu.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
mainPanel.removeAll();
mainPanel.add(new UserPanel());
mainPanel.revalidate();
mainPanel.repaint();
}
});
}
examMenu.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
@@ -55,23 +76,46 @@ public class MainFrame extends JFrame{
}
});
}
private JPanel initPanel(){
mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel,BoxLayout.Y_AXIS));
mainPanel = new JPanel(new BorderLayout());
mainPanel.setBackground(BACKGROUND_COLOR);
setJMenuBar(initMenuBar());
//默认为单词库界面
mainPanel.add(new QuestionsPanel());
mainPanel.setVisible(true);
if(MainFrame.role.equals("admin")) {
//默认为问题库界面
mainPanel.add(new QuestionsPanel(), BorderLayout.CENTER);
}
else{
//默认为考试界面
mainPanel.add(new ExamPanel(), BorderLayout.CENTER);
}
return mainPanel;
}
private JMenuBar initMenuBar(){
menuBar = new JMenuBar();
questionsMenu = new JMenu("问题库管理");
examMenu = new JMenu("考试管理");
menuBar.add(questionsMenu);
menuBar.setBackground(PRIMARY_COLOR);
if(role.equals("admin")) {
questionsMenu = new JMenu("问题库管理");
questionsMenu.setForeground(Color.WHITE);
questionsMenu.setFont(new Font("微软雅黑", Font.BOLD, 14));
menuBar.add(questionsMenu);
userMenu = new JMenu("用户管理");
userMenu.setForeground(Color.WHITE);
userMenu.setFont(new Font("微软雅黑", Font.BOLD, 14));
menuBar.add(userMenu);
}
examMenu = new JMenu("测试管理");
examMenu.setForeground(Color.WHITE);
examMenu.setFont(new Font("微软雅黑", Font.BOLD, 14));
menuBar.add(examMenu);
return menuBar;
}
public static void main(String[] args) {
new MainFrame().initView();
}

View File

@@ -7,7 +7,7 @@ import java.awt.event.MouseEvent;
import java.util.Vector;
import backend.model.Questions;
import backend.service.impl.QuestionsService;
import backend.service.QuestionsService;
import backend.model.enums.GlobalData;
public class QuestionsPanel extends JPanel{
@@ -25,6 +25,13 @@ public class QuestionsPanel extends JPanel{
private JComboBox frequencyComboBox;
private JTextField keyTextField;
private JButton queryButton;
// 颜色常量定义
private static final Color PRIMARY_COLOR = new Color(70, 130, 180); // 钢蓝色
private static final Color BACKGROUND_COLOR = new Color(248, 249, 250); // 浅灰色背景
private static final Color BORDER_COLOR = new Color(220, 220, 220); // 边框颜色
private static final Color HIGHLIGHT_COLOR = new Color(255, 255, 204); // 高亮背景
static {
columNames.add("ID");
columNames.add("题目");
@@ -32,6 +39,7 @@ public class QuestionsPanel extends JPanel{
columNames.add("答案");
columNames.add("频率");
}
public void initListener(){
queryButton.addActionListener(e->{
Integer frequency = frequencyComboBox.getSelectedIndex()==0?null:frequencyComboBox.getSelectedIndex();
@@ -44,6 +52,8 @@ public class QuestionsPanel extends JPanel{
refreshData();
});
deleteButton.addActionListener(e->{
if(MainFrame.role.equals("user"))
return;
int row = table.getSelectedRow();
if(row!=-1){
int id = Integer.valueOf(tableData.get(row).get(0));
@@ -57,9 +67,13 @@ public class QuestionsPanel extends JPanel{
});
//添加事件:打开对话框
addButton.addActionListener(e->{
if(MainFrame.role.equals("user"))
return;
new EditQuestionDialog(0,null);
});
editButton.addActionListener(e->{
if(MainFrame.role.equals("user"))
return;
int row = table.getSelectedRow();
if(row>=0)
openEditDialog(row);
@@ -69,6 +83,8 @@ public class QuestionsPanel extends JPanel{
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(MainFrame.role.equals("user"))
return;
if(e.getClickCount()==2){
int row = table.getSelectedRow();
openEditDialog(row);
@@ -94,55 +110,111 @@ public class QuestionsPanel extends JPanel{
scrollPane.getHorizontalScrollBar().setValue(0);
scrollPane.revalidate();
}
public QuestionsPanel(){
initView();
initListener();
}
private void initView(){
//设置主面板的布局为盒子布局,垂直方向
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
//1.按钮界面
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1,3,5,5));
setLayout(new BorderLayout());
setBackground(BACKGROUND_COLOR);
// 创建顶部工具栏
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.setBackground(PRIMARY_COLOR);
topPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
JLabel titleLabel = new JLabel("题目管理");
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
titleLabel.setForeground(Color.WHITE);
topPanel.add(titleLabel, BorderLayout.WEST);
add(topPanel, BorderLayout.NORTH);
// 创建中央内容面板
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
centerPanel.setBackground(BACKGROUND_COLOR);
centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 1.按钮界面
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
buttonPanel.setBackground(BACKGROUND_COLOR);
addButton = new JButton("添加");
deleteButton = new JButton("删除");
editButton = new JButton("修改");
// 设置按钮样式
setButtonStyle(addButton);
setButtonStyle(deleteButton);
setButtonStyle(editButton);
buttonPanel.add(addButton);
buttonPanel.add(deleteButton);
buttonPanel.add(editButton);
buttonPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE,50));
add(buttonPanel);
//添加垂直间隔
add(Box.createVerticalStrut(10));
//2.搜索界面
JPanel queryPanel = new JPanel();
queryPanel.setLayout(new GridLayout(1,3,5,5));
centerPanel.add(buttonPanel);
centerPanel.add(Box.createVerticalStrut(10));
// 2.搜索界面
JPanel queryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
queryPanel.setBackground(BACKGROUND_COLOR);
frequencyComboBox = new JComboBox<String>(new String[]{"全部","低频","中频","高频"});
keyTextField = new JTextField(15);
queryButton = new JButton("查询");
// 设置查询按钮样式
setButtonStyle(queryButton);
queryPanel.add(new JLabel("频率:"));
queryPanel.add(frequencyComboBox);
queryPanel.add(new JLabel("关键词:"));
queryPanel.add(keyTextField);
queryPanel.add(queryButton);
queryPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE,30));
add(queryPanel);
//添加垂直间隔
add(Box.createVerticalStrut(10));
//3.表格界面
centerPanel.add(queryPanel);
centerPanel.add(Box.createVerticalStrut(10));
// 3.表格界面
model = new DefaultTableModel(){
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
table = new JTable(model);
table.setFont(new Font("微软雅黑", Font.PLAIN, 12));
table.getTableHeader().setFont(new Font("微软雅黑", Font.BOLD, 13));
table.getTableHeader().setBackground(PRIMARY_COLOR);
table.getTableHeader().setForeground(Color.WHITE);
table.setSelectionBackground(new Color(176, 224, 230));
table.setRowHeight(25);
scrollPane = new JScrollPane(table);
add(scrollPane);
scrollPane.setPreferredSize(new Dimension(700, 400));
scrollPane.setBorder(BorderFactory.createLineBorder(BORDER_COLOR, 1));
centerPanel.add(scrollPane);
add(centerPanel, BorderLayout.CENTER);
tableData = questionsService.getAll();
//刷新数据
refreshData();
}
// 设置按钮样式
private void setButtonStyle(JButton button) {
button.setFont(new Font("微软雅黑", Font.BOLD, 14));
button.setPreferredSize(new Dimension(80, 30));
button.setBackground(PRIMARY_COLOR);
button.setForeground(Color.WHITE);
button.setFocusPainted(false);
button.setBorder(BorderFactory.createRaisedBevelBorder());
}
private void refreshData(){
model.setDataVector(tableData,columNames);
model.fireTableDataChanged();

View File

@@ -2,8 +2,8 @@ package view;
import backend.model.User;
import backend.model.enums.LoginStatus;
import backend.service.impl.AuthService;
import backend.utils.impl.CaptchaUtils;
import backend.service.AuthService;
import backend.utils.CaptchaUtils;
import javax.swing.*;
import java.awt.*;
@@ -21,6 +21,13 @@ public class RegisterFrame extends JFrame{
private JButton registerButton;//注册按钮
private JButton backButton;//返回按钮
private AuthService authService = new AuthService();
// 颜色常量定义
private static final Color PRIMARY_COLOR = new Color(70, 130, 180); // 钢蓝色
private static final Color BACKGROUND_COLOR = new Color(248, 249, 250); // 浅灰色背景
private static final Color BORDER_COLOR = new Color(220, 220, 220); // 边框颜色
private static final Color HIGHLIGHT_COLOR = new Color(255, 255, 204); // 高亮背景
public RegisterFrame() {
//初始化界面
initView();
@@ -32,19 +39,22 @@ public class RegisterFrame extends JFrame{
emailTextField.setText("123456@qq.com");
confirmPasswordField.setText(passwordField.getText());
}
private void initView(){
//1.设置标题
setTitle("注册");
setTitle("中医药知识测试系统 - 注册");
//2.设置点击关闭时的动作
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//3.中间层容器
//3.设置窗口背景色
getContentPane().setBackground(BACKGROUND_COLOR);
//4.中间层容器
add(initPanel());
//4.不允许窗口改变大小
//5.不允许窗口改变大小
setResizable(false);
//5.自动调整窗口大小 居中显示
pack();//自动调整窗口大小
setLocationRelativeTo(null);//剧中
//6.显示窗口
//6.设置窗口大小 居中显示
setSize(400, 400);
setLocationRelativeTo(null);
//7.显示窗口
setVisible(true);
}
@@ -78,7 +88,7 @@ public class RegisterFrame extends JFrame{
account.setPassword(password);
account.setEmail(emailTextField.getText());
account.setRole("user");
account.setCreatedAt(String.valueOf(System.currentTimeMillis()));
account.setCreatedAt();
LoginStatus loginStatus = authService.register(account);
if(loginStatus==LoginStatus.REGISTER_SUCCESS) {
this.dispose();
@@ -110,27 +120,168 @@ public class RegisterFrame extends JFrame{
private JPanel initPanel(){
mainPanel = new JPanel();
GridLayout gridLayout = new GridLayout(8,1,10,10);
mainPanel.setLayout(gridLayout);
//第1层 空白面板 占用
mainPanel.add(new JPanel());
//第2层 账号面板
mainPanel.add(initAcountPanel());
//第3层 密码面板
mainPanel.add(initPasswordPanel());
//第4层 密码确认面板
mainPanel.add(initConfirmPasswordPanel());
//第5层 邮箱面板
mainPanel.add(initEmailPanel());
//第6层 验证码面板
mainPanel.add(initCaptchaPanel());
//第7层 按钮面板
mainPanel.add(initButtonPanel());
//第8层 空白面板 占用
mainPanel = new JPanel(new BorderLayout());
mainPanel.setBackground(BACKGROUND_COLOR);
// 创建顶部标题面板
JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
titlePanel.setBackground(PRIMARY_COLOR);
JLabel titleLabel = new JLabel("用户注册");
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
titleLabel.setForeground(Color.WHITE);
titlePanel.add(titleLabel);
mainPanel.add(titlePanel, BorderLayout.NORTH);
// 创建中央注册表单面板
JPanel formPanel = new JPanel(new GridBagLayout());
formPanel.setBackground(BACKGROUND_COLOR);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
// 第1行 - 标题
gbc.gridx = 0; gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.CENTER;
JLabel formTitleLabel = new JLabel("创建新账户");
formTitleLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
formTitleLabel.setForeground(PRIMARY_COLOR);
formPanel.add(formTitleLabel, gbc);
// 第2行 - 用户名
gbc.gridx = 0; gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.anchor = GridBagConstraints.WEST;
JLabel usernameLabel = new JLabel("用户名:");
usernameLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
formPanel.add(usernameLabel, gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
usernameTextField = new JTextField(15);
usernameTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
usernameTextField.setPreferredSize(new Dimension(200, 25));
formPanel.add(usernameTextField, gbc);
// 第3行 - 密码
gbc.gridx = 0; gbc.gridy = 2;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.WEST;
JLabel passwordLabel = new JLabel("密 码:");
passwordLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
formPanel.add(passwordLabel, gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
passwordField = new JPasswordField(15);
passwordField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
passwordField.setPreferredSize(new Dimension(200, 25));
formPanel.add(passwordField, gbc);
// 第4行 - 确认密码
gbc.gridx = 0; gbc.gridy = 3;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.WEST;
JLabel confirmPasswordLabel = new JLabel("确认密码:");
confirmPasswordLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
formPanel.add(confirmPasswordLabel, gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
confirmPasswordField = new JPasswordField(15);
confirmPasswordField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
confirmPasswordField.setPreferredSize(new Dimension(200, 25));
formPanel.add(confirmPasswordField, gbc);
// 第5行 - 邮箱
gbc.gridx = 0; gbc.gridy = 4;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.WEST;
JLabel emailLabel = new JLabel("邮 箱:");
emailLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
formPanel.add(emailLabel, gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
emailTextField = new JTextField(15);
emailTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
emailTextField.setPreferredSize(new Dimension(200, 25));
formPanel.add(emailTextField, gbc);
// 第6行 - 验证码
gbc.gridx = 0; gbc.gridy = 5;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.WEST;
JLabel captchaLabel = new JLabel("验证码:");
captchaLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
formPanel.add(captchaLabel, gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
JPanel captchaPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
captchaPanel.setBackground(BACKGROUND_COLOR);
captchaTextField = new JTextField(8);
captchaTextField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
captchaTextField.setPreferredSize(new Dimension(80, 25));
captchaPanel.add(captchaTextField);
this.captchaLabel = new JLabel(CaptchaUtils.generateCaptcha());
this.captchaLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
this.captchaLabel.setBackground(Color.WHITE);
this.captchaLabel.setOpaque(true);
this.captchaLabel.setBorder(BorderFactory.createLineBorder(BORDER_COLOR));
this.captchaLabel.setPreferredSize(new Dimension(80, 25));
this.captchaLabel.setHorizontalAlignment(JLabel.CENTER);
captchaPanel.add(this.captchaLabel);
formPanel.add(captchaPanel, gbc);
// 第7行 - 按钮
gbc.gridx = 0; gbc.gridy = 6;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.CENTER;
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 0));
buttonPanel.setBackground(BACKGROUND_COLOR);
registerButton = new JButton("注册");
backButton = new JButton("返回");
// 设置按钮样式
setButtonStyle(registerButton);
setButtonStyle(backButton);
buttonPanel.add(registerButton);
buttonPanel.add(backButton);
formPanel.add(buttonPanel, gbc);
// 添加边距
formPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
mainPanel.add(formPanel, BorderLayout.CENTER);
return mainPanel;
}
// 设置按钮样式
private void setButtonStyle(JButton button) {
button.setFont(new Font("微软雅黑", Font.BOLD, 14));
button.setPreferredSize(new Dimension(80, 30));
button.setBackground(PRIMARY_COLOR);
button.setForeground(Color.WHITE);
button.setFocusPainted(false);
button.setBorder(BorderFactory.createRaisedBevelBorder());
}
private JPanel initAcountPanel(){
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1,4,10,0));

225
src/view/UserPanel.java Normal file
View File

@@ -0,0 +1,225 @@
package view;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;
import backend.dao.UserDao;
import backend.model.User;
import backend.service.AuthService;
public class UserPanel extends JPanel {
private AuthService authService = new AuthService();
private static Vector<String> columNames = new Vector<>();
private DefaultTableModel model;
private JTable table;
private JScrollPane scrollPane;
private Vector<Vector<String>> tableData;
//按钮界面
private JButton addButton;
private JButton deleteButton;
private JButton editButton;
//搜索界面
private JComboBox roleComboBox;
private JTextField keyTextField;
private JButton queryButton;
// 颜色常量定义
private static final Color PRIMARY_COLOR = new Color(70, 130, 180); // 钢蓝色
private static final Color BACKGROUND_COLOR = new Color(248, 249, 250); // 浅灰色背景
private static final Color BORDER_COLOR = new Color(220, 220, 220); // 边框颜色
private static final Color HIGHLIGHT_COLOR = new Color(255, 255, 204); // 高亮背景
static {
columNames.add("ID");
columNames.add("昵称");
columNames.add("权限");
columNames.add("邮箱");
columNames.add("创建时间");
}
public void initListener(){
queryButton.addActionListener(e->{
Integer r = roleComboBox.getSelectedIndex()==0? null:roleComboBox.getSelectedIndex();
String role;
if(r==null)
role=null;
else if(r==1)
role="user";
else role="admin";
String key = keyTextField.getText();
//清楚已有数据
model.setRowCount(0);
//条件查询
tableData = authService.getByCondition(role,key);
//刷新表格
refreshData();
});
deleteButton.addActionListener(e->{
if(MainFrame.role.equals("user"))
return;
int row = table.getSelectedRow();
if(row!=-1){
int id = Integer.valueOf(tableData.get(row).get(0));
String word = tableData.get(row).get(1);
int option = JOptionPane.showConfirmDialog(this,"确认删除"+word+"吗?","提示",JOptionPane.YES_NO_CANCEL_OPTION);
if(option == JOptionPane.YES_OPTION){
authService.deleteUser(id);
model.removeRow(row);
}
}
});
//添加事件:打开对话框
addButton.addActionListener(e->{
if(MainFrame.role.equals("user"))
return;
new EditUserDialog(0,null);
});
editButton.addActionListener(e->{
if(MainFrame.role.equals("user"))
return;
int row = table.getSelectedRow();
if(row>=0)
openEditDialog(row);
});
//双击某行弹出修改对话框
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(MainFrame.role.equals("user"))
return;
if(e.getClickCount()==2){
int row = table.getSelectedRow();
openEditDialog(row);
}
}
});
}
private void initView(){
setLayout(new BorderLayout());
setBackground(BACKGROUND_COLOR);
// 创建顶部工具栏
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.setBackground(PRIMARY_COLOR);
topPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
JLabel titleLabel = new JLabel("用户管理");
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
titleLabel.setForeground(Color.WHITE);
topPanel.add(titleLabel, BorderLayout.WEST);
add(topPanel, BorderLayout.NORTH);
// 创建中央内容面板
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
centerPanel.setBackground(BACKGROUND_COLOR);
centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 1.按钮界面
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
buttonPanel.setBackground(BACKGROUND_COLOR);
addButton = new JButton("添加");
deleteButton = new JButton("删除");
editButton = new JButton("修改");
// 设置按钮样式
setButtonStyle(addButton);
setButtonStyle(deleteButton);
setButtonStyle(editButton);
buttonPanel.add(addButton);
buttonPanel.add(deleteButton);
buttonPanel.add(editButton);
centerPanel.add(buttonPanel);
centerPanel.add(Box.createVerticalStrut(10));
// 2.搜索界面
JPanel queryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
queryPanel.setBackground(BACKGROUND_COLOR);
roleComboBox = new JComboBox<String>(new String[]{"全部","user","admin"});
keyTextField = new JTextField(15);
queryButton = new JButton("查询");
// 设置查询按钮样式
setButtonStyle(queryButton);
queryPanel.add(new JLabel("角色:"));
queryPanel.add(roleComboBox);
queryPanel.add(new JLabel("关键词:"));
queryPanel.add(keyTextField);
queryPanel.add(queryButton);
centerPanel.add(queryPanel);
centerPanel.add(Box.createVerticalStrut(10));
// 3.表格界面
model = new DefaultTableModel(){
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
table = new JTable(model);
table.setFont(new Font("微软雅黑", Font.PLAIN, 12));
table.getTableHeader().setFont(new Font("微软雅黑", Font.BOLD, 13));
table.getTableHeader().setBackground(PRIMARY_COLOR);
table.getTableHeader().setForeground(Color.WHITE);
table.setSelectionBackground(new Color(176, 224, 230));
table.setRowHeight(25);
scrollPane = new JScrollPane(table);
scrollPane.setPreferredSize(new Dimension(700, 400));
scrollPane.setBorder(BorderFactory.createLineBorder(BORDER_COLOR, 1));
centerPanel.add(scrollPane);
add(centerPanel, BorderLayout.CENTER);
tableData = authService.getAll();
//刷新数据
refreshData();
}
// 设置按钮样式
private void setButtonStyle(JButton button) {
button.setFont(new Font("微软雅黑", Font.BOLD, 14));
button.setPreferredSize(new Dimension(80, 30));
button.setBackground(PRIMARY_COLOR);
button.setForeground(Color.WHITE);
button.setFocusPainted(false);
button.setBorder(BorderFactory.createRaisedBevelBorder());
}
private void openEditDialog(int row){
Vector<String> data = tableData.get(row);
UserDao userDao = new UserDao();
User userPo = userDao.findById(Integer.parseInt(data.get(0)));
new EditUserDialog(1, userPo);
//修改成功后刷新并定位修改位置
tableData = authService.getAll();
refreshData();
table.setRowSelectionInterval(row,row);
scrollPane.getVerticalScrollBar().setValue(row*table.getRowHeight());
scrollPane.getHorizontalScrollBar().setValue(0);
scrollPane.revalidate();
}
public UserPanel(){
initView();
initListener();
}
private void refreshData(){
model.setDataVector(tableData,columNames);
model.fireTableDataChanged();
}
}