diff --git a/src/main/java/database/Database2.java b/src/main/java/database/Database2.java
index 28a8ac5..8ea93b0 100644
--- a/src/main/java/database/Database2.java
+++ b/src/main/java/database/Database2.java
@@ -3,7 +3,9 @@
 import java.util.Calendar;
 import java.util.UUID;
 import java.util.List;
+import java.util.Map;
 import java.util.Date;
+import java.util.HashMap;
 
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
@@ -20,6 +22,7 @@
 import entity.Seed;
 import entity.User;
 import entity.UserPT;
+import entity.config;
 import entity.Notice;
 import entity.BegInfo;
 import entity.Post;
@@ -29,1047 +32,1053 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-// public class Database2 implements DataManagerInterface {
+public class Database2 implements DataManagerInterface {
 
-//     private EntityManagerFactory emf;
-//     private static final Logger logger = LoggerFactory.getLogger(Database2.class);
+    private EntityManagerFactory emf;
+    private static final Logger logger = LoggerFactory.getLogger(Database2.class);
 
-//     // 构造函数，初始化EntityManagerFactory
-//     public Database2() {
-//         this.emf = Persistence.createEntityManagerFactory("myPersistenceUnit"); // 使用 persistence.xml 中定义的持久化单元名称。
-//     }
+    // 构造函数，初始化EntityManagerFactory
+    public Database2() {
+        config cfg = new config();
+        Map<String, Object> props = new HashMap<>();
+        props.put("javax.persistence.jdbc.url",
+                "jdbc:mysql://" + cfg.SqlURL + "/" + cfg.Database);
+        props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
+        props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
+        this.emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
+    }
 
-//     @Override
-//     public int RegisterUser(User userinfo) {
-//         return 0;
-//     }
+    public Database2(EntityManagerFactory emf) {
+        this.emf = emf;
+    }
 
-//     @Override
-//     public int UpdateInformation(User userinfo) {
-//         return 0;
-//     }
+    @Override
+    public int RegisterUser(User userinfo) {
+        return 0;
+    }
 
-//     @Override
-//     public User GetInformation(String userid) {
-//         return null;
-//     }
+    @Override
+    public int UpdateInformation(User userinfo) {
+        return 0;
+    }
 
-//     @Override
-//     public UserPT GetInformationPT(String userid) {
-//         return null;
-//     }
+    @Override
+    public User GetInformation(String userid) {
+        return null;
+    }
 
-//     @Override
-//     public int UpdateInformationPT(UserPT userinfo) {
-//         return 0;
-//     }
+    @Override
+    public UserPT GetInformationPT(String userid) {
+        return null;
+    }
 
-//     @Override
-//     public int RegisterUserPT(UserPT userinfo) {
-//         return 0;
-//     }
+    @Override
+    public int UpdateInformationPT(UserPT userinfo) {
+        return 0;
+    }
 
-//     @Override
-//     public Seed GetSeedInformation(String seedid) {
-//         return null;
-//     }
+    @Override
+    public int RegisterUserPT(UserPT userinfo) {
+        return 0;
+    }
 
-//     @Override
-//     public int RegisterSeed(Seed seedinfo) {
-//         return 0;
-//     }
+    @Override
+    public Seed GetSeedInformation(String seedid) {
+        return null;
+    }
 
-//     @Override
-//     public int UpdateSeed(Seed seedinfo) {
-//         return 0;
-//     }
+    @Override
+    public int RegisterSeed(Seed seedinfo) {
+        return 0;
+    }
 
-//     @Override
-//     public Seed[] SearchSeed(String userQ) {
-//         return new Seed[0];
-//     }
+    @Override
+    public int UpdateSeed(Seed seedinfo) {
+        return 0;
+    }
 
-//     @Override
-//     public int AddNotice(Notice notice) {
-//         return 0;
-//     }
+    @Override
+    public Seed[] SearchSeed(String userQ) {
+        return new Seed[0];
+    }
 
-//     @Override
-//     public boolean UpdateNotice(Notice notice) {
-//         return false;
-//     }
+    @Override
+    public int AddNotice(Notice notice) {
+        return 0;
+    }
 
-//     @Override
-//     public boolean DeleteNotice(String noticeid) {
-//         return false;
-//     }
+    @Override
+    public boolean UpdateNotice(Notice notice) {
+        return false;
+    }
 
-//     @Override
-//     public int GetUserAvailableInviteTimes(String userid) {
-//         return 0;
-//     }
+    @Override
+    public boolean DeleteNotice(String noticeid) {
+        return false;
+    }
 
-//     @Override
-//     public int InviteUser(String inviterid, String inviteemail) {
-//         return 0;
-//     }
+    @Override
+    public int GetUserAvailableInviteTimes(String userid) {
+        return 0;
+    }
 
-//     @Override
-//     public boolean AddCollect(String userid, String postid) {
-//         return false;
-//     }
+    @Override
+    public int InviteUser(String inviterid, String inviteemail) {
+        return 0;
+    }
 
-//     @Override
-//     public boolean DeleteCollect(String userid, String postid) {
-//         return false;
-//     }
+    @Override
+    public boolean AddCollect(String userid, String postid) {
+        return false;
+    }
 
-//     @Override
-//     public int AddBegSeed(BegInfo info) {
-//         if (info == null || info.begid == null || info.begid.isEmpty()) {
-//             logger.warn("Invalid parameter: info is null or begid is empty");
-//             return 2;
-//         }
+    @Override
+    public boolean DeleteCollect(String userid, String postid) {
+        return false;
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int AddBegSeed(BegInfo info) {
+        if (info == null || info.begid == null || info.begid.isEmpty()) {
+            logger.warn("Invalid parameter: info is null or begid is empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 检查是否重复
-//             BegInfo existingBeg = em.find(BegInfo.class, info.begid);
-//             if (existingBeg != null) {
-//                 logger.warn("BegSeed with ID {} already exists", info.begid);
-//                 return 1;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 设置默认值
-//             if (info.endtime == null) {
-//                 // 设置默认14天截止期
-//                 Calendar calendar = Calendar.getInstance();
-//                 calendar.add(Calendar.DAY_OF_MONTH, 14);
-//                 info.endtime = calendar.getTime();
-//             }
-//             info.hasseed = false;
+            // 检查是否重复
+            BegInfo existingBeg = em.find(BegInfo.class, info.begid);
+            if (existingBeg != null) {
+                logger.warn("BegSeed with ID {} already exists", info.begid);
+                return 1;
+            }
 
-//             // 保存新的求种信息
-//             em.persist(info);
-//             tx.commit();
+            // 设置默认值
+            if (info.endtime == null) {
+                // 设置默认14天截止期
+                Calendar calendar = Calendar.getInstance();
+                calendar.add(Calendar.DAY_OF_MONTH, 14);
+                info.endtime = calendar.getTime();
+            }
+            info.hasseed = 0;
 
-//             logger.info("Successfully added new BegSeed with ID: {}", info.begid);
-//             return 0;
+            // 保存新的求种信息
+            em.persist(info);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error adding BegSeed: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("Successfully added new BegSeed with ID: {}", info.begid);
+            return 0;
 
-//     @Override
-//     public int UpdateBegSeed(BegInfo info) {
-//         if (info == null || info.begid == null || info.begid.isEmpty()) {
-//             logger.warn("Invalid parameter: info is null or begid is empty");
-//             return 2;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error adding BegSeed: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int UpdateBegSeed(BegInfo info) {
+        if (info == null || info.begid == null || info.begid.isEmpty()) {
+            logger.warn("Invalid parameter: info is null or begid is empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 检查是否存在
-//             BegInfo existingBeg = em.find(BegInfo.class, info.begid);
-//             if (existingBeg == null) {
-//                 logger.warn("BegSeed with ID {} does not exist", info.begid);
-//                 return 1;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 保持原有值不变的字段
-//             info.hasseed = existingBeg.hasseed;
-//             if (info.endtime == null) {
-//                 info.endtime = existingBeg.endtime;
-//             }
+            // 检查是否存在
+            BegInfo existingBeg = em.find(BegInfo.class, info.begid);
+            if (existingBeg == null) {
+                logger.warn("BegSeed with ID {} does not exist", info.begid);
+                return 1;
+            }
 
-//             // 更新求种信息
-//             em.merge(info);
-//             tx.commit();
+            // 保持原有值不变的字段
+            info.hasseed = existingBeg.hasseed;
+            if (info.endtime == null) {
+                info.endtime = existingBeg.endtime;
+            }
 
-//             logger.info("Successfully updated BegSeed with ID: {}", info.begid);
-//             return 0;
+            // 更新求种信息
+            em.merge(info);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error updating BegSeed: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("Successfully updated BegSeed with ID: {}", info.begid);
+            return 0;
 
-//     @Override
-//     public int DeleteBegSeed(String begid) {
-//         if (begid == null || begid.isEmpty()) {
-//             logger.warn("Invalid parameter: begid is null or empty");
-//             return 2;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error updating BegSeed: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int DeleteBegSeed(String begid) {
+        if (begid == null || begid.isEmpty()) {
+            logger.warn("Invalid parameter: begid is null or empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 查找要删除的求种信息
-//             BegInfo begInfo = em.find(BegInfo.class, begid);
-//             if (begInfo == null) {
-//                 logger.warn("BegSeed with ID {} does not exist", begid);
-//                 return 1;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 删除求种信息
-//             em.remove(begInfo);
-//             tx.commit();
+            // 查找要删除的求种信息
+            BegInfo begInfo = em.find(BegInfo.class, begid);
+            if (begInfo == null) {
+                logger.warn("BegSeed with ID {} does not exist", begid);
+                tx.rollback();
+                return 1;
+            }
 
-//             logger.info("Successfully deleted BegSeed with ID: {}", begid);
-//             return 0;
+            // 删除求种信息
+            em.remove(begInfo);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error deleting BegSeed: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("Successfully deleted BegSeed with ID: {}", begid);
+            return 0;
 
-//     @Override
-//     public int VoteSeed(String begId, String seedId, String userId) {
-//         if (begId == null || seedId == null || userId == null ||
-//                 begId.isEmpty() || seedId.isEmpty() || userId.isEmpty()) {
-//             logger.warn("Invalid parameters: begId, seedId or userId is null or empty");
-//             return 2;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error deleting BegSeed: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int VoteSeed(String begId, String seedId, String userId) {
+        if (begId == null || seedId == null || userId == null ||
+                begId.isEmpty() || seedId.isEmpty() || userId.isEmpty()) {
+            logger.warn("Invalid parameters: begId, seedId or userId is null or empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 检查求种信息是否存在
-//             BegInfo begInfo = em.find(BegInfo.class, begId);
-//             if (begInfo == null) {
-//                 logger.warn("BegSeed with ID {} does not exist", begId);
-//                 return 2;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 检查用户是否已投票
-//             QUserVotes uv = QUserVotes.userVotes;
-//             Long voteCount = new JPAQuery<>(em)
-//                     .select(uv.count())
-//                     .from(uv)
-//                     .where(uv.user.userid.eq(userId))
-//                     .where(uv.begInfo.begid.eq(begId))
-//                     .where(uv.seed.seedid.eq(seedId))
-//                     .fetchOne();
+            // 检查求种信息是否存在
+            BegInfo begInfo = em.find(BegInfo.class, begId);
+            if (begInfo == null) {
+                logger.warn("BegSeed with ID {} does not exist", begId);
+                return 2;
+            }
 
-//             if (voteCount > 0) {
-//                 logger.warn("User {} has already voted for seed {} in beg {}", userId,
-//                         seedId, begId);
-//                 return 1;
-//             }
+            // 检查用户是否已投票
+            Long voteCount = new JPAQuery<>(em)
+                    .select(QUserVotes.userVotes.count())
+                    .from(QUserVotes.userVotes)
+                    .where(QUserVotes.userVotes.id.eq(new entity.UserVotesId(userId, begId, seedId)))
+                    .fetchOne();
 
-//             // 创建新的投票记录
-//             em.createNativeQuery("INSERT INTO UserVotes (user_id, beg_id, seed_id, created_at) " +
-//                     "VALUES (?, ?, ?, CURRENT_TIMESTAMP)")
-//                     .setParameter(1, userId)
-//                     .setParameter(2, begId)
-//                     .setParameter(3, seedId)
-//                     .executeUpdate();
+            if (voteCount != null && voteCount > 0) {
+                logger.warn("User {} has already voted for seed {} in beg {}", userId, seedId, begId);
+                return 1;
+            }
 
-//             // 更新SubmitSeed表中的投票数
-//             em.createQuery("UPDATE SubmitSeed s SET s.votes = s.votes + 1 " +
-//                     "WHERE s.begId = :begId AND s.seedId = :seedId")
-//                     .setParameter("begId", begId)
-//                     .setParameter("seedId", seedId)
-//                     .executeUpdate();
+            // 创建新的投票记录
+            em.createNativeQuery("INSERT INTO UserVotes (user_id, beg_id, seed_id, created_at) " +
+                    "VALUES (?, ?, ?, CURRENT_TIMESTAMP)")
+                    .setParameter(1, userId)
+                    .setParameter(2, begId)
+                    .setParameter(3, seedId)
+                    .executeUpdate();
 
-//             tx.commit();
-//             logger.info("Successfully added vote from user {} for seed {} in beg {}",
-//                     userId, seedId, begId);
-//             return 0;
+            // 更新SubmitSeed表中的投票数
+            em.createQuery("UPDATE SubmitSeed s SET s.votes = s.votes + 1 " +
+                    "WHERE s.id.begId = :begId AND s.id.seedId = :seedId")
+                    .setParameter("begId", begId)
+                    .setParameter("seedId", seedId)
+                    .executeUpdate();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error voting for seed: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            tx.commit();
+            logger.info("Successfully added vote from user {} for seed {} in beg {}", userId, seedId, begId);
+            return 0;
 
-//     @Override
-//     public int SubmitSeed(String begid, Seed seed) {
-//         if (begid == null || seed == null || begid.isEmpty() || seed.seedid == null) {
-//             logger.warn("Invalid parameters: begid or seed is null or empty");
-//             return 2;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error voting for seed: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int SubmitSeed(String begid, Seed seed) {
+        if (begid == null || seed == null || begid.isEmpty() || seed.seedid == null) {
+            logger.warn("Invalid parameters: begid or seed is null or empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 检查求种信息是否存在
-//             BegInfo begInfo = em.find(BegInfo.class, begid);
-//             if (begInfo == null) {
-//                 logger.warn("BegSeed with ID {} does not exist", begid);
-//                 return 2;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 检查种子是否已提交过
-//             QSubmitSeed ss = QSubmitSeed.submitSeed;
-//             Long submitCount = new JPAQuery<>(em)
-//                     .select(ss.count())
-//                     .from(ss)
-//                     .where(ss.begInfo.begid.eq(begid))
-//                     .where(ss.seed.seedid.eq(seed.seedid))
-//                     .fetchOne();
+            // 检查求种信息是否存在
+            BegInfo begInfo = em.find(BegInfo.class, begid);
+            if (begInfo == null) {
+                logger.warn("BegSeed with ID {} does not exist", begid);
+                return 2;
+            }
 
-//             if (submitCount > 0) {
-//                 logger.warn("Seed {} has already been submitted for beg {}", seed.seedid,
-//                         begid);
-//                 return 1;
-//             }
+            // 检查种子是否已提交过
+            QSubmitSeed ss = QSubmitSeed.submitSeed;
+            Long submitCount = new JPAQuery<>(em)
+                    .select(ss.count())
+                    .from(ss)
+                    .where(ss.begInfo.begid.eq(begid))
+                    .where(ss.seed.seedid.eq(seed.seedid))
+                    .fetchOne();
 
-//             // 保存种子信息（如果不存在）
-//             if (em.find(Seed.class, seed.seedid) == null) {
-//                 em.persist(seed);
-//             }
+            if (submitCount > 0) {
+                logger.warn("Seed {} has already been submitted for beg {}", seed.seedid,
+                        begid);
+                return 1;
+            }
 
-//             // 创建提交记录
-//             em.createNativeQuery("INSERT INTO SubmitSeed (beg_id, seed_id, votes) VALUES (?, ?, 0)")
-//                     .setParameter(1, begid)
-//                     .setParameter(2, seed.seedid)
-//                     .executeUpdate();
+            // 保存种子信息（如果不存在）
+            if (em.find(Seed.class, seed.seedid) == null) {
+                em.persist(seed);
+            }
 
-//             tx.commit();
-//             logger.info("Successfully submitted seed {} for beg {}", seed.seedid, begid);
-//             return 0;
+            // 创建提交记录
+            em.createNativeQuery("INSERT INTO SubmitSeed (beg_id, seed_id, votes) VALUES (?, ?, 0)")
+                    .setParameter(1, begid)
+                    .setParameter(2, seed.seedid)
+                    .executeUpdate();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error submitting seed: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            tx.commit();
+            logger.info("Successfully submitted seed {} for beg {}", seed.seedid, begid);
+            return 0;
 
-//     @Override
-//     public void SettleBeg() {
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error submitting seed: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+    @Override
+    public void SettleBeg() {
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 1. 获取所有已过期且未完成的求种信息
-//             QBegInfo b = QBegInfo.begInfo;
-//             List<BegInfo> expiredBegs = new JPAQuery<>(em)
-//                     .select(b)
-//                     .from(b)
-//                     .where(b.endtime.loe(new Date())
-//                             .and(b.hasseed.eq(false)))
-//                     .fetch();
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             for (BegInfo beg : expiredBegs) {
-//                 // 2. 查找投票最多的提交任务
-//                 QSubmitSeed ss = QSubmitSeed.submitSeed;
-//                 Tuple topSubmission = new JPAQuery<>(em)
-//                         .select(ss.seed.seedid, ss.votes)
-//                         .from(ss)
-//                         .where(ss.begInfo.begid.eq(beg.begid))
-//                         .orderBy(ss.votes.desc())
-//                         .limit(1)
-//                         .fetchOne();
+            // 1. 获取所有已过期且未完成的求种信息
+            QBegInfo b = QBegInfo.begInfo;
+            List<BegInfo> expiredBegs = new JPAQuery<>(em)
+                    .select(b)
+                    .from(b)
+                    .where(b.endtime.loe(new Date())
+                            .and(b.hasseed.eq(0)))
+                    .fetch();
 
-//                 if (topSubmission != null && topSubmission.get(ss.votes) > 0) {
-//                     String seedId = topSubmission.get(ss.seed.seedid);
+            for (BegInfo beg : expiredBegs) {
+                // 2. 查找投票最多的提交任务
+                QSubmitSeed ss = QSubmitSeed.submitSeed;
+                Tuple topSubmission = new JPAQuery<>(em)
+                        .select(ss.seed.seedid, ss.votes)
+                        .from(ss)
+                        .where(ss.begInfo.begid.eq(beg.begid))
+                        .orderBy(ss.votes.desc())
+                        .limit(1)
+                        .fetchOne();
 
-//                     // 3. 获取上传者ID
-//                     QSeed s = QSeed.seed;
-//                     String ownerId = new JPAQuery<>(em)
-//                             .select(s.seeduserid)
-//                             .from(s)
-//                             .where(s.seedid.eq(seedId))
-//                             .fetchOne();
+                if (topSubmission != null && topSubmission.get(ss.votes) > 0) {
+                    String seedId = topSubmission.get(ss.seed.seedid);
 
-//                     // 4. 获取上传者的PT信息并更新魔力值
-//                     UserPT ownerPT = em.find(UserPT.class, ownerId);
-//                     if (ownerPT != null) {
-//                         // 5. 发放奖励
-//                         ownerPT.magic += beg.magic;
-//                         em.merge(ownerPT);
+                    // 3. 获取上传者ID
+                    QSeed s = QSeed.seed;
+                    String ownerId = new JPAQuery<>(em)
+                            .select(s.seeduserid)
+                            .from(s)
+                            .where(s.seedid.eq(seedId))
+                            .fetchOne();
 
-//                         // 6. 更新求种状态
-//                         beg.hasseed = true;
-//                         em.merge(beg);
+                    // 4. 获取上传者的PT信息并更新魔力值
+                    UserPT ownerPT = em.find(UserPT.class, ownerId);
+                    if (ownerPT != null) {
+                        // 5. 发放奖励
+                        ownerPT.magic += beg.magic;
+                        em.merge(ownerPT);
 
-//                         logger.info("Reward {} magic points awarded to user {} for beg {}",
-//                                 beg.magic, ownerId, beg.begid);
-//                     }
-//                 }
-//             }
+                        // 6. 更新求种状态
+                        beg.hasseed = 1;
+                        em.merge(beg);
 
-//             tx.commit();
-//             logger.info("Successfully settled {} expired beg requests",
-//                     expiredBegs.size());
+                        logger.info("Reward {} magic points awarded to user {} for beg {}",
+                                beg.magic, ownerId, beg.begid);
+                    }
+                }
+            }
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error settling beg requests: {}", e.getMessage(), e);
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            tx.commit();
+            logger.info("Successfully settled {} expired beg requests",
+                    expiredBegs.size());
 
-//     @Override
-//     public int AddPost(Post post) {
-//         if (post == null || post.postid == null || post.postid.isEmpty()) {
-//             logger.warn("Invalid parameter: post is null or postid is empty");
-//             return 2;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error settling beg requests: {}", e.getMessage(), e);
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int AddPost(Post post) {
+        if (post == null || post.postid == null || post.postid.isEmpty()) {
+            logger.warn("Invalid parameter: post is null or postid is empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 检查是否重复
-//             Post existingPost = em.find(Post.class, post.postid);
-//             if (existingPost != null) {
-//                 logger.warn("Post with ID {} already exists", post.postid);
-//                 return 1;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 检查用户是否存在
-//             User user = em.find(User.class, post.postuserid);
-//             if (user == null) {
-//                 logger.warn("User with ID {} does not exist", post.postuserid);
-//                 return 2;
-//             }
+            // 检查是否重复
+            Post existingPost = em.find(Post.class, post.postid);
+            if (existingPost != null) {
+                logger.warn("Post with ID {} already exists", post.postid);
+                return 1;
+            }
 
-//             // 设置初始值
-//             if (post.posttime == null) {
-//                 post.posttime = new Date();
-//             }
-//             post.replytime = 0;
-//             post.readtime = 0;
+            // 检查用户是否存在
+            User user = em.find(User.class, post.postuserid);
+            if (user == null) {
+                logger.warn("User with ID {} does not exist", post.postuserid);
+                return 2;
+            }
 
-//             // 保存帖子
-//             em.persist(post);
-//             tx.commit();
+            // 设置初始值
+            if (post.posttime == null) {
+                post.posttime = new Date();
+            }
+            post.replytime = 0;
+            post.readtime = 0;
 
-//             logger.info("Successfully added new post with ID: {}", post.postid);
-//             return 0;
+            // 保存帖子
+            em.persist(post);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error adding post: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("Successfully added new post with ID: {}", post.postid);
+            return 0;
 
-//     @Override
-//     public int UpdatePost(Post post) {
-//         if (post == null || post.postid == null || post.postid.isEmpty()) {
-//             logger.warn("Invalid parameter: post is null or postid is empty");
-//             return 2;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error adding post: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int UpdatePost(Post post) {
+        if (post == null || post.postid == null || post.postid.isEmpty()) {
+            logger.warn("Invalid parameter: post is null or postid is empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 检查帖子是否存在
-//             Post existingPost = em.find(Post.class, post.postid);
-//             if (existingPost == null) {
-//                 logger.warn("Post with ID {} does not exist", post.postid);
-//                 return 1;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 保持原有不可修改的字段
-//             post.postuserid = existingPost.postuserid;
-//             post.posttime = existingPost.posttime;
-//             post.replytime = existingPost.replytime;
-//             post.readtime = existingPost.readtime;
+            // 检查帖子是否存在
+            Post existingPost = em.find(Post.class, post.postid);
+            if (existingPost == null) {
+                logger.warn("Post with ID {} does not exist", post.postid);
+                return 1;
+            }
 
-//             // 更新帖子
-//             em.merge(post);
-//             tx.commit();
+            // 保持原有不可修改的字段
+            post.postuserid = existingPost.postuserid;
+            post.posttime = existingPost.posttime;
+            post.replytime = existingPost.replytime;
+            post.readtime = existingPost.readtime;
 
-//             logger.info("Successfully updated post with ID: {}", post.postid);
-//             return 0;
+            // 更新帖子
+            em.merge(post);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error updating post: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("Successfully updated post with ID: {}", post.postid);
+            return 0;
 
-//     @Override
-//     public int DeletePost(String postid) {
-//         if (postid == null || postid.isEmpty()) {
-//             logger.warn("Invalid parameter: postid is null or empty");
-//             return 2;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error updating post: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int DeletePost(String postid) {
+        if (postid == null || postid.isEmpty()) {
+            logger.warn("Invalid parameter: postid is null or empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 查找要删除的帖子
-//             Post post = em.find(Post.class, postid);
-//             if (post == null) {
-//                 logger.warn("Post with ID {} does not exist", postid);
-//                 return 1;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 删除帖子(由于设置了级联删除，相关的回复会自动删除)
-//             em.remove(post);
-//             tx.commit();
+            // 查找要删除的帖子
+            Post post = em.find(Post.class, postid);
+            if (post == null) {
+                logger.warn("Post with ID {} does not exist", postid);
+                tx.rollback();
+                return 1;
+            }
 
-//             logger.info("Successfully deleted post with ID: {}", postid);
-//             return 0;
+            // 删除帖子(由于设置了级联删除，相关的回复会自动删除)
+            em.remove(post);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error deleting post: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("Successfully deleted post with ID: {}", postid);
+            return 0;
 
-//     @Override
-//     public int AddComment(String postid, String userid, String comment) {
-//         if (postid == null || postid.isEmpty() ||
-//                 userid == null || userid.isEmpty() ||
-//                 comment == null || comment.isEmpty()) {
-//             logger.warn("Invalid parameters: postid, userid or comment is null or empty");
-//             return 2;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error deleting post: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int AddComment(String postid, String userid, String comment) {
+        if (postid == null || postid.isEmpty() ||
+                userid == null || userid.isEmpty() ||
+                comment == null || comment.isEmpty()) {
+            logger.warn("Invalid parameters: postid, userid or comment is null or empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 检查帖子是否存在
-//             Post post = em.find(Post.class, postid);
-//             if (post == null) {
-//                 logger.warn("Post with ID {} does not exist", postid);
-//                 return 1;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 检查评论用户是否存在
-//             User user = em.find(User.class, userid);
-//             if (user == null) {
-//                 logger.warn("User with ID {} does not exist", userid);
-//                 return 1;
-//             }
+            // 检查帖子是否存在
+            Post post = em.find(Post.class, postid);
+            if (post == null) {
+                logger.warn("Post with ID {} does not exist", postid);
+                return 1;
+            }
 
-//             // 创建新的回复
-//             PostReply reply = new PostReply();
-//             reply.replyid = UUID.randomUUID().toString();
-//             reply.postid = postid;
-//             reply.content = comment;
-//             reply.authorid = userid;
-//             reply.createdAt = new Date();
+            // 检查评论用户是否存在
+            User user = em.find(User.class, userid);
+            if (user == null) {
+                logger.warn("User with ID {} does not exist", userid);
+                return 1;
+            }
 
-//             // 保存回复
-//             em.persist(reply);
+            // 创建新的回复
+            PostReply reply = new PostReply();
+            reply.replyid = UUID.randomUUID().toString();
+            reply.postid = postid;
+            reply.content = comment;
+            reply.authorid = userid;
+            reply.createdAt = new Date();
 
-//             // 更新帖子的回复数
-//             post.replytime += 1;
-//             em.merge(post);
+            // 保存回复
+            em.persist(reply);
 
-//             tx.commit();
+            // 更新帖子的回复数
+            post.replytime += 1;
+            em.merge(post);
 
-//             logger.info("Successfully added comment by user {} to post {}, reply ID: {}",
-//                     userid, postid, reply.replyid);
-//             return 0;
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error adding comment: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("Successfully added comment by user {} to post {}, reply ID: {}",
+                    userid, postid, reply.replyid);
+            return 0;
 
-//     @Override
-//     public int DeleteComment(String postid, String commentid) {
-//         if (postid == null || postid.isEmpty() || commentid == null || commentid.isEmpty()) {
-//             logger.warn("Invalid parameters: postid or commentid is null or empty");
-//             return 2;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error adding comment: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public int DeleteComment(String postid, String commentid) {
+        if (postid == null || postid.isEmpty() || commentid == null || commentid.isEmpty()) {
+            logger.warn("Invalid parameters: postid or commentid is null or empty");
+            return 2;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 检查帖子是否存在
-//             Post post = em.find(Post.class, postid);
-//             if (post == null) {
-//                 logger.warn("Post with ID {} does not exist", postid);
-//                 return 1;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 检查评论是否存在且属于该帖子
-//             PostReply reply = em.find(PostReply.class, commentid);
-//             if (reply == null || !reply.postid.equals(postid)) {
-//                 logger.warn("Comment {} does not exist or does not belong to post {}", commentid, postid);
-//                 return 1;
-//             }
+            // 检查帖子是否存在
+            Post post = em.find(Post.class, postid);
+            if (post == null) {
+                logger.warn("Post with ID {} does not exist", postid);
+                return 1;
+            }
 
-//             // 删除评论
-//             em.remove(reply);
+            // 检查评论是否存在且属于该帖子
+            PostReply reply = em.find(PostReply.class, commentid);
+            if (reply == null || !reply.postid.equals(postid)) {
+                logger.warn("Comment {} does not exist or does not belong to post {}", commentid, postid);
+                return 1;
+            }
 
-//             // 更新帖子的回复数
-//             post.replytime = Math.max(0, post.replytime - 1);
-//             em.merge(post);
+            // 删除评论
+            em.remove(reply);
 
-//             tx.commit();
+            // 更新帖子的回复数
+            post.replytime = Math.max(0, post.replytime - 1);
+            em.merge(post);
 
-//             logger.info("Successfully deleted comment {} from post {}", commentid, postid);
-//             return 0;
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("Error deleting comment: {}", e.getMessage());
-//             return 2;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("Successfully deleted comment {} from post {}", commentid, postid);
+            return 0;
 
-//     @Override
-//     public boolean ExchangeMagicToUpload(String userid, int magic) {
-//         if (userid == null || userid.isEmpty() || magic <= 0) {
-//             logger.warn("参数无效: userid为空或magic <= 0");
-//             return false;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error deleting comment: {}", e.getMessage());
+            return 2;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public boolean ExchangeMagicToUpload(String userid, int magic) {
+        if (userid == null || userid.isEmpty() || magic <= 0) {
+            logger.warn("参数无效: userid为空或magic <= 0");
+            return false;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             UserPT userPT = em.find(UserPT.class, userid);
-//             if (userPT == null) {
-//                 logger.warn("未找到用户 {} 的PT信息", userid);
-//                 return false;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             if (userPT.magic < magic) {
-//                 logger.warn("用户 {} 的魔力值不足", userid);
-//                 return false;
-//             }
+            UserPT userPT = em.find(UserPT.class, userid);
+            if (userPT == null) {
+                logger.warn("未找到用户 {} 的PT信息", userid);
+                return false;
+            }
 
-//             // 1:1兑换，直接加上魔力值（假设单位是MB）
-//             userPT.magic -= magic;
-//             userPT.upload += magic;
+            if (userPT.magic < magic) {
+                logger.warn("用户 {} 的魔力值不足", userid);
+                return false;
+            }
 
-//             // 更新分享率
-//             if (userPT.download > 0) {
-//                 userPT.share = (double) userPT.upload / userPT.download;
-//             }
+            // 1:1兑换，直接加上魔力值（假设单位是MB）
+            userPT.magic -= magic;
+            userPT.upload += magic;
 
-//             em.merge(userPT);
-//             tx.commit();
+            // 更新分享率
+            if (userPT.download > 0) {
+                userPT.share = (double) userPT.upload / userPT.download;
+            }
 
-//             logger.info("用户 {} 成功将 {} 点魔力值兑换为 {}MB 上传量", userid, magic, magic);
-//             return true;
+            em.merge(userPT);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("魔力值兑换上传量时发生错误: {}", e.getMessage());
-//             return false;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("用户 {} 成功将 {} 点魔力值兑换为 {}MB 上传量", userid, magic, magic);
+            return true;
 
-//     @Override
-//     public boolean ExchangeMagicToDownload(String userid, int magic) {
-//         if (userid == null || userid.isEmpty() || magic <= 0) {
-//             logger.warn("参数无效: userid为空或magic <= 0");
-//             return false;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("魔力值兑换上传量时发生错误: {}", e.getMessage());
+            return false;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public boolean ExchangeMagicToDownload(String userid, int magic) {
+        if (userid == null || userid.isEmpty() || magic <= 0) {
+            logger.warn("参数无效: userid为空或magic <= 0");
+            return false;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             UserPT userPT = em.find(UserPT.class, userid);
-//             if (userPT == null) {
-//                 logger.warn("未找到用户 {} 的PT信息", userid);
-//                 return false;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             if (userPT.magic < magic) {
-//                 logger.warn("用户 {} 的魔力值不足", userid);
-//                 return false;
-//             }
+            UserPT userPT = em.find(UserPT.class, userid);
+            if (userPT == null) {
+                logger.warn("未找到用户 {} 的PT信息", userid);
+                return false;
+            }
 
-//             // 1:1兑换，直接减去魔力值对应的下载量（假设单位是MB）
-//             userPT.magic -= magic;
-//             userPT.download = Math.max(0, userPT.download - magic);
+            if (userPT.magic < magic) {
+                logger.warn("用户 {} 的魔力值不足", userid);
+                return false;
+            }
 
-//             // 更新分享率
-//             if (userPT.download > 0) {
-//                 userPT.share = (double) userPT.upload / userPT.download;
-//             }
+            // 1:1兑换，直接减去魔力值对应的下载量（假设单位是MB）
+            userPT.magic -= magic;
+            userPT.download = Math.max(0, userPT.download - magic);
 
-//             em.merge(userPT);
-//             tx.commit();
+            // 更新分享率
+            if (userPT.download > 0) {
+                userPT.share = (double) userPT.upload / userPT.download;
+            }
 
-//             logger.info("用户 {} 成功将 {} 点魔力值兑换为 {}MB 下载量减免", userid, magic, magic);
-//             return true;
+            em.merge(userPT);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("魔力值兑换下载量时发生错误: {}", e.getMessage());
-//             return false;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("用户 {} 成功将 {} 点魔力值兑换为 {}MB 下载量减免", userid, magic, magic);
+            return true;
 
-//     @Override
-//     public boolean ExchangeMagicToVip(String userid, int magic) {
-//         if (userid == null || userid.isEmpty() || magic <= 0) {
-//             logger.warn("参数无效: userid为空或magic <= 0");
-//             return false;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("魔力值兑换下载量时发生错误: {}", e.getMessage());
+            return false;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public boolean ExchangeMagicToVip(String userid, int magic) {
+        if (userid == null || userid.isEmpty() || magic <= 0) {
+            logger.warn("参数无效: userid为空或magic <= 0");
+            return false;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             UserPT userPT = em.find(UserPT.class, userid);
-//             if (userPT == null) {
-//                 logger.warn("未找到用户 {} 的PT信息", userid);
-//                 return false;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             if (userPT.magic < magic) {
-//                 logger.warn("用户 {} 的魔力值不足", userid);
-//                 return false;
-//             }
+            UserPT userPT = em.find(UserPT.class, userid);
+            if (userPT == null) {
+                logger.warn("未找到用户 {} 的PT信息", userid);
+                return false;
+            }
 
-//             // 1:1兑换VIP下载次数
-//             userPT.magic -= magic;
-//             userPT.viptime += magic;
+            if (userPT.magic < magic) {
+                logger.warn("用户 {} 的魔力值不足", userid);
+                return false;
+            }
 
-//             em.merge(userPT);
-//             tx.commit();
+            // 1:1兑换VIP下载次数
+            userPT.magic -= magic;
+            userPT.viptime += magic;
 
-//             logger.info("用户 {} 成功将 {} 点魔力值兑换为 {} 次VIP下载次数", userid, magic, magic);
-//             return true;
+            em.merge(userPT);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("魔力值兑换VIP下载次数时发生错误: {}", e.getMessage());
-//             return false;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("用户 {} 成功将 {} 点魔力值兑换为 {} 次VIP下载次数", userid, magic, magic);
+            return true;
 
-//     @Override
-//     public boolean UploadTransmitProfile(Profile profile) {
-//         if (profile == null || profile.profileurl == null || profile.profileurl.isEmpty() ||
-//                 profile.userid == null || profile.userid.isEmpty()) {
-//             logger.warn("参数无效: profile为空或必要字段为空");
-//             return false;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("魔力值兑换VIP下载次数时发生错误: {}", e.getMessage());
+            return false;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public boolean UploadTransmitProfile(Profile profile) {
+        if (profile == null || profile.profileurl == null || profile.profileurl.isEmpty() ||
+                profile.userid == null || profile.userid.isEmpty()) {
+            logger.warn("参数无效: profile为空或必要字段为空");
+            return false;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             // 检查用户是否存在
-//             User user = em.find(User.class, profile.userid);
-//             if (user == null) {
-//                 logger.warn("用户 {} 不存在", profile.userid);
-//                 return false;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             // 检查是否已存在相同的迁移申请
-//             Profile existingProfile = em.find(Profile.class, profile.profileurl);
-//             if (existingProfile != null) {
-//                 logger.warn("迁移申请 {} 已存在", profile.profileurl);
-//                 return false;
-//             }
+            // 检查用户是否存在
+            User user = em.find(User.class, profile.userid);
+            if (user == null) {
+                logger.warn("用户 {} 不存在", profile.userid);
+                return false;
+            }
 
-//             // 设置初始值
-//             profile.exampass = false;
-//             profile.magicgived = "0";
-//             profile.uploadgived = "0";
+            // 检查是否已存在相同的迁移申请
+            Profile existingProfile = em.find(Profile.class, profile.profileurl);
+            if (existingProfile != null) {
+                logger.warn("迁移申请 {} 已存在", profile.profileurl);
+                return false;
+            }
 
-//             // 保存迁移申请
-//             em.persist(profile);
-//             tx.commit();
+            // 设置初始值
+            profile.exampass = false;
+            profile.magicgived = "0";
+            profile.uploadgived = "0";
 
-//             logger.info("成功上传迁移申请 {}", profile.profileurl);
-//             return true;
+            // 保存迁移申请
+            em.persist(profile);
+            tx.commit();
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("上传迁移申请时发生错误: {}", e.getMessage());
-//             return false;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("成功上传迁移申请 {}", profile.profileurl);
+            return true;
 
-//     @Override
-//     public Profile GetTransmitProfile(String profileid) {
-//         if (profileid == null || profileid.isEmpty()) {
-//             logger.warn("参数无效: profileid为空");
-//             return null;
-//         }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("上传迁移申请时发生错误: {}", e.getMessage());
+            return false;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
+    @Override
+    public Profile GetTransmitProfile(String profileid) {
+        if (profileid == null || profileid.isEmpty()) {
+            logger.warn("参数无效: profileid为空");
+            return null;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             Profile profile = em.find(Profile.class, profileid);
-//             if (profile == null) {
-//                 logger.warn("未找到迁移申请 {}", profileid);
-//                 return null;
-//             }
+        EntityManager em = null;
 
-//             logger.info("成功获取迁移申请 {}", profileid);
-//             return profile;
+        try {
+            em = emf.createEntityManager();
+            Profile profile = em.find(Profile.class, profileid);
+            if (profile == null) {
+                logger.warn("未找到迁移申请 {}", profileid);
+                return null;
+            }
 
-//         } catch (Exception e) {
-//             logger.error("获取迁移申请时发生错误: {}", e.getMessage());
-//             return null;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+            logger.info("成功获取迁移申请 {}", profileid);
+            return profile;
 
-//     @Override
-//     public boolean ExamTransmitProfile(String profileid, boolean result) {
-//         if (profileid == null || profileid.isEmpty()) {
-//             logger.warn("参数无效: profileid为空");
-//             return false;
-//         }
+        } catch (Exception e) {
+            logger.error("获取迁移申请时发生错误: {}", e.getMessage());
+            return null;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//         EntityManager em = null;
-//         EntityTransaction tx = null;
+    @Override
+    public boolean ExamTransmitProfile(String profileid, boolean result) {
+        if (profileid == null || profileid.isEmpty()) {
+            logger.warn("参数无效: profileid为空");
+            return false;
+        }
 
-//         try {
-//             em = emf.createEntityManager();
-//             tx = em.getTransaction();
-//             tx.begin();
+        EntityManager em = null;
+        EntityTransaction tx = null;
 
-//             Profile profile = em.find(Profile.class, profileid);
-//             if (profile == null) {
-//                 logger.warn("未找到迁移申请 {}", profileid);
-//                 return false;
-//             }
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
 
-//             if (profile.exampass != result) {
-//                 profile.exampass = result;
+            // 查找迁移申请
+            Profile profile = em.find(Profile.class, profileid);
+            if (profile == null) {
+                logger.warn("未找到迁移申请 {}", profileid);
+                return false;
+            }
 
-//                 if (result) {
-//                     // 如果审核通过，更新用户的PT信息
-//                     UserPT userPT = em.find(UserPT.class, profile.userid);
-//                     if (userPT != null) {
-//                         // 发放魔力值
-//                         int magicToGive = Integer.parseInt(profile.magictogive);
-//                         userPT.magic += magicToGive;
-//                         profile.magicgived = String.valueOf(magicToGive);
+            // 更新审核状态
+            profile.exampass = result;
 
-//                         // 发放上传量
-//                         long uploadToGive = Long.parseLong(profile.uploadtogive);
-//                         userPT.upload += uploadToGive;
-//                         profile.uploadgived = String.valueOf(uploadToGive);
+            if (result) {
+                // 如果审核通过，更新用户的PT信息
+                UserPT userPT = em.find(UserPT.class, profile.userid);
+                if (userPT != null) {
+                    // 发放魔力值
+                    int magicToGive = Integer.parseInt(profile.magictogive);
+                    userPT.magic += magicToGive;
+                    profile.magicgived = String.valueOf(magicToGive);
 
-//                         em.merge(userPT);
-//                     }
-//                 }
+                    // 发放上传量
+                    long uploadToGive = Long.parseLong(profile.uploadtogive);
+                    userPT.upload += uploadToGive;
+                    profile.uploadgived = String.valueOf(uploadToGive);
 
-//                 em.merge(profile);
-//             }
+                    em.merge(userPT);
+                }
+            }
 
-//             tx.commit();
+            em.merge(profile);
+            tx.commit();
 
-//             logger.info("成功审核迁移申请 {}, 结果: {}", profileid, result);
-//             return true;
+            logger.info("成功审核迁移申请 {}, 结果: {}", profileid, result);
+            return true;
 
-//         } catch (Exception e) {
-//             if (tx != null && tx.isActive()) {
-//                 tx.rollback();
-//             }
-//             logger.error("审核迁移申请时发生错误: {}", e.getMessage());
-//             return false;
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("审核迁移申请时发生错误: {}", e.getMessage());
+            return false;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
 
-//     @Override
-//     public Profile[] GetTransmitProfileList() {
-//         EntityManager em = null;
+    @Override
+    public Profile[] GetTransmitProfileList() {
+        EntityManager em = null;
 
-//         try {
-//             em = emf.createEntityManager();
+        try {
+            em = emf.createEntityManager();
 
-//             // 获取所有迁移申请
-//             QProfile p = QProfile.profile;
-//             List<Profile> profiles = new JPAQuery<>(em)
-//                     .select(p)
-//                     .from(p)
-//                     .fetch();
+            // 获取所有迁移申请
+            QProfile p = QProfile.profile;
+            List<Profile> profiles = new JPAQuery<>(em)
+                    .select(p)
+                    .from(p)
+                    .fetch();
 
-//             logger.info("成功获取所有迁移申请，共 {} 条", profiles.size());
-//             return profiles.toArray(new Profile[0]);
+            logger.info("成功获取所有迁移申请，共 {} 条", profiles.size());
+            return profiles.toArray(new Profile[0]);
 
-//         } catch (Exception e) {
-//             logger.error("获取迁移申请列表时发生错误: {}", e.getMessage());
-//             return new Profile[0];
-//         } finally {
-//             if (em != null) {
-//                 em.close();
-//             }
-//         }
-//     }
-// }
\ No newline at end of file
+        } catch (Exception e) {
+            logger.error("获取迁移申请列表时发生错误: {}", e.getMessage());
+            return new Profile[0];
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/databasetest/database2Test.java b/src/test/java/databasetest/database2Test.java
index 196db26..55e09e2 100644
--- a/src/test/java/databasetest/database2Test.java
+++ b/src/test/java/databasetest/database2Test.java
@@ -1,864 +1,1078 @@
-// package databasetest;
+package databasetest;
 
-// import database.Database2;
-// import entity.*;
-// import org.junit.jupiter.api.*;
+import database.Database2;
+import entity.*;
+import org.junit.jupiter.api.*;
 
-// import javax.persistence.*;
-// import java.util.*;
-// import java.util.stream.Collectors;
+import javax.persistence.*;
+import java.util.*;
 
-// public class database2Test {
-// private static EntityManagerFactory emf;
-// private static EntityManager em;
-// private static Database2 db;
+public class database2Test {
+    private static EntityManagerFactory emf;
+    private static EntityManager em;
+    private static Database2 db;
 
-// @BeforeAll
-// static void setup() throws Exception {
-// // 强制加载 MySQL 驱动
-// Class.forName("com.mysql.cj.jdbc.Driver");
-// entity.config cfg = new entity.config();
-// Map<String, Object> props = new HashMap<>();
-// String jdbcUrl = String.format(
-// "jdbc:mysql://%s/%s?useSSL=false&serverTimezone=UTC",
-// cfg.SqlURL, cfg.TestDatabase);
-// props.put("javax.persistence.jdbc.url", jdbcUrl);
-// props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
-// props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
-// props.put("javax.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
-// emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
-// em = emf.createEntityManager();
-// // 修改此处：传入配置好的EntityManagerFactory给Database2
-// db = new Database2(emf);
-// }
+    @BeforeAll
+    static void setup() throws Exception {
+        // 强制加载 MySQL 驱动
+        Class.forName("com.mysql.cj.jdbc.Driver");
+        entity.config cfg = new entity.config();
+        Map<String, Object> props = new HashMap<>();
+        String jdbcUrl = String.format(
+                "jdbc:mysql://%s/%s?useSSL=false&serverTimezone=UTC",
+                cfg.SqlURL, cfg.TestDatabase);
+        props.put("javax.persistence.jdbc.url", jdbcUrl);
+        props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
+        props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
+        props.put("javax.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
+        emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
+        em = emf.createEntityManager();
+        db = new Database2(emf);
+    }
 
-// @AfterAll
-// static void teardown() {
-// if (em != null && em.isOpen())
-// em.close();
-// if (emf != null && emf.isOpen())
-// emf.close();
-// }
+    @AfterAll
+    static void teardown() {
+        if (em != null && em.isOpen())
+            em.close();
+        if (emf != null && emf.isOpen())
+            emf.close();
+    }
 
-// @TestFactory
-// Collection<DynamicTest> testAddBegSeed() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+    @TestFactory
+    Collection<DynamicTest> testAddBegSeed() {
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class).getResultList();
+        if (userIds.isEmpty())
+            return Collections.emptyList();
+        String uid = userIds.get(0);
 
-// String begId = "test_beg_" + UUID.randomUUID().toString();
+        return List.of(
+                DynamicTest.dynamicTest("AddBegSeed success", () -> {
+                    String begId = "test_beg_" + System.currentTimeMillis();
+                    BegInfo beg = new BegInfo();
+                    beg.begid = begId;
+                    beg.begnumbers = 1;
+                    beg.magic = 100;
+                    beg.endtime = new Date();
+                    beg.hasseed = 0;
+                    try {
+                        int ret = db.AddBegSeed(beg);
+                        Assertions.assertEquals(0, ret, "AddBegSeed应返回0");
+                    } finally {
+                        EntityTransaction tx = em.getTransaction();
+                        tx.begin();
+                        BegInfo toDelete = em.find(BegInfo.class, begId);
+                        if (toDelete != null)
+                            em.remove(toDelete);
+                        tx.commit();
+                    }
+                }),
 
-// BegInfo beg = new BegInfo();
-// beg.begid = begId;
-// beg.begnumbers = 1;
-// beg.magic = 100;
-// beg.endtime = new Date();
-// beg.hasseed = false;
+                DynamicTest.dynamicTest("AddBegSeed duplicate", () -> {
+                    String begId = "test_beg_" + (System.currentTimeMillis() + 1);
+                    BegInfo beg = new BegInfo();
+                    beg.begid = begId;
+                    beg.begnumbers = 1;
+                    beg.magic = 100;
+                    beg.endtime = new Date();
+                    beg.hasseed = 0;
+                    try {
+                        db.AddBegSeed(beg);
+                        int ret = db.AddBegSeed(beg);
+                        Assertions.assertEquals(1, ret, "重复插入应返回1");
+                    } finally {
+                        EntityTransaction tx = em.getTransaction();
+                        tx.begin();
+                        BegInfo toDelete = em.find(BegInfo.class, begId);
+                        if (toDelete != null)
+                            em.remove(toDelete);
+                        tx.commit();
+                    }
+                }),
 
-// return List.of(
-// DynamicTest.dynamicTest("AddBegSeed success", () -> {
-// int ret = db.AddBegSeed(beg);
-// Assertions.assertEquals(0, ret, "AddBegSeed应返回0");
-// BegInfo inserted = em.find(BegInfo.class, begId);
-// Assertions.assertNotNull(inserted, "求种信息应已插入");
-// Assertions.assertFalse(inserted.hasseed, "新求种默认未完成");
-// }),
+                DynamicTest.dynamicTest("AddBegSeed invalid param", () -> {
+                    Assertions.assertEquals(2, db.AddBegSeed(null));
+                    BegInfo invalidBeg = new BegInfo();
+                    invalidBeg.begid = "";
+                    Assertions.assertEquals(2, db.AddBegSeed(invalidBeg));
+                }));
+    }
 
-// DynamicTest.dynamicTest("AddBegSeed duplicate", () -> {
-// int ret = db.AddBegSeed(beg);
-// Assertions.assertEquals(1, ret, "重复插入应返回1");
-// }),
+    @TestFactory
+    Collection<DynamicTest> testUpdateBegSeed() {
+        List<BegInfo> existingBegs = em.createQuery("SELECT b FROM BegInfo b", BegInfo.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (existingBegs.isEmpty()) {
+            return Collections.emptyList();
+        }
 
-// DynamicTest.dynamicTest("AddBegSeed invalid param", () -> {
-// Assertions.assertEquals(2, db.AddBegSeed(null));
-// BegInfo invalidBeg = new BegInfo();
-// invalidBeg.begid = "";
-// Assertions.assertEquals(2, db.AddBegSeed(invalidBeg));
-// }));
-// }
+        BegInfo originalBeg = existingBegs.get(0);
+        String begId = originalBeg.begid;
+        int originalMagic = originalBeg.magic;
+        int originalBegNumbers = originalBeg.begnumbers;
+        int originalHasSeed = originalBeg.hasseed;
+        Date originalEndTime = originalBeg.endtime;
 
-// @TestFactory
-// Collection<DynamicTest> testUpdateBegSeed() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+        return List.of(
+                DynamicTest.dynamicTest("UpdateBegSeed success", () -> {
+                    try {
+                        BegInfo update = new BegInfo();
+                        update.begid = begId;
+                        update.begnumbers = originalBegNumbers + 1;
+                        update.magic = originalMagic + 100;
+                        update.endtime = originalEndTime;
+                        update.hasseed = originalHasSeed;
 
-// String begId = "test_beg_update_" + UUID.randomUUID().toString();
+                        int ret = db.UpdateBegSeed(update);
+                        Assertions.assertEquals(0, ret, "UpdateBegSeed应返回0");
 
-// // 先插入一条求种记录
-// BegInfo beg = new BegInfo();
-// beg.begid = begId;
-// beg.begnumbers = 1;
-// beg.magic = 100;
-// beg.endtime = new Date();
-// db.AddBegSeed(beg);
+                        em.clear();
+                        BegInfo updated = em.find(BegInfo.class, begId);
+                        Assertions.assertEquals(originalMagic + 100, updated.magic, "魔力值应已更新");
+                        Assertions.assertEquals(originalBegNumbers + 1, updated.begnumbers, "求种人数应已更新");
+                    } finally {
+                        // 恢复原始数据
+                        EntityTransaction tx = em.getTransaction();
+                        tx.begin();
+                        BegInfo toRestore = em.find(BegInfo.class, begId);
+                        if (toRestore != null) {
+                            toRestore.magic = originalMagic;
+                            toRestore.begnumbers = originalBegNumbers;
+                            toRestore.hasseed = originalHasSeed;
+                            toRestore.endtime = originalEndTime;
+                            em.merge(toRestore);
+                        }
+                        tx.commit();
+                    }
+                }),
+                DynamicTest.dynamicTest("UpdateBegSeed not exist", () -> {
+                    BegInfo notExist = new BegInfo();
+                    notExist.begid = "not_exist_beg";
+                    notExist.begnumbers = 1;
+                    notExist.magic = 100;
+                    notExist.endtime = new Date();
+                    notExist.hasseed = 0;
 
-// return List.of(
-// DynamicTest.dynamicTest("UpdateBegSeed success", () -> {
-// BegInfo update = new BegInfo();
-// update.begid = begId;
-// update.begnumbers = 2;
-// update.magic = 200;
+                    int ret = db.UpdateBegSeed(notExist);
+                    Assertions.assertEquals(1, ret, "不存在的求种应返回1");
+                }),
+                DynamicTest.dynamicTest("UpdateBegSeed invalid param", () -> {
+                    Assertions.assertEquals(2, db.UpdateBegSeed(null));
+                    BegInfo invalid = new BegInfo();
+                    invalid.begid = "";
+                    Assertions.assertEquals(2, db.UpdateBegSeed(invalid));
+                }));
+    }
 
-// int ret = db.UpdateBegSeed(update);
-// Assertions.assertEquals(0, ret, "UpdateBegSeed应返回0");
+    @TestFactory
+    Collection<DynamicTest> testDeleteBegSeed() {
+        List<BegInfo> existingBegs = em.createQuery("SELECT b FROM BegInfo b", BegInfo.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (existingBegs.isEmpty()) {
+            return Collections.emptyList();
+        }
 
-// BegInfo updated = em.find(BegInfo.class, begId);
-// Assertions.assertEquals(200, updated.magic, "魔力值应已更新");
-// Assertions.assertEquals(2, updated.begnumbers, "求种人数应已更新");
-// }),
+        BegInfo begToDelete = existingBegs.get(0);
+        String begId = begToDelete.begid;
 
-// DynamicTest.dynamicTest("UpdateBegSeed not exist", () -> {
-// BegInfo notExist = new BegInfo();
-// notExist.begid = "not_exist_beg";
-// notExist.begnumbers = 1;
-// int ret = db.UpdateBegSeed(notExist);
-// Assertions.assertEquals(1, ret, "不存在的求种应返回1");
-// }),
+        return List.of(
+                DynamicTest.dynamicTest("DeleteBegSeed success", () -> {
+                    EntityTransaction tx = em.getTransaction();
+                    try {
+                        tx.begin();
+                        int ret = db.DeleteBegSeed(begId);
+                        Assertions.assertEquals(0, ret, "DeleteBegSeed 应返回0");
+                    } finally {
+                        tx.rollback();
+                    }
+                }),
 
-// DynamicTest.dynamicTest("UpdateBegSeed invalid param", () -> {
-// Assertions.assertEquals(2, db.UpdateBegSeed(null));
-// BegInfo invalid = new BegInfo();
-// invalid.begid = "";
-// Assertions.assertEquals(2, db.UpdateBegSeed(invalid));
-// }));
-// }
+                DynamicTest.dynamicTest("DeleteBegSeed not exist", () -> {
+                    int ret = db.DeleteBegSeed("not_exist_beg");
+                    Assertions.assertEquals(1, ret, "不存在的求种任务应返回1");
+                }),
 
-// @TestFactory
-// Collection<DynamicTest> testDeleteBegSeed() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+                DynamicTest.dynamicTest("DeleteBegSeed invalid param", () -> {
+                    Assertions.assertEquals(2, db.DeleteBegSeed(null));
+                    Assertions.assertEquals(2, db.DeleteBegSeed(""));
+                }));
+    }
 
-// String begId = "test_beg_delete_" + UUID.randomUUID().toString();
+    @TestFactory
+    Collection<DynamicTest> testVoteSeed() {
+        // 获取现有用户ID
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (userIds.isEmpty())
+            return Collections.emptyList();
+        String uid = userIds.get(0);
 
-// // 先插入一条求种记录
-// BegInfo beg = new BegInfo();
-// beg.begid = begId;
-// beg.begnumbers = 1;
-// beg.magic = 100;
-// beg.endtime = new Date();
-// beg.hasseed = false;
-// db.AddBegSeed(beg);
+        // 获取现有的求种信息
+        List<BegInfo> begs = em.createQuery("SELECT b FROM BegInfo b", BegInfo.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (begs.isEmpty())
+            return Collections.emptyList();
+        String begId = begs.get(0).begid;
 
-// return List.of(
-// DynamicTest.dynamicTest("DeleteBegSeed success", () -> {
-// int ret = db.DeleteBegSeed(begId);
-// Assertions.assertEquals(0, ret, "DeleteBegSeed应返回0");
-// BegInfo deleted = em.find(BegInfo.class, begId);
-// Assertions.assertNull(deleted, "求种信息应已删除");
-// }),
+        // 获取现有的种子信息
+        List<Seed> seeds = em.createQuery("SELECT s FROM Seed s", Seed.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (seeds.isEmpty())
+            return Collections.emptyList();
+        String seedId = seeds.get(0).seedid;
 
-// DynamicTest.dynamicTest("DeleteBegSeed not exist", () -> {
-// int ret = db.DeleteBegSeed("not_exist_beg");
-// Assertions.assertEquals(1, ret, "不存在的求种应返回1");
-// }),
+        try {
+            return List.of(
+                    DynamicTest.dynamicTest("VoteSeed success", () -> {
+                        int ret = db.VoteSeed(begId, seedId, uid);
+                        Assertions.assertEquals(0, ret, "VoteSeed应返回0");
+                    }),
 
-// DynamicTest.dynamicTest("DeleteBegSeed invalid param", () -> {
-// Assertions.assertEquals(2, db.DeleteBegSeed(null));
-// Assertions.assertEquals(2, db.DeleteBegSeed(""));
-// }));
-// }
+                    DynamicTest.dynamicTest("VoteSeed duplicate", () -> {
+                        int ret = db.VoteSeed(begId, seedId, uid);
+                        Assertions.assertEquals(1, ret, "重复投票应返回1");
+                    }),
 
-// @TestFactory
-// Collection<DynamicTest> testVoteSeed() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+                    DynamicTest.dynamicTest("VoteSeed invalid param", () -> {
+                        Assertions.assertEquals(2, db.VoteSeed(null, seedId, uid));
+                        Assertions.assertEquals(2, db.VoteSeed(begId, null, uid));
+                        Assertions.assertEquals(2, db.VoteSeed(begId, seedId, null));
+                    }));
+        } finally {
+            EntityTransaction tx = em.getTransaction();
+            tx.begin();
+            try {
+                em.createQuery(
+                        "DELETE FROM UserVotes v WHERE v.begid = :begid AND v.seedid = :seedid AND v.userid = :uid")
+                        .setParameter("begid", begId)
+                        .setParameter("seedid", seedId)
+                        .setParameter("uid", uid)
+                        .executeUpdate();
+            } catch (Exception ignored) {
+            }
+            tx.commit();
+        }
+    }
 
-// String uid = userIds.get(0);
-// String begId = "test_beg_vote_" + UUID.randomUUID().toString();
-// String seedId = "test_seed_" + UUID.randomUUID().toString();
+    @TestFactory
+    Collection<DynamicTest> testSubmitSeed() {
+        // 获取现有的求种信息
+        List<BegInfo> begs = em.createQuery("SELECT b FROM BegInfo b WHERE b.hasseed = 0", BegInfo.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (begs.isEmpty())
+            return Collections.emptyList();
+        String begId = begs.get(0).begid;
 
-// // 插入求种记录
-// BegInfo beg = new BegInfo();
-// beg.begid = begId;
-// beg.begnumbers = 1;
-// beg.magic = 100;
-// beg.endtime = new Date();
-// beg.hasseed = false;
-// db.AddBegSeed(beg);
+        // 获取现有的可用种子信息
+        List<Seed> existingSeeds = em.createQuery(
+                "SELECT s FROM Seed s WHERE s.seedid NOT IN " +
+                        "(SELECT ss.seed.seedid FROM SubmitSeed ss)",
+                Seed.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (existingSeeds.isEmpty())
+            return Collections.emptyList();
+        Seed seed = existingSeeds.get(0);
 
-// // 插入种子记录
-// Seed seed = new Seed();
-// seed.seedid = seedId;
-// seed.seeduserid = uid;
-// seed.title = "测试种子";
-// em.getTransaction().begin();
-// em.persist(seed);
-// em.getTransaction().commit();
+        try {
+            return List.of(
+                    DynamicTest.dynamicTest("SubmitSeed success", () -> {
+                        int ret = db.SubmitSeed(begId, seed);
+                        Assertions.assertEquals(0, ret, "SubmitSeed应返回0");
+                    }),
 
-// // 提交种子
-// db.SubmitSeed(begId, seed);
+                    DynamicTest.dynamicTest("SubmitSeed duplicate", () -> {
+                        int ret = db.SubmitSeed(begId, seed);
+                        Assertions.assertEquals(1, ret, "重复提交应返回1");
+                    }),
 
-// return List.of(
-// DynamicTest.dynamicTest("VoteSeed success", () -> {
-// int ret = db.VoteSeed(begId, seedId, uid);
-// Assertions.assertEquals(0, ret, "VoteSeed应返回0");
-// }),
+                    DynamicTest.dynamicTest("SubmitSeed invalid param", () -> {
+                        Assertions.assertEquals(2, db.SubmitSeed(null, seed));
+                        Assertions.assertEquals(2, db.SubmitSeed(begId, null));
+                    }));
+        } finally {
+            // 清理测试数据
+            EntityTransaction tx = em.getTransaction();
+            tx.begin();
+            try {
+                // 恢复求种状态
+                BegInfo toRestore = em.find(BegInfo.class, begId);
+                if (toRestore != null) {
+                    toRestore.hasseed = 0;
+                    em.merge(toRestore);
+                }
 
-// DynamicTest.dynamicTest("VoteSeed duplicate", () -> {
-// int ret = db.VoteSeed(begId, seedId, uid);
-// Assertions.assertEquals(1, ret, "重复投票应返回1");
-// }),
+                // 清理投票记录
+                em.createQuery("DELETE FROM Vote v WHERE v.begid = :begid AND v.seedid = :seedid")
+                        .setParameter("begid", begId)
+                        .setParameter("seedid", seed.seedid)
+                        .executeUpdate();
+            } catch (Exception ignored) {
+            }
+            tx.commit();
+        }
+    }
 
-// DynamicTest.dynamicTest("VoteSeed invalid param", () -> {
-// Assertions.assertEquals(2, db.VoteSeed(null, seedId, uid));
-// Assertions.assertEquals(2, db.VoteSeed(begId, null, uid));
-// Assertions.assertEquals(2, db.VoteSeed(begId, seedId, null));
-// }));
-// }
+    @Test
+    void testSettleBeg() {
+        String uid = em.createQuery("select u.userid from User u", String.class)
+                .setMaxResults(1)
+                .getSingleResult();
 
-// @TestFactory
-// Collection<DynamicTest> testSubmitSeed() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+        String begId = "test_beg_settle_" + System.currentTimeMillis();
+        String seedId = "test_seed_settle_" + System.currentTimeMillis();
 
-// String uid = userIds.get(0);
-// String begId = "test_beg_submit_" + UUID.randomUUID().toString();
-// String seedId = "test_seed_submit_" + UUID.randomUUID().toString();
+        BegInfo beg = new BegInfo();
+        beg.begid = begId;
+        beg.begnumbers = 1;
+        beg.magic = 100;
+        Calendar cal = Calendar.getInstance();
+        cal.add(Calendar.DAY_OF_MONTH, -15); // 15天前
+        beg.endtime = cal.getTime();
+        beg.hasseed = 0;
 
-// // 插入求种记录
-// BegInfo beg = new BegInfo();
-// beg.begid = begId;
-// beg.begnumbers = 1;
-// beg.magic = 100;
-// beg.endtime = new Date();
-// beg.hasseed = false;
-// db.AddBegSeed(beg);
+        Seed seed = new Seed();
+        seed.seedid = seedId;
+        seed.seeduserid = uid;
+        seed.title = "测试种子";
+        seed.seedsize = "1";
 
-// Seed seed = new Seed();
-// seed.seedid = seedId;
-// seed.seeduserid = uid;
-// seed.title = "测试种子";
+        try {
+            db.AddBegSeed(beg);
+            db.SubmitSeed(begId, seed);
+            db.VoteSeed(begId, seedId, uid);
 
-// return List.of(
-// DynamicTest.dynamicTest("SubmitSeed success", () -> {
-// int ret = db.SubmitSeed(begId, seed);
-// Assertions.assertEquals(0, ret, "SubmitSeed应返回0");
-// }),
+            db.SettleBeg();
+            em.clear();
 
-// DynamicTest.dynamicTest("SubmitSeed duplicate", () -> {
-// int ret = db.SubmitSeed(begId, seed);
-// Assertions.assertEquals(1, ret, "重复提交应返回1");
-// }),
+            BegInfo settled = em.find(BegInfo.class, begId);
+            Assertions.assertEquals(settled.hasseed, 1, "求种应已完成");
 
-// DynamicTest.dynamicTest("SubmitSeed invalid param", () -> {
-// Assertions.assertEquals(2, db.SubmitSeed(null, seed));
-// Assertions.assertEquals(2, db.SubmitSeed(begId, null));
-// }));
-// }
+            UserPT userPT = em.find(UserPT.class, uid);
+            Assertions.assertTrue(userPT.magic >= 0, "用户应获得魔力值奖励");
+        } finally {
+            EntityTransaction tx = em.getTransaction();
+            tx.begin();
+            try {
+                // 删除投票记录
+                em.createQuery(
+                        "DELETE FROM UserVotes v WHERE v.begid = :begid AND v.seedid = :seedid AND v.userid = :uid")
+                        .setParameter("begid", begId)
+                        .setParameter("seedid", seedId)
+                        .setParameter("uid", uid)
+                        .executeUpdate();
+                // 删除提交记录
+                em.createQuery("DELETE FROM SubmitSeed s WHERE s.begid = :begid AND s.seedid = :seedid")
+                        .setParameter("begid", begId)
+                        .setParameter("seedid", seedId)
+                        .executeUpdate();
+            } catch (Exception ignored) {
+            }
+            // 删除种子和求种任务
+            Seed toDeleteSeed = em.find(Seed.class, seedId);
+            if (toDeleteSeed != null)
+                em.remove(toDeleteSeed);
+            BegInfo toDeleteBeg = em.find(BegInfo.class, begId);
+            if (toDeleteBeg != null)
+                em.remove(toDeleteBeg);
+            tx.commit();
+        }
+    }
 
-// @Test
-// void testSettleBeg() {
-// // 准备测试数据
-// String uid = em.createQuery("select u.userid from User u", String.class)
-// .setMaxResults(1)
-// .getSingleResult();
+    @TestFactory
+    Collection<DynamicTest> testAddPost() {
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class).getResultList();
+        if (userIds.isEmpty())
+            return Collections.emptyList();
+        String uid = userIds.get(0);
+        String postid = "test_post_" + System.currentTimeMillis();
+        Post post = new Post();
+        post.postid = postid;
+        post.postuserid = uid;
+        post.posttitle = "单元测试帖子";
+        post.postcontent = "内容";
+        post.posttime = new Date();
 
-// String begId = "test_beg_settle_" + UUID.randomUUID().toString();
-// String seedId = "test_seed_settle_" + UUID.randomUUID().toString();
+        return List.of(
+                DynamicTest.dynamicTest("AddPost success", () -> {
+                    try {
+                        int ret = db.AddPost(post);
+                        Assertions.assertEquals(0, ret, "AddPost 应返回0");
+                        Post inserted = em.find(Post.class, postid);
+                        Assertions.assertNotNull(inserted, "帖子应已插入");
+                    } finally {
+                        EntityTransaction tx = em.getTransaction();
+                        tx.begin();
+                        Post toDelete = em.find(Post.class, postid);
+                        if (toDelete != null)
+                            em.remove(toDelete);
+                        tx.commit();
+                    }
+                }),
+                DynamicTest.dynamicTest("AddPost duplicate", () -> {
+                    try {
+                        db.AddPost(post);
+                        int ret = db.AddPost(post);
+                        Assertions.assertEquals(1, ret, "重复插入应返回1");
+                    } finally {
+                        EntityTransaction tx = em.getTransaction();
+                        tx.begin();
+                        Post toDelete = em.find(Post.class, postid);
+                        if (toDelete != null)
+                            em.remove(toDelete);
+                        tx.commit();
+                    }
+                }),
+                DynamicTest.dynamicTest("AddPost user not exist", () -> {
+                    Post p2 = new Post();
+                    p2.postid = "test_post_" + (System.currentTimeMillis() + 1);
+                    p2.postuserid = "not_exist_user";
+                    p2.posttitle = "无效用户";
+                    p2.postcontent = "内容";
+                    p2.posttime = new Date();
+                    int ret = db.AddPost(p2);
+                    Assertions.assertEquals(2, ret, "用户不存在应返回2");
+                }),
+                DynamicTest.dynamicTest("AddPost invalid param", () -> {
+                    Assertions.assertEquals(2, db.AddPost(null));
+                    Post p3 = new Post();
+                    p3.postid = null;
+                    p3.postuserid = uid;
+                    Assertions.assertEquals(2, db.AddPost(p3));
+                    Post p4 = new Post();
+                    p4.postid = "";
+                    p4.postuserid = uid;
+                    Assertions.assertEquals(2, db.AddPost(p4));
+                }));
+    }
 
-// // 创建求种记录(已过期)
-// BegInfo beg = new BegInfo();
-// beg.begid = begId;
-// beg.begnumbers = 1;
-// beg.magic = 100;
-// Calendar cal = Calendar.getInstance();
-// cal.add(Calendar.DAY_OF_MONTH, -15); // 15天前
-// beg.endtime = cal.getTime();
-// beg.hasseed = false;
-// db.AddBegSeed(beg);
+    @TestFactory
+    Collection<DynamicTest> testUpdatePost() {
+        List<Post> existingPosts = em.createQuery("SELECT p FROM Post p", Post.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (existingPosts.isEmpty()) {
+            return Collections.emptyList();
+        }
 
-// // 创建种子并提交
-// Seed seed = new Seed();
-// seed.seedid = seedId;
-// seed.seeduserid = uid;
-// seed.title = "测试种子";
-// db.SubmitSeed(begId, seed);
+        Post originalPost = existingPosts.get(0);
+        String postId = originalPost.postid;
+        String originalTitle = originalPost.posttitle;
+        String originalContent = originalPost.postcontent;
+        String originalUserId = originalPost.postuserid;
+        Date originalTime = originalPost.posttime;
 
-// // 投票
-// db.VoteSeed(begId, seedId, uid);
+        return List.of(
+                DynamicTest.dynamicTest("UpdatePost success", () -> {
+                    try {
+                        Post update = new Post();
+                        update.postid = postId;
+                        update.postuserid = originalUserId;
+                        update.posttitle = originalTitle + "_updated";
+                        update.postcontent = originalContent + "_updated";
+                        update.posttime = originalTime;
 
-// // 执行结算
-// db.SettleBeg();
+                        int ret = db.UpdatePost(update);
+                        Assertions.assertEquals(0, ret, "UpdatePost应返回0");
 
-// // 验证结算结果
-// BegInfo settled = em.find(BegInfo.class, begId);
-// Assertions.assertTrue(settled.hasseed, "求种应已完成");
+                        em.clear();
+                        Post updated = em.find(Post.class, postId);
+                        Assertions.assertEquals(originalTitle + "_updated", updated.posttitle, "标题应已更新");
+                        Assertions.assertEquals(originalContent + "_updated", updated.postcontent, "内容应已更新");
+                    } finally {
+                        // 恢复原始数据
+                        EntityTransaction tx = em.getTransaction();
+                        tx.begin();
+                        Post toRestore = em.find(Post.class, postId);
+                        if (toRestore != null) {
+                            toRestore.posttitle = originalTitle;
+                            toRestore.postcontent = originalContent;
+                            toRestore.posttime = originalTime;
+                            em.merge(toRestore);
+                        }
+                        tx.commit();
+                    }
+                }),
+                DynamicTest.dynamicTest("UpdatePost not exist", () -> {
+                    Post notExist = new Post();
+                    notExist.postid = "not_exist_post";
+                    notExist.postuserid = originalUserId;
+                    notExist.posttitle = "不存在的帖子";
+                    notExist.postcontent = "测试内容";
+                    notExist.posttime = new Date();
 
-// UserPT userPT = em.find(UserPT.class, uid);
-// Assertions.assertTrue(userPT.magic >= 100, "用户应获得魔力值奖励");
-// }
+                    int ret = db.UpdatePost(notExist);
+                    Assertions.assertEquals(1, ret, "不存在的帖子应返回1");
+                }),
+                DynamicTest.dynamicTest("UpdatePost invalid param", () -> {
+                    Assertions.assertEquals(2, db.UpdatePost(null));
+                    Post invalid = new Post();
+                    invalid.postid = "";
+                    Assertions.assertEquals(2, db.UpdatePost(invalid));
 
-// @TestFactory
-// Collection<DynamicTest> testAddPost() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
-// String uid = userIds.get(0);
-// String postid = "test_post_" + UUID.randomUUID();
-// Post post = new Post();
-// post.postid = postid;
-// post.postuserid = uid;
-// post.posttitle = "单元测试帖子";
-// post.postcontent = "内容";
-// post.posttime = new Date();
+                    Post invalid2 = new Post();
+                    invalid2.postid = null;
+                    Assertions.assertEquals(2, db.UpdatePost(invalid2));
+                }));
+    }
 
-// return List.of(
-// DynamicTest.dynamicTest("AddPost success", () -> {
-// int ret = db.AddPost(post);
-// Assertions.assertEquals(0, ret, "AddPost 应返回0");
-// Post inserted = em.find(Post.class, postid);
-// Assertions.assertNotNull(inserted, "帖子应已插入");
-// }),
-// DynamicTest.dynamicTest("AddPost duplicate", () -> {
-// int ret = db.AddPost(post);
-// Assertions.assertEquals(1, ret, "重复插入应返回1");
-// }),
-// DynamicTest.dynamicTest("AddPost user not exist", () -> {
-// Post p2 = new Post();
-// p2.postid = "test_post_" + UUID.randomUUID();
-// p2.postuserid = "not_exist_user";
-// p2.posttitle = "无效用户";
-// p2.postcontent = "内容";
-// p2.posttime = new Date();
-// int ret = db.AddPost(p2);
-// Assertions.assertEquals(2, ret, "用户不存在应返回2");
-// }),
-// DynamicTest.dynamicTest("AddPost invalid param", () -> {
-// Assertions.assertEquals(2, db.AddPost(null));
-// Post p3 = new Post();
-// p3.postid = null;
-// p3.postuserid = uid;
-// Assertions.assertEquals(2, db.AddPost(p3));
-// Post p4 = new Post();
-// p4.postid = "";
-// p4.postuserid = uid;
-// Assertions.assertEquals(2, db.AddPost(p4));
-// }));
-// }
+    @TestFactory
+    Collection<DynamicTest> testDeletePost() {
+        List<Post> existingPosts = em.createQuery("SELECT p FROM Post p", Post.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (existingPosts.isEmpty()) {
+            return Collections.emptyList();
+        }
 
-// @TestFactory
-// Collection<DynamicTest> testUpdatePost() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
-// String uid = userIds.get(0);
-// String postid = "test_post_update_" + UUID.randomUUID();
-// Post post = new Post();
-// post.postid = postid;
-// post.postuserid = uid;
-// post.posttitle = "原始标题";
-// post.postcontent = "原始内容";
-// post.posttime = new Date();
-// db.AddPost(post);
+        Post postToDelete = existingPosts.get(0);
+        String postId = postToDelete.postid;
 
-// return List.of(
-// DynamicTest.dynamicTest("UpdatePost success", () -> {
-// Post update = new Post();
-// update.postid = postid;
-// update.postuserid = uid; // 实际实现会忽略此字段
-// update.posttitle = "新标题";
-// update.postcontent = "新内容";
-// update.posttime = post.posttime;
-// int ret = db.UpdatePost(update);
-// Assertions.assertEquals(0, ret, "UpdatePost 应返回0");
-// Post updated = em.find(Post.class, postid);
-// Assertions.assertEquals("新标题", updated.posttitle);
-// Assertions.assertEquals("新内容", updated.postcontent);
-// }),
-// DynamicTest.dynamicTest("UpdatePost not exist", () -> {
-// Post notExist = new Post();
-// notExist.postid = "not_exist_post";
-// notExist.postuserid = uid;
-// notExist.posttitle = "xxx";
-// notExist.postcontent = "xxx";
-// int ret = db.UpdatePost(notExist);
-// Assertions.assertEquals(1, ret, "不存在的帖子应返回1");
-// }),
-// DynamicTest.dynamicTest("UpdatePost invalid param", () -> {
-// Assertions.assertEquals(2, db.UpdatePost(null));
-// Post p2 = new Post();
-// p2.postid = null;
-// Assertions.assertEquals(2, db.UpdatePost(p2));
-// Post p3 = new Post();
-// p3.postid = "";
-// Assertions.assertEquals(2, db.UpdatePost(p3));
-// }));
-// }
+        return List.of(
+                DynamicTest.dynamicTest("DeletePost success", () -> {
+                    EntityTransaction tx = em.getTransaction();
+                    try {
+                        tx.begin();
+                        int ret = db.DeletePost(postId);
+                        Assertions.assertEquals(0, ret, "DeletePost 应返回0");
+                    } finally {
+                        tx.rollback();
+                    }
+                }),
 
-// @TestFactory
-// Collection<DynamicTest> testDeletePost() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
-// String uid = userIds.get(0);
-// String postid = "test_post_delete_" + UUID.randomUUID();
-// Post post = new Post();
-// post.postid = postid;
-// post.postuserid = uid;
-// post.posttitle = "待删除帖子";
-// post.postcontent = "内容";
-// post.posttime = new Date();
-// db.AddPost(post);
+                DynamicTest.dynamicTest("DeletePost not exist", () -> {
+                    int ret = db.DeletePost("not_exist_post");
+                    Assertions.assertEquals(1, ret, "不存在的帖子应返回1");
+                }),
 
-// return List.of(
-// DynamicTest.dynamicTest("DeletePost success", () -> {
-// int ret = db.DeletePost(postid);
-// Assertions.assertEquals(0, ret, "DeletePost 应返回0");
-// Post deleted = em.find(Post.class, postid);
-// Assertions.assertNull(deleted, "帖子应已删除");
-// }),
-// DynamicTest.dynamicTest("DeletePost not exist", () -> {
-// int ret = db.DeletePost("not_exist_post");
-// Assertions.assertEquals(1, ret, "不存在的帖子应返回1");
-// }),
-// DynamicTest.dynamicTest("DeletePost invalid param", () -> {
-// Assertions.assertEquals(2, db.DeletePost(null));
-// Assertions.assertEquals(2, db.DeletePost(""));
-// }));
-// }
-
-// @TestFactory
-// Collection<DynamicTest> testAddComment() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// List<String> postIds = em.createQuery("select p.postid from Post p",
-// String.class).getResultList();
-// if (userIds.isEmpty() || postIds.isEmpty()) {
-// return Collections.emptyList();
-// }
-// String comment = "单元测试评论";
-// return userIds.stream().flatMap(uid -> postIds.stream()
-// .map(pid -> DynamicTest.dynamicTest("AddComment for user=" + uid + ", post="
-// + pid, () -> {
-// int ret = db.AddComment(pid, uid, comment);
-// Assertions.assertEquals(0, ret, "AddComment 应返回0");
-// // 验证评论已插入
-// List<PostReply> replies = em.createQuery(
-// "SELECT r FROM PostReply r WHERE r.postid = :pid AND r.authorid = :uid AND
-// r.content = :c",
-// PostReply.class)
-// .setParameter("pid", pid)
-// .setParameter("uid", uid)
-// .setParameter("c", comment)
-// .getResultList();
-// Assertions.assertFalse(replies.isEmpty(), "评论应已插入");
-// }))).collect(Collectors.toList());
-// }
+                DynamicTest.dynamicTest("DeletePost invalid param", () -> {
+                    Assertions.assertEquals(2, db.DeletePost(null));
+                    Assertions.assertEquals(2, db.DeletePost(""));
+                }));
+    }
 
-// @TestFactory
-// Collection<DynamicTest> testDeleteComment() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// List<String> postIds = em.createQuery("select p.postid from Post p",
-// String.class).getResultList();
-// if (userIds.isEmpty() || postIds.isEmpty()) {
-// return Collections.emptyList();
-// }
-// String comment = "待删除评论";
-// List<DynamicTest> tests = new ArrayList<>();
-// for (String uid : userIds) {
-// for (String pid : postIds) {
-// // 插入评论
-// db.AddComment(pid, uid, comment);
-// // 查询评论id
-// List<PostReply> replies = em.createQuery(
-// "SELECT r FROM PostReply r WHERE r.postid = :pid AND r.authorid = :uid AND
-// r.content = :c",
-// PostReply.class)
-// .setParameter("pid", pid)
-// .setParameter("uid", uid)
-// .setParameter("c", comment)
-// .getResultList();
-// if (replies.isEmpty())
-// continue;
-// PostReply reply = replies.get(0);
-// String replyid = reply.replyid;
+    @TestFactory
+    Collection<DynamicTest> testAddComment() {
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class).getResultList();
+        List<String> postIds = em.createQuery("select p.postid from Post p", String.class).getResultList();
+        if (userIds.isEmpty() || postIds.isEmpty()) {
+            return Collections.emptyList();
+        }
+        String uid = userIds.get(0);
+        String pid = postIds.get(0);
+        String comment = "单元测试评论";
+        return List.of(
+                DynamicTest.dynamicTest("AddComment", () -> {
+                    String replyid = null;
+                    try {
+                        int ret = db.AddComment(pid, uid, comment);
+                        Assertions.assertEquals(0, ret, "AddComment 应返回0");
+                        List<PostReply> replies = em.createQuery(
+                                "SELECT r FROM PostReply r WHERE r.postid = :pid AND r.authorid = :uid AND r.content = :c",
+                                PostReply.class)
+                                .setParameter("pid", pid)
+                                .setParameter("uid", uid)
+                                .setParameter("c", comment)
+                                .getResultList();
+                        Assertions.assertFalse(replies.isEmpty(), "评论应已插入");
+                        replyid = replies.get(0).replyid;
+                    } finally {
+                        if (replyid != null) {
+                            EntityTransaction tx = em.getTransaction();
+                            tx.begin();
+                            PostReply toDelete = em.find(PostReply.class, replyid);
+                            if (toDelete != null)
+                                em.remove(toDelete);
+                            tx.commit();
+                        }
+                    }
+                }));
+    }
 
-// tests.add(DynamicTest.dynamicTest("DeleteComment for post=" + pid + ",
-// replyid=" + replyid, () -> {
-// int ret = db.DeleteComment(pid, replyid);
-// Assertions.assertEquals(0, ret, "DeleteComment 应返回0");
-// PostReply deleted = em.find(PostReply.class, replyid);
-// Assertions.assertNull(deleted, "评论应已删除");
-// }));
-// }
-// }
-// return tests;
-// }
+    @TestFactory
+    Collection<DynamicTest> testDeleteComment() {
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class).getResultList();
+        List<String> postIds = em.createQuery("select p.postid from Post p", String.class).getResultList();
+        if (userIds.isEmpty() || postIds.isEmpty()) {
+            return Collections.emptyList();
+        }
+        String uid = userIds.get(0);
+        String pid = postIds.get(0);
+        String comment = "待删除评论";
 
-// @TestFactory
-// Collection<DynamicTest> testExchangeMagicToUpload() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+        return List.of(
+                DynamicTest.dynamicTest("DeleteComment", () -> {
+                    String replyid = null;
+                    try {
+                        // 先确保评论存在
+                        EntityTransaction tx = em.getTransaction();
+                        tx.begin();
+                        PostReply reply = new PostReply();
+                        reply.replyid = "reply_" + System.currentTimeMillis();
+                        reply.postid = pid;
+                        reply.authorid = uid;
+                        reply.content = comment;
+                        reply.createdAt = new Date();
+                        em.persist(reply);
+                        tx.commit();
+                        replyid = reply.replyid;
 
-// String uid = userIds.get(0);
-// final UserPT testUserPT;
+                        // 执行删除测试
+                        int ret = db.DeleteComment(pid, replyid);
+                        Assertions.assertEquals(0, ret, "DeleteComment 应返回0");
 
-// // 确保用户有足够的魔力值用于测试
-// EntityTransaction tx = em.getTransaction();
-// tx.begin();
-// UserPT tempUserPT = em.find(UserPT.class, uid);
-// if (tempUserPT == null) {
-// tempUserPT = new UserPT();
-// tempUserPT.userid = uid;
-// tempUserPT.magic = 1000;
-// tempUserPT.upload = 1000;
-// tempUserPT.download = 1000;
-// em.persist(tempUserPT);
-// } else {
-// tempUserPT.magic = 1000;
-// em.merge(tempUserPT);
-// }
-// testUserPT = tempUserPT;
-// tx.commit();
+                        em.clear();
+                        PostReply deleted = em.find(PostReply.class, replyid);
+                        Assertions.assertNull(deleted, "评论应已删除");
+                    } finally {
+                        if (replyid != null) {
+                            try {
+                                EntityTransaction tx = em.getTransaction();
+                                if (!tx.isActive()) {
+                                    tx.begin();
+                                    PostReply toDelete = em.find(PostReply.class, replyid);
+                                    if (toDelete != null) {
+                                        em.remove(toDelete);
+                                    }
+                                    tx.commit();
+                                }
+                            } catch (Exception e) {
+                            }
+                        }
+                    }
+                }));
+    }
 
-// return List.of(
-// DynamicTest.dynamicTest("ExchangeMagicToUpload success", () -> {
-// int magic = 100;
-// long beforeUpload = testUserPT.upload;
-// int beforeMagic = testUserPT.magic;
+    @TestFactory
+    Collection<DynamicTest> testExchangeMagicToUpload() {
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class).getResultList();
+        if (userIds.isEmpty())
+            return Collections.emptyList();
 
-// boolean ret = db.ExchangeMagicToUpload(uid, magic);
-// Assertions.assertTrue(ret, "兑换上传量应成功");
+        String uid = userIds.get(0);
+        final UserPT testUserPT;
 
-// em.clear();
-// UserPT after = em.find(UserPT.class, uid);
-// Assertions.assertEquals(beforeMagic - magic, after.magic, "魔力值应减少");
-// Assertions.assertEquals(beforeUpload + magic, after.upload, "上传量应增加");
-// }),
+        EntityTransaction tx = em.getTransaction();
+        tx.begin();
+        UserPT tempUserPT = em.find(UserPT.class, uid);
 
-// DynamicTest.dynamicTest("ExchangeMagicToUpload insufficient magic", () -> {
-// boolean ret = db.ExchangeMagicToUpload(uid, 2000);
-// Assertions.assertFalse(ret, "魔力值不足时应返回false");
-// }),
+        if (tempUserPT == null) {
+            tempUserPT = new UserPT();
+            tempUserPT.userid = uid;
+            tempUserPT.magic = 1000;
+            tempUserPT.upload = 1000;
+            tempUserPT.download = 1000;
+            em.persist(tempUserPT);
+        } else {
+            tempUserPT.magic = 1000;
+            tempUserPT.upload = 1000;
+            em.merge(tempUserPT);
+        }
+        testUserPT = tempUserPT;
+        tx.commit();
 
-// DynamicTest.dynamicTest("ExchangeMagicToUpload invalid params", () -> {
-// Assertions.assertFalse(db.ExchangeMagicToUpload(null, 100));
-// Assertions.assertFalse(db.ExchangeMagicToUpload("", 100));
-// Assertions.assertFalse(db.ExchangeMagicToUpload(uid, 0));
-// Assertions.assertFalse(db.ExchangeMagicToUpload(uid, -1));
-// }));
-// }
+        return List.of(
+                DynamicTest.dynamicTest("ExchangeMagicToUpload success", () -> {
+                    try {
+                        int magic = 100;
+                        long beforeUpload = testUserPT.upload;
+                        int beforeMagic = testUserPT.magic;
 
-// @TestFactory
-// Collection<DynamicTest> testExchangeMagicToDownload() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+                        boolean ret = db.ExchangeMagicToUpload(uid, magic);
+                        Assertions.assertTrue(ret, "兑换上传量应成功");
 
-// String uid = userIds.get(0);
-// final UserPT testUserPT;
+                        em.clear();
+                        UserPT after = em.find(UserPT.class, uid);
+                        Assertions.assertEquals(beforeMagic - magic, after.magic, "魔力值应减少");
+                        Assertions.assertEquals(beforeUpload + magic, after.upload, "上传量应增加");
+                    } finally {
+                        EntityTransaction tx2 = em.getTransaction();
+                        tx2.begin();
+                        UserPT user = em.find(UserPT.class, uid);
+                        if (user != null) {
+                            user.magic = 0;
+                            user.upload = 0;
+                            em.merge(user);
+                        }
+                        tx2.commit();
+                    }
+                }),
 
-// // 确保用户有足够的魔力值和下载量用于测试
-// EntityTransaction tx = em.getTransaction();
-// tx.begin();
-// UserPT tempUserPT = em.find(UserPT.class, uid);
-// if (tempUserPT == null) {
-// tempUserPT = new UserPT();
-// tempUserPT.userid = uid;
-// tempUserPT.magic = 1000;
-// tempUserPT.upload = 1000;
-// tempUserPT.download = 1000;
-// em.persist(tempUserPT);
-// } else {
-// tempUserPT.magic = 1000;
-// em.merge(tempUserPT);
-// }
-// testUserPT = tempUserPT;
-// tx.commit();
+                DynamicTest.dynamicTest("ExchangeMagicToUpload insufficient magic", () -> {
+                    boolean ret = db.ExchangeMagicToUpload(uid, 2000);
+                    Assertions.assertFalse(ret, "魔力值不足时应返回false");
+                }),
 
-// return List.of(
-// DynamicTest.dynamicTest("ExchangeMagicToDownload success", () -> {
-// int magic = 100;
-// long beforeDownload = testUserPT.download;
-// int beforeMagic = testUserPT.magic;
+                DynamicTest.dynamicTest("ExchangeMagicToUpload invalid params", () -> {
+                    Assertions.assertFalse(db.ExchangeMagicToUpload(null, 100));
+                    Assertions.assertFalse(db.ExchangeMagicToUpload("", 100));
+                    Assertions.assertFalse(db.ExchangeMagicToUpload(uid, 0));
+                    Assertions.assertFalse(db.ExchangeMagicToUpload(uid, -1));
+                }));
+    }
 
-// boolean ret = db.ExchangeMagicToDownload(uid, magic);
-// Assertions.assertTrue(ret, "兑换下载量应成功");
+    @TestFactory
+    Collection<DynamicTest> testExchangeMagicToDownload() {
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class).getResultList();
+        if (userIds.isEmpty())
+            return Collections.emptyList();
 
-// em.clear();
-// UserPT after = em.find(UserPT.class, uid);
-// Assertions.assertEquals(beforeMagic - magic, after.magic, "魔力值应减少");
-// Assertions.assertEquals(beforeDownload - magic, after.download, "下载量应减少");
-// }),
+        String uid = userIds.get(0);
+        final UserPT testUserPT;
 
-// DynamicTest.dynamicTest("ExchangeMagicToDownload insufficient magic", () -> {
-// boolean ret = db.ExchangeMagicToDownload(uid, 2000);
-// Assertions.assertFalse(ret, "魔力值不足时应返回false");
-// }),
+        EntityTransaction tx = em.getTransaction();
+        tx.begin();
+        UserPT tempUserPT = em.find(UserPT.class, uid);
+        if (tempUserPT == null) {
+            tempUserPT = new UserPT();
+            tempUserPT.userid = uid;
+            tempUserPT.magic = 1000;
+            tempUserPT.upload = 1000;
+            tempUserPT.download = 1000;
+            em.persist(tempUserPT);
+        } else {
+            tempUserPT.magic = 1000;
+            tempUserPT.download = 1000;
+            em.merge(tempUserPT);
+        }
+        testUserPT = tempUserPT;
+        tx.commit();
 
-// DynamicTest.dynamicTest("ExchangeMagicToDownload invalid params", () -> {
-// Assertions.assertFalse(db.ExchangeMagicToDownload(null, 100));
-// Assertions.assertFalse(db.ExchangeMagicToDownload("", 100));
-// Assertions.assertFalse(db.ExchangeMagicToDownload(uid, 0));
-// Assertions.assertFalse(db.ExchangeMagicToDownload(uid, -1));
-// }));
-// }
+        return List.of(
+                DynamicTest.dynamicTest("ExchangeMagicToDownload success", () -> {
+                    try {
+                        int magic = 100;
+                        long beforeDownload = testUserPT.download;
+                        int beforeMagic = testUserPT.magic;
 
-// @TestFactory
-// Collection<DynamicTest> testExchangeMagicToVip() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+                        boolean ret = db.ExchangeMagicToDownload(uid, magic);
+                        Assertions.assertTrue(ret, "兑换下载量应成功");
 
-// String uid = userIds.get(0);
-// final UserPT testUserPT;
+                        em.clear();
+                        UserPT after = em.find(UserPT.class, uid);
+                        Assertions.assertEquals(beforeMagic - magic, after.magic, "魔力值应减少");
+                        Assertions.assertEquals(beforeDownload - magic, after.download, "下载量应减少");
+                    } finally {
+                        EntityTransaction tx2 = em.getTransaction();
+                        tx2.begin();
+                        UserPT user = em.find(UserPT.class, uid);
+                        if (user != null) {
+                            user.magic = 0;
+                            user.download = 0;
+                            em.merge(user);
+                        }
+                        tx2.commit();
+                    }
+                }),
 
-// // 确保用户有足够的魔力值用于测试
-// EntityTransaction tx = em.getTransaction();
-// tx.begin();
-// UserPT tempUserPT = em.find(UserPT.class, uid);
-// if (tempUserPT == null) {
-// tempUserPT = new UserPT();
-// tempUserPT.userid = uid;
-// tempUserPT.magic = 1000;
-// tempUserPT.upload = 1000;
-// tempUserPT.download = 1000;
-// em.persist(tempUserPT);
-// } else {
-// tempUserPT.magic = 1000;
-// em.merge(tempUserPT);
-// }
-// testUserPT = tempUserPT;
-// tx.commit();
+                DynamicTest.dynamicTest("ExchangeMagicToDownload insufficient magic", () -> {
+                    boolean ret = db.ExchangeMagicToDownload(uid, 2000);
+                    Assertions.assertFalse(ret, "魔力值不足时应返回false");
+                }),
 
-// return List.of(
-// DynamicTest.dynamicTest("ExchangeMagicToVip success", () -> {
-// int magic = 100;
-// int beforeVip = testUserPT.viptime;
-// int beforeMagic = testUserPT.magic;
+                DynamicTest.dynamicTest("ExchangeMagicToDownload invalid params", () -> {
+                    Assertions.assertFalse(db.ExchangeMagicToDownload(null, 100));
+                    Assertions.assertFalse(db.ExchangeMagicToDownload("", 100));
+                    Assertions.assertFalse(db.ExchangeMagicToDownload(uid, 0));
+                    Assertions.assertFalse(db.ExchangeMagicToDownload(uid, -1));
+                }));
+    }
 
-// boolean ret = db.ExchangeMagicToVip(uid, magic);
-// Assertions.assertTrue(ret, "兑换VIP次数应成功");
+    @TestFactory
+    Collection<DynamicTest> testExchangeMagicToVip() {
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class).getResultList();
+        if (userIds.isEmpty())
+            return Collections.emptyList();
 
-// em.clear();
-// UserPT after = em.find(UserPT.class, uid);
-// Assertions.assertEquals(beforeMagic - magic, after.magic, "魔力值应减少");
-// Assertions.assertEquals(beforeVip + magic, after.viptime, "VIP次数应增加");
-// }),
+        String uid = userIds.get(0);
+        final UserPT testUserPT;
 
-// DynamicTest.dynamicTest("ExchangeMagicToVip insufficient magic", () -> {
-// boolean ret = db.ExchangeMagicToVip(uid, 2000);
-// Assertions.assertFalse(ret, "魔力值不足时应返回false");
-// }),
+        EntityTransaction tx = em.getTransaction();
+        tx.begin();
+        UserPT tempUserPT = em.find(UserPT.class, uid);
+        if (tempUserPT == null) {
+            tempUserPT = new UserPT();
+            tempUserPT.userid = uid;
+            tempUserPT.magic = 1000;
+            tempUserPT.upload = 1000;
+            tempUserPT.download = 1000;
+            tempUserPT.viptime = 0;
+            em.persist(tempUserPT);
+        } else {
+            tempUserPT.magic = 1000;
+            tempUserPT.viptime = 0;
+            em.merge(tempUserPT);
+        }
+        testUserPT = tempUserPT;
+        tx.commit();
 
-// DynamicTest.dynamicTest("ExchangeMagicToVip invalid params", () -> {
-// Assertions.assertFalse(db.ExchangeMagicToVip(null, 100));
-// Assertions.assertFalse(db.ExchangeMagicToVip("", 100));
-// Assertions.assertFalse(db.ExchangeMagicToVip(uid, 0));
-// Assertions.assertFalse(db.ExchangeMagicToVip(uid, -1));
-// }));
-// }
+        return List.of(
+                DynamicTest.dynamicTest("ExchangeMagicToVip success", () -> {
+                    try {
+                        int magic = 100;
+                        int beforeVip = testUserPT.viptime;
+                        int beforeMagic = testUserPT.magic;
 
-// @TestFactory
-// Collection<DynamicTest> testUploadTransmitProfile() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+                        boolean ret = db.ExchangeMagicToVip(uid, magic);
+                        Assertions.assertTrue(ret, "兑换VIP次数应成功");
 
-// String uid = userIds.get(0);
-// String profileId = "test_profile_" + UUID.randomUUID();
-// Profile profile = new Profile();
-// profile.profileurl = profileId;
-// profile.userid = uid;
-// profile.magictogive = "100";
-// profile.uploadtogive = "1000";
-// profile.downloadtogive = "500";
+                        em.clear();
+                        UserPT after = em.find(UserPT.class, uid);
+                        Assertions.assertEquals(beforeMagic - magic, after.magic, "魔力值应减少");
+                        Assertions.assertEquals(beforeVip + magic, after.viptime, "VIP次数应增加");
+                    } finally {
+                        EntityTransaction tx2 = em.getTransaction();
+                        tx2.begin();
+                        UserPT user = em.find(UserPT.class, uid);
+                        if (user != null) {
+                            user.magic = 0;
+                            user.viptime = 0;
+                            em.merge(user);
+                        }
+                        tx2.commit();
+                    }
+                }),
 
-// return List.of(
-// DynamicTest.dynamicTest("UploadTransmitProfile success", () -> {
-// boolean ret = db.UploadTransmitProfile(profile);
-// Assertions.assertTrue(ret, "上传迁移信息应成功");
+                DynamicTest.dynamicTest("ExchangeMagicToVip insufficient magic", () -> {
+                    boolean ret = db.ExchangeMagicToVip(uid, 2000);
+                    Assertions.assertFalse(ret, "魔力值不足时应返回false");
+                }),
 
-// Profile inserted = em.find(Profile.class, profileId);
-// Assertions.assertNotNull(inserted, "迁移信息应已插入");
-// Assertions.assertFalse(inserted.exampass, "新迁移信息默认未审核");
-// Assertions.assertEquals("0", inserted.magicgived, "已发放魔力值应为0");
-// Assertions.assertEquals("0", inserted.uploadgived, "已发放上传量应为0");
-// }),
+                DynamicTest.dynamicTest("ExchangeMagicToVip invalid params", () -> {
+                    Assertions.assertFalse(db.ExchangeMagicToVip(null, 100));
+                    Assertions.assertFalse(db.ExchangeMagicToVip("", 100));
+                    Assertions.assertFalse(db.ExchangeMagicToVip(uid, 0));
+                    Assertions.assertFalse(db.ExchangeMagicToVip(uid, -1));
+                }));
+    }
 
-// DynamicTest.dynamicTest("UploadTransmitProfile duplicate", () -> {
-// boolean ret = db.UploadTransmitProfile(profile);
-// Assertions.assertFalse(ret, "重复上传应返回false");
-// }),
+    @TestFactory
+    Collection<DynamicTest> testUploadTransmitProfile() {
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class).getResultList();
+        if (userIds.isEmpty())
+            return Collections.emptyList();
 
-// DynamicTest.dynamicTest("UploadTransmitProfile invalid params", () -> {
-// Assertions.assertFalse(db.UploadTransmitProfile(null));
-// Profile invalidProfile = new Profile();
-// Assertions.assertFalse(db.UploadTransmitProfile(invalidProfile));
-// }));
-// }
+        String uid = userIds.get(0);
+        String profileId = "test_profile_" + System.currentTimeMillis();
+        Profile profile = new Profile();
+        profile.profileurl = profileId;
+        profile.userid = uid;
+        profile.magictogive = "100";
+        profile.uploadtogive = "1000";
+        profile.downloadtogive = "500";
+        profile.exampass = false;
+        profile.magicgived = "0";
+        profile.uploadgived = "0";
+        profile.applicationurl = "http://example.com/apply";
 
-// @TestFactory
-// Collection<DynamicTest> testGetTransmitProfile() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+        return List.of(
+                DynamicTest.dynamicTest("UploadTransmitProfile success", () -> {
+                    try {
+                        boolean ret = db.UploadTransmitProfile(profile);
+                        Assertions.assertTrue(ret, "上传迁移信息应成功");
 
-// String uid = userIds.get(0);
-// String profileId = "test_profile_get_" + UUID.randomUUID();
-// Profile profile = new Profile();
-// profile.profileurl = profileId;
-// profile.userid = uid;
-// profile.magictogive = "100";
-// profile.uploadtogive = "1000";
-// profile.exampass = false;
+                        Profile inserted = em.find(Profile.class, profileId);
+                        Assertions.assertNotNull(inserted, "迁移信息应已插入");
+                        Assertions.assertFalse(inserted.exampass, "新迁移信息默认未审核");
+                    } finally {
+                        EntityTransaction tx = em.getTransaction();
+                        tx.begin();
+                        Profile toDelete = em.find(Profile.class, profileId);
+                        if (toDelete != null)
+                            em.remove(toDelete);
+                        tx.commit();
+                    }
+                }),
 
-// // 先插入测试数据
-// EntityTransaction tx = em.getTransaction();
-// tx.begin();
-// em.persist(profile);
-// tx.commit();
+                DynamicTest.dynamicTest("UploadTransmitProfile duplicate", () -> {
+                    try {
+                        db.UploadTransmitProfile(profile);
+                        boolean ret = db.UploadTransmitProfile(profile);
+                        Assertions.assertFalse(ret, "重复上传应返回false");
+                    } finally {
+                        EntityTransaction tx = em.getTransaction();
+                        tx.begin();
+                        Profile toDelete = em.find(Profile.class, profileId);
+                        if (toDelete != null)
+                            em.remove(toDelete);
+                        tx.commit();
+                    }
+                }),
 
-// return List.of(
-// DynamicTest.dynamicTest("GetTransmitProfile success", () -> {
-// Profile ret = db.GetTransmitProfile(profileId);
-// Assertions.assertNotNull(ret, "应成功获取迁移信息");
-// Assertions.assertEquals(uid, ret.userid, "用户ID应匹配");
-// Assertions.assertEquals("100", ret.magictogive, "待发放魔力值应匹配");
-// Assertions.assertEquals("1000", ret.uploadtogive, "待发放上传量应匹配");
-// }),
+                DynamicTest.dynamicTest("UploadTransmitProfile invalid params", () -> {
+                    Assertions.assertFalse(db.UploadTransmitProfile(null));
+                    Profile invalidProfile = new Profile();
+                    Assertions.assertFalse(db.UploadTransmitProfile(invalidProfile));
+                }));
+    }
 
-// DynamicTest.dynamicTest("GetTransmitProfile not exist", () -> {
-// Profile ret = db.GetTransmitProfile("not_exist_profile");
-// Assertions.assertNull(ret, "不存在的迁移信息应返回null");
-// }),
+    @TestFactory
+    Collection<DynamicTest> testGetTransmitProfile() {
+        // 获取现有的迁移信息记录
+        List<Profile> existingProfiles = em.createQuery(
+                "SELECT p FROM Profile p", Profile.class)
+                .setMaxResults(1)
+                .getResultList();
+        if (existingProfiles.isEmpty())
+            return Collections.emptyList();
 
-// DynamicTest.dynamicTest("GetTransmitProfile invalid params", () -> {
-// Assertions.assertNull(db.GetTransmitProfile(null));
-// Assertions.assertNull(db.GetTransmitProfile(""));
-// }));
-// }
+        Profile profile = existingProfiles.get(0);
+        String profileId = profile.profileurl;
 
-// @TestFactory
-// Collection<DynamicTest> testExamTransmitProfile() {
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class).getResultList();
-// if (userIds.isEmpty())
-// return Collections.emptyList();
+        return List.of(
+                DynamicTest.dynamicTest("GetTransmitProfile success", () -> {
+                    Profile ret = db.GetTransmitProfile(profileId);
+                    Assertions.assertNotNull(ret, "应成功获取迁移信息");
+                }),
 
-// String uid = userIds.get(0);
-// String profileId = "test_profile_exam_" + UUID.randomUUID();
-// Profile profile = new Profile();
-// profile.profileurl = profileId;
-// profile.userid = uid;
-// profile.magictogive = "100";
-// profile.uploadtogive = "1000";
-// profile.exampass = false;
+                DynamicTest.dynamicTest("GetTransmitProfile not exist", () -> {
+                    Profile ret = db.GetTransmitProfile("not_exist_profile");
+                    Assertions.assertNull(ret, "不存在的迁移信息应返回null");
+                }),
 
-// // 先插入测试数据
-// EntityTransaction tx = em.getTransaction();
-// tx.begin();
-// em.persist(profile);
-// UserPT userPT = em.find(UserPT.class, uid);
-// if (userPT == null) {
-// userPT = new UserPT();
-// userPT.userid = uid;
-// userPT.magic = 0;
-// userPT.upload = 0;
-// em.persist(userPT);
-// }
-// tx.commit();
+                DynamicTest.dynamicTest("GetTransmitProfile invalid params", () -> {
+                    Assertions.assertNull(db.GetTransmitProfile(null));
+                    Assertions.assertNull(db.GetTransmitProfile(""));
+                }));
+    }
 
-// return List.of(
-// DynamicTest.dynamicTest("ExamTransmitProfile approve", () -> {
-// boolean ret = db.ExamTransmitProfile(profileId, true);
-// Assertions.assertTrue(ret, "审核通过应成功");
+    @TestFactory
+    Collection<DynamicTest> testExamTransmitProfile() {
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class).getResultList();
+        if (userIds.isEmpty())
+            return Collections.emptyList();
 
-// em.clear();
-// Profile examined = em.find(Profile.class, profileId);
-// Assertions.assertTrue(examined.exampass, "迁移信息应已审核通过");
-// Assertions.assertEquals("100", examined.magicgived, "应记录已发放魔力值");
-// Assertions.assertEquals("1000", examined.uploadgived, "应记录已发放上传量");
+        String uid = userIds.get(0);
+        String profileId = "test_profile_exam_" + System.currentTimeMillis();
+        Profile profile = new Profile();
+        profile.profileurl = profileId;
+        profile.userid = uid;
+        profile.magictogive = "100";
+        profile.uploadtogive = "1000";
+        profile.exampass = false;
+        profile.magicgived = "0";
+        profile.uploadgived = "0";
+        profile.applicationurl = "http://example.com/apply";
 
-// UserPT afterPT = em.find(UserPT.class, uid);
-// Assertions.assertEquals(100, afterPT.magic, "用户魔力值应增加");
-// Assertions.assertEquals(1000, afterPT.upload, "用户上传量应增加");
-// }),
+        EntityTransaction tx = em.getTransaction();
+        tx.begin();
+        em.persist(profile);
+        UserPT userPT = em.find(UserPT.class, uid);
+        if (userPT == null) {
+            userPT = new UserPT();
+            userPT.userid = uid;
+            userPT.magic = 0;
+            userPT.upload = 0;
+            em.persist(userPT);
+        } else {
+            userPT.magic = 0;
+            userPT.upload = 0;
+            em.merge(userPT);
+        }
+        tx.commit();
 
-// DynamicTest.dynamicTest("ExamTransmitProfile reject", () -> {
-// String rejectId = "test_profile_reject_" + UUID.randomUUID();
-// Profile rejectProfile = new Profile();
-// rejectProfile.profileurl = rejectId;
-// rejectProfile.userid = uid;
-// rejectProfile.magictogive = "100";
-// rejectProfile.uploadtogive = "1000";
-// rejectProfile.exampass = false;
+        return List.of(
+                DynamicTest.dynamicTest("ExamTransmitProfile approve", () -> {
+                    try {
+                        boolean ret = db.ExamTransmitProfile(profileId, true);
+                        Assertions.assertTrue(ret, "审核通过应成功");
+                    } finally {
+                        EntityTransaction tx2 = em.getTransaction();
+                        tx2.begin();
+                        UserPT user = em.find(UserPT.class, uid);
+                        if (user != null) {
+                            user.magic = 0;
+                            user.upload = 0;
+                            em.merge(user);
+                        }
+                        Profile toDelete = em.find(Profile.class, profileId);
+                        if (toDelete != null)
+                            em.remove(toDelete);
+                        tx2.commit();
+                    }
+                }),
 
-// tx.begin();
-// em.persist(rejectProfile);
-// tx.commit();
+                DynamicTest.dynamicTest("ExamTransmitProfile reject", () -> {
+                    String rejectId = "test_profile_reject_" + System.currentTimeMillis();
+                    Profile rejectProfile = new Profile();
+                    rejectProfile.profileurl = rejectId;
+                    rejectProfile.userid = uid;
+                    rejectProfile.magictogive = "100";
+                    rejectProfile.uploadtogive = "1000";
+                    rejectProfile.magicgived = "0";
+                    rejectProfile.uploadgived = "0";
+                    rejectProfile.exampass = false;
+                    rejectProfile.applicationurl = "http://example.com/apply";
 
-// boolean ret = db.ExamTransmitProfile(rejectId, false);
-// Assertions.assertTrue(ret, "审核拒绝应成功");
+                    EntityTransaction tx3 = em.getTransaction();
+                    tx3.begin();
+                    em.persist(rejectProfile);
+                    tx3.commit();
 
-// em.clear();
-// Profile examined = em.find(Profile.class, rejectId);
-// Assertions.assertFalse(examined.exampass, "迁移信息应已审核拒绝");
-// Assertions.assertEquals("0", examined.magicgived, "不应发放魔力值");
-// Assertions.assertEquals("0", examined.uploadgived, "不应发放上传量");
-// }),
+                    try {
+                        boolean ret = db.ExamTransmitProfile(rejectId, false);
+                        Assertions.assertTrue(ret, "审核拒绝应成功");
+                    } finally {
+                        EntityTransaction tx4 = em.getTransaction();
+                        tx4.begin();
+                        Profile toDelete = em.find(Profile.class, rejectId);
+                        if (toDelete != null)
+                            em.remove(toDelete);
+                        tx4.commit();
+                    }
+                }),
 
-// DynamicTest.dynamicTest("ExamTransmitProfile invalid params", () -> {
-// Assertions.assertFalse(db.ExamTransmitProfile(null, true));
-// Assertions.assertFalse(db.ExamTransmitProfile("", true));
-// Assertions.assertFalse(db.ExamTransmitProfile("not_exist_profile", true));
-// }));
-// }
+                DynamicTest.dynamicTest("ExamTransmitProfile invalid params", () -> {
+                    Assertions.assertFalse(db.ExamTransmitProfile(null, true));
+                    Assertions.assertFalse(db.ExamTransmitProfile("", true));
+                    Assertions.assertFalse(db.ExamTransmitProfile("not_exist_profile", true));
+                }));
+    }
 
-// @Test
-// void testGetTransmitProfileList() {
-// // 清空已有数据
-// em.getTransaction().begin();
-// em.createQuery("DELETE FROM Profile").executeUpdate();
-// em.getTransaction().commit();
+    @Test
+    void testGetTransmitProfileList() {
+        em.getTransaction().begin();
+        em.createQuery("DELETE FROM Profile").executeUpdate();
+        em.getTransaction().commit();
 
-// // 插入测试数据
-// List<String> userIds = em.createQuery("select u.userid from User u",
-// String.class)
-// .setMaxResults(3)
-// .getResultList();
-// if (userIds.isEmpty()) {
-// return;
-// }
+        List<String> userIds = em.createQuery("select u.userid from User u", String.class)
+                .setMaxResults(3)
+                .getResultList();
+        if (userIds.isEmpty()) {
+            return;
+        }
 
-// EntityTransaction tx = em.getTransaction();
-// tx.begin();
-// for (int i = 0; i < userIds.size(); i++) {
-// Profile profile = new Profile();
-// profile.profileurl = "test_profile_list_" + i;
-// profile.userid = userIds.get(i);
-// profile.magictogive = String.valueOf(100 * (i + 1));
-// profile.uploadtogive = String.valueOf(1000 * (i + 1));
-// profile.exampass = false;
-// em.persist(profile);
-// }
-// tx.commit();
+        EntityTransaction tx = em.getTransaction();
+        tx.begin();
+        for (int i = 0; i < userIds.size(); i++) {
+            Profile profile = new Profile();
+            profile.profileurl = "test_profile_list_" + i + "_" + System.currentTimeMillis();
+            profile.userid = userIds.get(i);
+            profile.magictogive = String.valueOf(100 * (i + 1));
+            profile.uploadtogive = String.valueOf(1000 * (i + 1));
+            profile.exampass = false;
+            profile.magicgived = "0";
+            profile.uploadgived = "0";
+            profile.applicationurl = "http://example.com/apply";
+            em.persist(profile);
+        }
+        tx.commit();
 
-// // 测试获取列表
-// Profile[] profiles = db.GetTransmitProfileList();
-// Assertions.assertEquals(userIds.size(), profiles.length, "应返回所有迁移申请");
-// Arrays.stream(profiles)
-// .forEach(p ->
-// Assertions.assertTrue(p.profileurl.startsWith("test_profile_list_"),
-// "应为测试数据"));
-// }
-// }
+        try {
+            Profile[] profiles = db.GetTransmitProfileList();
+            Assertions.assertEquals(userIds.size(), profiles.length, "应返回所有迁移申请");
+            Arrays.stream(profiles)
+                    .forEach(p -> Assertions.assertTrue(p.profileurl.startsWith("test_profile_list_"), "应为测试数据"));
+        } finally {
+            EntityTransaction tx2 = em.getTransaction();
+            tx2.begin();
+            em.createQuery("DELETE FROM Profile p WHERE p.profileurl LIKE 'test_profile_list_%'").executeUpdate();
+            tx2.commit();
+        }
+    }
+}
\ No newline at end of file
