diff --git a/src/main/java/database/Database1.java b/src/main/java/database/Database1.java
index 0689e69..580f9e8 100644
--- a/src/main/java/database/Database1.java
+++ b/src/main/java/database/Database1.java
@@ -1,25 +1,36 @@
 package database;
 
+import java.util.Calendar;
+import java.util.UUID;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Date;
 
 import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
 import javax.persistence.PersistenceContext;
 import javax.persistence.Persistence;
 
 import com.querydsl.jpa.impl.JPAQuery;
+import com.querydsl.core.Tuple;
 
 import entity.BegInfo;
 import entity.Notice;
 import entity.Post;
+import entity.PostReply;
 import entity.Profile;
+import entity.QBegInfo;
 import entity.QNotice;
+import entity.QProfile;
 import entity.QSeed;
+import entity.QSubmitSeed;
 import entity.QUser;
 import entity.QUserPT;
 import entity.QUserStar;
 import entity.QUserInvite;
+import entity.QUserVotes;
 import entity.QPost;
 import entity.Seed;
 import entity.User;
@@ -29,10 +40,14 @@
 import entity.PostReply;
 import entity.QPostReply;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class Database1 implements DataManagerInterface {
     @PersistenceContext
     private final EntityManager entitymanager;
-
+    private static final Logger logger = LoggerFactory.getLogger(Database1.class);
+    private EntityManagerFactory emf;
     public Database1() {
         config cfg = new config();
         Map<String,Object> props = new HashMap<>();
@@ -41,6 +56,7 @@
         props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
         props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
         this.entitymanager = Persistence.createEntityManagerFactory("myPersistenceUnit", props).createEntityManager();
+        // this.emf=entitymanager;
     }
     @Override
     public String LoginUser(User userinfo){
@@ -507,98 +523,904 @@
     }
 
     @Override
-    public int AddBegSeed(BegInfo info){
-        return 0;
+    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;
+        }
+
+        EntityTransaction tx = null;
+
+        try {
+            tx = entitymanager.getTransaction();
+            tx.begin();
+
+            // 检查是否重复
+            BegInfo existingBeg = entitymanager.find(BegInfo.class, info.begid);
+            if (existingBeg != null) {
+                logger.warn("BegSeed with ID {} already exists", info.begid);
+                return 1;
+            }
+
+            // 设置默认值
+            if (info.endtime == null) {
+                // 设置默认14天截止期
+                Calendar calendar = Calendar.getInstance();
+                calendar.add(Calendar.DAY_OF_MONTH, 14);
+                info.endtime = calendar.getTime();
+            }
+            info.hasseed = 0;
+
+            // 保存新的求种信息
+            entitymanager.persist(info);
+            tx.commit();
+
+            logger.info("Successfully added new BegSeed with ID: {}", info.begid);
+            return 0;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error adding BegSeed: {}", e.getMessage());
+            return 2;
+        }
     }
 
     @Override
-    public int UpdateBegSeed(BegInfo info){
-        return 0;
+    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;
+        }
+
+        EntityTransaction tx = null;
+
+        try {
+            tx = entitymanager.getTransaction();
+            tx.begin();
+
+            // 检查是否存在
+            BegInfo existingBeg = entitymanager.find(BegInfo.class, info.begid);
+            if (existingBeg == null) {
+                logger.warn("BegSeed with ID {} does not exist", info.begid);
+                return 1;
+            }
+
+            // 保持原有值不变的字段
+            info.hasseed = existingBeg.hasseed;
+            if (info.endtime == null) {
+                info.endtime = existingBeg.endtime;
+            }
+
+            // 更新求种信息
+            entitymanager.merge(info);
+            tx.commit();
+
+            logger.info("Successfully updated BegSeed with ID: {}", info.begid);
+            return 0;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error updating BegSeed: {}", e.getMessage());
+            return 2;
+        }
     }
 
     @Override
-    public int DeleteBegSeed(String begid){
-        return 0;
+    public int DeleteBegSeed(String begid) {
+        if (begid == null || begid.isEmpty()) {
+            logger.warn("Invalid parameter: begid is null or empty");
+            return 2;
+        }
+
+        EntityTransaction tx = null;
+
+        try {
+            tx = entitymanager.getTransaction();
+            tx.begin();
+
+            // 查找要删除的求种信息
+            BegInfo begInfo = entitymanager.find(BegInfo.class, begid);
+            if (begInfo == null) {
+                logger.warn("BegSeed with ID {} does not exist", begid);
+                tx.rollback();
+                return 1;
+            }
+
+            // 删除求种信息
+            entitymanager.remove(begInfo);
+            tx.commit();
+
+            logger.info("Successfully deleted BegSeed with ID: {}", begid);
+            return 0;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error deleting BegSeed: {}", e.getMessage());
+            return 2;
+        }
     }
 
     @Override
-    public int VoteSeed(String begId, String seedId, String userId){
-        return 0;
+    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;
+        }
+
+        EntityTransaction tx = null;
+
+        try {
+            tx = entitymanager.getTransaction();
+            tx.begin();
+
+            // 检查求种信息是否存在
+            BegInfo begInfo = entitymanager.find(BegInfo.class, begId);
+            if (begInfo == null) {
+                logger.warn("BegSeed with ID {} does not exist", begId);
+                return 2;
+            }
+
+            // 检查用户是否已投票
+            Long voteCount = new JPAQuery<>(entitymanager)
+                    .select(QUserVotes.userVotes.count())
+                    .from(QUserVotes.userVotes)
+                    .where(QUserVotes.userVotes.id.eq(new entity.UserVotesId(userId, begId, seedId)))
+                    .fetchOne();
+
+            if (voteCount != null && voteCount > 0) {
+                logger.warn("User {} has already voted for seed {} in beg {}", userId, seedId, begId);
+                return 1;
+            }
+
+            // 创建新的投票记录
+            entitymanager.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();
+
+            // 更新SubmitSeed表中的投票数
+            entitymanager.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();
+
+            tx.commit();
+            logger.info("Successfully added vote from user {} for seed {} in beg {}", userId, seedId, begId);
+            return 0;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error voting for seed: {}", e.getMessage());
+            return 2;
+        }
     }
 
     @Override
-    public int SubmitSeed(String begid,Seed seed){
-        return 0;
+    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;
+        }
+
+        EntityTransaction tx = null;
+
+        try {
+            tx = entitymanager.getTransaction();
+            tx.begin();
+
+            // 检查求种信息是否存在
+            BegInfo begInfo = entitymanager.find(BegInfo.class, begid);
+            if (begInfo == null) {
+                logger.warn("BegSeed with ID {} does not exist", begid);
+                return 2;
+            }
+
+            // 检查种子是否已提交过
+            QSubmitSeed ss = QSubmitSeed.submitSeed;
+            Long submitCount = new JPAQuery<>(entitymanager)
+                    .select(ss.count())
+                    .from(ss)
+                    .where(ss.begInfo.begid.eq(begid))
+                    .where(ss.seed.seedid.eq(seed.seedid))
+                    .fetchOne();
+
+            if (submitCount > 0) {
+                logger.warn("Seed {} has already been submitted for beg {}", seed.seedid,
+                        begid);
+                return 1;
+            }
+
+            // 保存种子信息（如果不存在）
+            if (entitymanager.find(Seed.class, seed.seedid) == null) {
+                entitymanager.persist(seed);
+            }
+
+            // 创建提交记录
+            entitymanager.createNativeQuery("INSERT INTO SubmitSeed (beg_id, seed_id, votes) VALUES (?, ?, 0)")
+                    .setParameter(1, begid)
+                    .setParameter(2, seed.seedid)
+                    .executeUpdate();
+
+            tx.commit();
+            logger.info("Successfully submitted seed {} for beg {}", seed.seedid, begid);
+            return 0;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error submitting seed: {}", e.getMessage());
+            return 2;
+        }
     }
 
     @Override
-    public void SettleBeg(){
-        
+    public void SettleBeg() {
+        EntityTransaction tx = null;
+
+        try {
+            tx = entitymanager.getTransaction();
+            tx.begin();
+
+            // 1. 获取所有已过期且未完成的求种信息
+            QBegInfo b = QBegInfo.begInfo;
+            List<BegInfo> expiredBegs = new JPAQuery<>(entitymanager)
+                    .select(b)
+                    .from(b)
+                    .where(b.endtime.loe(new Date())
+                            .and(b.hasseed.eq(0)))
+                    .fetch();
+
+            for (BegInfo beg : expiredBegs) {
+                // 2. 查找投票最多的提交任务
+                QSubmitSeed ss = QSubmitSeed.submitSeed;
+                Tuple topSubmission = new JPAQuery<>(entitymanager)
+                        .select(ss.seed.seedid, ss.votes)
+                        .from(ss)
+                        .where(ss.begInfo.begid.eq(beg.begid))
+                        .orderBy(ss.votes.desc())
+                        .limit(1)
+                        .fetchOne();
+
+                if (topSubmission != null && topSubmission.get(ss.votes) > 0) {
+                    String seedId = topSubmission.get(ss.seed.seedid);
+
+                    // 3. 获取上传者ID
+                    QSeed s = QSeed.seed;
+                    String ownerId = new JPAQuery<>(entitymanager)
+                            .select(s.seeduserid)
+                            .from(s)
+                            .where(s.seedid.eq(seedId))
+                            .fetchOne();
+
+                    // 4. 获取上传者的PT信息并更新魔力值
+                    UserPT ownerPT = entitymanager.find(UserPT.class, ownerId);
+                    if (ownerPT != null) {
+                        // 5. 发放奖励
+                        ownerPT.magic += beg.magic;
+                        entitymanager.merge(ownerPT);
+
+                        // 6. 更新求种状态
+                        beg.hasseed = 1;
+                        entitymanager.merge(beg);
+
+                        logger.info("Reward {} magic points awarded to user {} for beg {}",
+                                beg.magic, ownerId, beg.begid);
+                    }
+                }
+            }
+
+            tx.commit();
+            logger.info("Successfully settled {} expired beg requests",
+                    expiredBegs.size());
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error settling beg requests: {}", e.getMessage(), e);
+        }
     }
 
     @Override
-    public int AddPost(Post post){
-        return 0;
+    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;
+        }
+
+        EntityTransaction tx = null;
+
+        try {
+            tx = entitymanager.getTransaction();
+            tx.begin();
+
+            // 检查是否重复
+            Post existingPost = entitymanager.find(Post.class, post.postid);
+            if (existingPost != null) {
+                logger.warn("Post with ID {} already exists", post.postid);
+                return 1;
+            }
+
+            // 检查用户是否存在
+            User user = entitymanager.find(User.class, post.postuserid);
+            if (user == null) {
+                logger.warn("User with ID {} does not exist", post.postuserid);
+                return 2;
+            }
+
+            // 设置初始值
+            if (post.posttime == null) {
+                post.posttime = new Date();
+            }
+            post.replytime = 0;
+            post.readtime = 0;
+
+            // 保存帖子
+            entitymanager.persist(post);
+            tx.commit();
+
+            logger.info("Successfully added new post with ID: {}", post.postid);
+            return 0;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error adding post: {}", e.getMessage());
+            return 2;
+        }
     }
 
     @Override
-    public int UpdatePost(Post post){
-        return 0;
+    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;
+        }
+
+        EntityTransaction tx = null;
+
+        try {
+            tx = entitymanager.getTransaction();
+            tx.begin();
+
+            // 检查帖子是否存在
+            Post existingPost = entitymanager.find(Post.class, post.postid);
+            if (existingPost == null) {
+                logger.warn("Post with ID {} does not exist", post.postid);
+                return 1;
+            }
+
+            // 保持原有不可修改的字段
+            post.postuserid = existingPost.postuserid;
+            post.posttime = existingPost.posttime;
+            post.replytime = existingPost.replytime;
+            post.readtime = existingPost.readtime;
+
+            // 更新帖子
+            entitymanager.merge(post);
+            tx.commit();
+
+            logger.info("Successfully updated post with ID: {}", post.postid);
+            return 0;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("Error updating post: {}", e.getMessage());
+            return 2;
+        }
     }
 
     @Override
     public int DeletePost(String postid){
-        return 0;
+        if (postid == null || postid.isEmpty()) {
+            logger.warn("Invalid parameter: postid is null or empty");
+            return 2;
+        }
+
+        EntityManager em = null;
+        EntityTransaction tx = null;
+
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
+
+            // 查找要删除的帖子
+            Post post = em.find(Post.class, postid);
+            if (post == null) {
+                logger.warn("Post with ID {} does not exist", postid);
+                tx.rollback();
+                return 1;
+            }
+
+            // 删除帖子(由于设置了级联删除，相关的回复会自动删除)
+            em.remove(post);
+            tx.commit();
+
+            logger.info("Successfully deleted post with ID: {}", postid);
+            return 0;
+
+        } 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();
+            }
+        }
     }
 
     @Override
     public int AddComment(String postid, String userid, String comment){
-        return 0;
+        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;
+        }
+
+        EntityManager em = null;
+        EntityTransaction tx = null;
+
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
+
+            // 检查帖子是否存在
+            Post post = em.find(Post.class, postid);
+            if (post == null) {
+                logger.warn("Post with ID {} does not exist", postid);
+                return 1;
+            }
+
+            // 检查评论用户是否存在
+            User user = em.find(User.class, userid);
+            if (user == null) {
+                logger.warn("User with ID {} does not exist", userid);
+                return 1;
+            }
+
+            // 创建新的评论
+            PostReply reply = new PostReply();
+            reply.replyid = UUID.randomUUID().toString();
+            reply.postid = postid;
+            reply.authorid = userid;
+            reply.content = comment;
+            reply.createdAt = new Date();
+
+            // 保存评论
+            em.persist(reply);
+
+            // 更新帖子的回复数
+            post.replytime += 1;
+            em.merge(post);
+
+            tx.commit();
+
+            logger.info("Successfully added comment by user {} to post {}, reply ID: {}",
+                    userid, postid, reply.replyid);
+            return 0;
+
+        } 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();
+            }
+        }
     }
 
     @Override
     public int DeleteComment(String postid,String commentid){
-        return 0;
+        if (postid == null || postid.isEmpty() || commentid == null || commentid.isEmpty()) {
+            logger.warn("Invalid parameters: postid or commentid is null or empty");
+            return 2;
+        }
+
+        EntityManager em = null;
+        EntityTransaction tx = null;
+
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
+
+            // 检查帖子是否存在
+            Post post = em.find(Post.class, postid);
+            if (post == null) {
+                logger.warn("Post with ID {} does not exist", postid);
+                return 1;
+            }
+
+            // 检查评论是否存在且属于该帖子
+            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;
+            }
+
+            // 删除评论
+            em.remove(reply);
+
+            // 更新帖子的回复数
+            post.replytime = Math.max(0, post.replytime - 1);
+            em.merge(post);
+
+            tx.commit();
+
+            logger.info("Successfully deleted comment {} from post {}", commentid, postid);
+            return 0;
+
+        } 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();
+            }
+        }
     }
 
     @Override
     public boolean ExchangeMagicToUpload(String userid,int magic)//将魔力值兑换为上传量，返回状态：0 success，1 不存在,2其他原因
     {
-        return true;
+        if (userid == null || userid.isEmpty() || magic <= 0) {
+            logger.warn("参数无效: userid为空或magic <= 0");
+            return false;
+        }
+
+        EntityManager em = null;
+        EntityTransaction tx = null;
+
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
+
+            UserPT userPT = em.find(UserPT.class, userid);
+            if (userPT == null) {
+                logger.warn("未找到用户 {} 的PT信息", userid);
+                return false;
+            }
+
+            if (userPT.magic < magic) {
+                logger.warn("用户 {} 的魔力值不足", userid);
+                return false;
+            }
+
+            // 1:1兑换，直接加上魔力值（假设单位是MB）
+            userPT.magic -= magic;
+            userPT.upload += magic;
+
+            // 更新分享率
+            if (userPT.download > 0) {
+                userPT.share = (double) userPT.upload / userPT.download;
+            }
+
+            em.merge(userPT);
+            tx.commit();
+
+            logger.info("用户 {} 成功将 {} 点魔力值兑换为 {}MB 上传量", userid, magic, magic);
+            return true;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("魔力值兑换上传量时发生错误: {}", e.getMessage());
+            return false;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
     }
     
     @Override
     public boolean ExchangeMagicToDownload(String userid,int magic)
     {
-        return true;
+        if (userid == null || userid.isEmpty() || magic <= 0) {
+            logger.warn("参数无效: userid为空或magic <= 0");
+            return false;
+        }
+
+        EntityManager em = null;
+        EntityTransaction tx = null;
+
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
+
+            UserPT userPT = em.find(UserPT.class, userid);
+            if (userPT == null) {
+                logger.warn("未找到用户 {} 的PT信息", userid);
+                return false;
+            }
+
+            if (userPT.magic < magic) {
+                logger.warn("用户 {} 的魔力值不足", userid);
+                return false;
+            }
+
+            // 1:1兑换，直接减去魔力值对应的下载量（假设单位是MB）
+            userPT.magic -= magic;
+            userPT.download = Math.max(0, userPT.download - magic);
+
+            // 更新分享率
+            if (userPT.download > 0) {
+                userPT.share = (double) userPT.upload / userPT.download;
+            }
+
+            em.merge(userPT);
+            tx.commit();
+
+            logger.info("用户 {} 成功将 {} 点魔力值兑换为 {}MB 下载量减免", userid, magic, magic);
+            return true;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("魔力值兑换下载量时发生错误: {}", e.getMessage());
+            return false;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
     }//将魔力值兑换为下载量，返回状态：0 success，1 不存在,2其他原因
 
     @Override
     public boolean ExchangeMagicToVip(String userid,int magic){
-        return true;
+        if (userid == null || userid.isEmpty() || magic <= 0) {
+            logger.warn("参数无效: userid为空或magic <= 0");
+            return false;
+        }
+
+        EntityManager em = null;
+        EntityTransaction tx = null;
+
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
+
+            UserPT userPT = em.find(UserPT.class, userid);
+            if (userPT == null) {
+                logger.warn("未找到用户 {} 的PT信息", userid);
+                return false;
+            }
+
+            if (userPT.magic < magic) {
+                logger.warn("用户 {} 的魔力值不足", userid);
+                return false;
+            }
+
+            // 1:1兑换VIP下载次数
+            userPT.magic -= magic;
+            userPT.viptime += magic;
+
+            em.merge(userPT);
+            tx.commit();
+
+            logger.info("用户 {} 成功将 {} 点魔力值兑换为 {} 次VIP下载次数", userid, magic, magic);
+            return true;
+
+        } catch (Exception e) {
+            if (tx != null && tx.isActive()) {
+                tx.rollback();
+            }
+            logger.error("魔力值兑换VIP下载次数时发生错误: {}", e.getMessage());
+            return false;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
     }
     //将魔力值兑换为VIP次数，返回状态：0 success，1 不存在,2其他原因
 
     @Override
     public boolean UploadTransmitProfile(Profile profile){
-        return true;
+        if (profile == null || profile.profileurl == null || profile.profileurl.isEmpty() ||
+                profile.userid == null || profile.userid.isEmpty()) {
+            logger.warn("参数无效: profile为空或必要字段为空");
+            return false;
+        }
+
+        EntityManager em = null;
+        EntityTransaction tx = null;
+
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
+
+            // 检查用户是否存在
+            User user = em.find(User.class, profile.userid);
+            if (user == null) {
+                logger.warn("用户 {} 不存在", profile.userid);
+                return false;
+            }
+
+            // 检查是否已存在相同的迁移申请
+            Profile existingProfile = em.find(Profile.class, profile.profileurl);
+            if (existingProfile != null) {
+                logger.warn("迁移申请 {} 已存在", profile.profileurl);
+                return false;
+            }
+
+            // 设置初始值
+            profile.exampass = false;
+            profile.magicgived = "0";
+            profile.uploadgived = "0";
+
+            // 保存迁移申请
+            em.persist(profile);
+            tx.commit();
+
+            logger.info("成功上传迁移申请 {}", profile.profileurl);
+            return true;
+
+        } 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 GetTransmitProfile(String profileid){
-        Profile profile = new Profile();
-        return profile;
+        if (profileid == null || profileid.isEmpty()) {
+            logger.warn("参数无效: profileid为空");
+            return null;
+        }
+
+        EntityManager em = null;
+
+        try {
+            em = emf.createEntityManager();
+            Profile profile = em.find(Profile.class, profileid);
+            if (profile == null) {
+                logger.warn("未找到迁移申请 {}", profileid);
+                return null;
+            }
+
+            logger.info("成功获取迁移申请 {}", profileid);
+            return profile;
+
+        } catch (Exception e) {
+            logger.error("获取迁移申请时发生错误: {}", e.getMessage());
+            return null;
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
     }
     //获取迁移信息
     
     @Override
     public boolean ExamTransmitProfile(String profileid,boolean result){
-        return true;
+        if (profileid == null || profileid.isEmpty()) {
+            logger.warn("参数无效: profileid为空");
+            return false;
+        }
+
+        EntityManager em = null;
+        EntityTransaction tx = null;
+
+        try {
+            em = emf.createEntityManager();
+            tx = em.getTransaction();
+            tx.begin();
+
+            // 查找迁移申请
+            Profile profile = em.find(Profile.class, profileid);
+            if (profile == null) {
+                logger.warn("未找到迁移申请 {}", profileid);
+                return false;
+            }
+
+            // 更新审核状态
+            profile.exampass = result;
+
+            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);
+
+                    // 发放上传量
+                    long uploadToGive = Long.parseLong(profile.uploadtogive);
+                    userPT.upload += uploadToGive;
+                    profile.uploadgived = String.valueOf(uploadToGive);
+
+                    em.merge(userPT);
+                }
+            }
+
+            em.merge(profile);
+            tx.commit();
+
+            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();
+            }
+        }
     }
     //审核迁移信息,0成功，1失败
     @Override
     public Profile[] GetTransmitProfileList(){
-        return new Profile[0];
+        EntityManager em = null;
+
+        try {
+            em = emf.createEntityManager();
+
+            // 获取所有迁移申请
+            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]);
+
+        } catch (Exception e) {
+            logger.error("获取迁移申请列表时发生错误: {}", e.getMessage());
+            return new Profile[0];
+        } finally {
+            if (em != null) {
+                em.close();
+            }
+        }
     }
     //获取所有迁移信息
 
