# CollabProjectApplicationService.java

    package com.yumu.noveltranslator.application.service;

    import com.yumu.noveltranslator.config.tenant.TenantContext;
    import com.yumu.noveltranslator.port.dto.collab.CollabProjectResponse;
    import com.yumu.noveltranslator.port.dto.collab.CreateCollabProjectRequest;
    import com.yumu.noveltranslator.port.dto.collab.InviteMemberRequest;
    import com.yumu.noveltranslator.port.dto.collab.ProjectMemberResponse;
    import com.yumu.noveltranslator.port.dto.common.PageResponse;
    import com.yumu.noveltranslator.port.in.CollabPort;
    import com.yumu.noveltranslator.domain.model.CollabChapterTask;
    import com.yumu.noveltranslator.domain.model.CollabInviteCode;
    import com.yumu.noveltranslator.domain.model.CollabProject;
    import com.yumu.noveltranslator.domain.model.CollabProjectMember;
    import com.yumu.noveltranslator.domain.model.Document;
    import com.yumu.noveltranslator.domain.model.User;
    import com.yumu.noveltranslator.enums.ChapterTaskStatus;
    import com.yumu.noveltranslator.enums.CollabProjectStatus;
    import com.yumu.noveltranslator.enums.ErrorCodeEnum;
    import com.yumu.noveltranslator.enums.ProjectMemberRole;
    import com.yumu.noveltranslator.enums.TranslationStatus;
    import com.yumu.noveltranslator.domain.event.ChapterSplitEvent;
    import com.yumu.noveltranslator.port.out.CollaborationRepositoryPort;
    import com.yumu.noveltranslator.port.out.DocumentRepositoryPort;
    import com.yumu.noveltranslator.port.out.UserRepositoryPort;
    import com.yumu.noveltranslator.exception.BusinessException;
    import com.yumu.noveltranslator.domain.service.MultiAgentTranslationService;
    import com.yumu.noveltranslator.domain.service.CollabStateMachine;
    import com.yumu.noveltranslator.domain.service.CollabEventPublisher;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import lombok.RequiredArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.context.ApplicationEventPublisher;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.time.LocalDateTime;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import java.util.UUID;
    import java.util.stream.Collectors;

    /**
     * 协作项目管理服务
     */
    @Service
    @Slf4j
    @RequiredArgsConstructor
    public class CollabProjectApplicationService implements com.yumu.noveltranslator.port.in.CollabPort {

        private final CollaborationRepositoryPort collabPort;
        private final DocumentRepositoryPort documentPort;
        private final UserRepositoryPort userPort;
        private final CollabStateMachine collabStateMachine;
        private final MultiAgentTranslationService multiAgentTranslationService;
        private final ApplicationEventPublisher eventPublisher;

        /**
         * 创建协作项目，创建者自动成为 OWNER
         */
        @Transactional
        public CollabProjectResponse createProject(CreateCollabProjectRequest request, Long userId) {
            CollabProject project = new CollabProject();
            project.setName(request.getName());
            project.setDescription(request.getDescription());
            project.setOwnerId(userId);
            project.setSourceLang(request.getSourceLang());
            project.setTargetLang(request.getTargetLang());
            project.setStatus(CollabProjectStatus.DRAFT.getValue());
            project.setProgress(0);
            collabPort.saveProject(project);

            // 创建者自动成为 OWNER
            CollabProjectMember owner = new CollabProjectMember();
            owner.setProjectId(project.getId());
            owner.setUserId(userId);
            owner.setRole(ProjectMemberRole.OWNER.getValue());
            owner.setInviteStatus("ACTIVE");
            owner.setJoinedTime(LocalDateTime.now());
            collabPort.saveMember(owner);

            log.info("创建协作项目: projectId={}, name={}, ownerId={}", project.getId(), project.getName(), userId);
            return toProjectResponse(project);
        }

        /**
         * 从上传文档创建协作项目（团队模式）
         */
        @Transactional
        public CollabPort.TeamProjectCreateResult createProjectFromDocument(Long userId, Long documentId, String documentName,
                                                                  String filePath, String fileType,
                                                                  String sourceLang, String targetLang) {
            String content;
            try {
                content = Files.readString(Paths.get(filePath), java.nio.charset.StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new BusinessException(ErrorCodeEnum.SYSTEM_ERROR, "读取文档失败: " + e.getMessage());
            }

            if (content == null || content.trim().isEmpty()) {
                throw new BusinessException(ErrorCodeEnum.PARAMETER_ERROR, "文档内容为空");
            }

            List<String> chapters = splitIntoChapters(content);

            return doCreateProject(userId, documentId, documentName, chapters, sourceLang, targetLang);
        }

        private CollabPort.TeamProjectCreateResult doCreateProject(Long userId, Long documentId, String documentName,
                                                         List<String> chapters, String sourceLang, String targetLang) {
            CollabProject project = createProjectAndOwner(userId, documentId, documentName, sourceLang, targetLang);

            log.info("团队模式创建项目（窄事务）: projectId={}, docName={}, chapters={}, 将异步插入",
                    project.getId(), documentName, chapters.size());

            // 更新文档状态为处理中
            documentPort.findById(documentId).ifPresent(doc -> {
                doc.setStatus(TranslationStatus.PROCESSING.getValue());
                doc.setUpdateTime(LocalDateTime.now());
                documentPort.update(doc);
            });

            eventPublisher.publishEvent(new ChapterSplitEvent(
                    project.getId(), userId, documentId, documentName,
                    chapters, sourceLang, targetLang));

            return new CollabPort.TeamProjectCreateResult(project.getId(), documentName, chapters.size());
        }

        /**
         * 窄事务：仅创建项目和 OWNER 成员
         */
        @Transactional
        protected CollabProject createProjectAndOwner(Long userId, Long documentId, String documentName,
                                                        String sourceLang, String targetLang) {
            CollabProject project = new CollabProject();
            project.setName(documentName);
            project.setDescription("团队模式自动创建");
            project.setOwnerId(userId);
            project.setDocumentId(documentId);
            project.setSourceLang(sourceLang != null ? sourceLang : "auto");
            project.setTargetLang(targetLang);
            project.setStatus(CollabProjectStatus.DRAFT.getValue());
            project.setProgress(0);
            collabPort.saveProject(project);

            CollabProjectMember owner = new CollabProjectMember();
            owner.setProjectId(project.getId());
            owner.setUserId(userId);
            owner.setRole(ProjectMemberRole.OWNER.getValue());
            owner.setInviteStatus("ACTIVE");
            owner.setJoinedTime(LocalDateTime.now());
            collabPort.saveMember(owner);

            return project;
        }

        /**
         * 将文档章节添加到已有协作项目
         */
        @Transactional
        public int addChaptersToProject(Long userId, Long projectId, Document document) {
            CollabProject project = collabPort.findProjectById(projectId).orElse(null);
            if (project == null) {
                throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "项目不存在: " + projectId);
            }

            // 权限校验
            var member = collabPort.findMemberByProjectAndUser(projectId, userId);
            if (member == null && !project.getOwnerId().equals(userId)) {
                throw new BusinessException(ErrorCodeEnum.FORBIDDEN, "无权向该项目添加章节");
            }

            String content;
            try {
                content = Files.readString(Paths.get(document.getPath()), java.nio.charset.StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new BusinessException(ErrorCodeEnum.SYSTEM_ERROR, "读取文档失败: " + e.getMessage());
            }

            if (content == null || content.trim().isEmpty()) {
                throw new BusinessException(ErrorCodeEnum.PARAMETER_ERROR, "文档内容为空");
            }

            List<String> chapters = splitIntoChapters(content);

            return doAddChaptersToProject(project, document, chapters);
        }

        @Transactional
        private int doAddChaptersToProject(CollabProject project, Document document, List<String> chapters) {
            Long projectId = project.getId();

            if (project.getDocumentId() == null) {
                project.setDocumentId(document.getId());
                collabPort.updateProject(project);
            }

            List<CollabChapterTask> existingChapters = collabPort.findChapterTasksByProjectId(projectId);
            int nextChapterNumber = existingChapters.stream()
                    .mapToInt(CollabChapterTask::getChapterNumber)
                    .max()
                    .orElse(0) + 1;

            for (String chapterText : chapters) {
                CollabChapterTask chapter = new CollabChapterTask();
                chapter.setProjectId(projectId);
                chapter.setChapterNumber(nextChapterNumber++);
                chapter.setTitle("第 " + chapter.getChapterNumber() + " 章");
                chapter.setSourceText(chapterText);
                chapter.setTargetText(null);
                chapter.setStatus(ChapterTaskStatus.UNASSIGNED.getValue());
                chapter.setProgress(0);
                chapter.setSourceWordCount(chapterText.length());
                collabPort.saveChapterTask(chapter);
            }

            document.setStatus(TranslationStatus.PROCESSING.getValue());
            document.setUpdateTime(java.time.LocalDateTime.now());
            documentPort.update(document);

            log.info("添加章节到项目: projectId={}, docName={}, chapters={}", projectId, document.getName(), chapters.size());
            return chapters.size();
        }

        /**
         * 启动多 Agent 翻译
         */
        public void startMultiAgentTranslation(Long projectId) {
            multiAgentTranslationService.startMultiAgentTranslation(projectId);
        }

        /**
         * 智能章节分割
         */
        private List<String> splitIntoChapters(String content) {
            String[] lines = content.split("\n");
            List<String> chapters = new ArrayList<>();
            StringBuilder currentChapter = new StringBuilder();
            boolean hasChapterTitle = false;

            java.util.regex.Pattern chapterPattern = java.util.regex.Pattern.compile(
                    "^\\s*(?:\\*\\*?)?\\s*(?:" +
                            "(?:第\\s*[零一二三四五六七八九十百千\\d]+\\s*(?:章|节|回|卷|篇))" +
                            "|(?:chapter\\s+[ivxlcdm\\d]+\\s*[:：]?\\s*.*)" +
                            "|(?:ch\\.?\\s*\\d+)" +
                            "|(?:part\\s+[ivxlcdm\\d]+\\s*[:：]?\\s*.*)" +
                            "|(?:(?:[一二三四五六七八九十]+)、)" +
                            ")",
                    java.util.regex.Pattern.CASE_INSENSITIVE
            );

            for (String line : lines) {
                String trimmed = line.trim();

                if (chapterPattern.matcher(trimmed).find()) {
                    if (currentChapter.length() > 0) {
                        String chapterText = currentChapter.toString().trim();
                        if (!chapterText.isEmpty()) {
                            chapters.add(chapterText);
                        }
                        currentChapter = new StringBuilder();
                    }
                    hasChapterTitle = true;
                    currentChapter.append(trimmed).append("\n");
                } else {
                    currentChapter.append(line).append("\n");
                }
            }

            if (currentChapter.length() > 0) {
                String chapterText = currentChapter.toString().trim();
                if (!chapterText.isEmpty()) {
                    chapters.add(chapterText);
                }
            }

            if (!hasChapterTitle) {
                chapters.clear();
                String[] paragraphs = content.split("\n+");
                StringBuilder current = new StringBuilder();
                int maxCharsPerChapter = 2000;

                for (String p : paragraphs) {
                    String pTrimmed = p.trim();
                    if (pTrimmed.isEmpty()) continue;
                    if (current.length() + pTrimmed.length() > maxCharsPerChapter && current.length() > 0) {
                        chapters.add(current.toString().trim());
                        current = new StringBuilder();
                    }
                    current.append(pTrimmed).append("\n");
                }
                if (current.length() > 0) {
                    chapters.add(current.toString().trim());
                }
            }

            if (chapters.isEmpty()) {
                chapters.add(content.trim());
            }

            log.debug("章节分割: 检测到章节标题={}, 分割出 {} 章", hasChapterTitle, chapters.size());
            return chapters;
        }

        /**
         * 获取项目详情
         */
        public CollabProjectResponse getProjectById(Long projectId) {
            CollabProject project = collabPort.findProjectById(projectId).orElse(null);
            if (project == null) {
                throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "项目不存在: " + projectId);
            }
            return toProjectResponse(project);
        }

        /**
         * 获取用户参与的项目列表
         */
        public PageResponse<CollabProjectResponse> listByUserId(Long userId, int page, int pageSize) {
            try {
                TenantContext.setBypassTenant(true);
                List<CollabProject> allProjects = collabPort.findProjectsByMemberUserId(userId);
                long total = allProjects.size();
                int fromIndex = Math.min((page - 1) * pageSize, (int) total);
                int toIndex = Math.min(fromIndex + pageSize, (int) total);
                List<CollabProject> pagedProjects = fromIndex < total
                        ? allProjects.subList(fromIndex, toIndex)
                        : List.of();
                Map<Long, User> userMap = batchLoadOwnerUsers(pagedProjects);
                List<CollabProjectResponse> responseList = pagedProjects.stream()
                        .map(p -> toProjectResponse(p, userMap))
                        .collect(Collectors.toList());
                return PageResponse.of(page, pageSize, total, responseList);
            } finally {
                TenantContext.setBypassTenant(false);
            }
        }

        /**
         * 更新项目信息
         */
        @Transactional
        public CollabProjectResponse updateProject(Long projectId, CreateCollabProjectRequest request, Long userId) {
            CollabProject project = collabPort.findProjectById(projectId).orElse(null);
            if (project == null) {
                throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "项目不存在: " + projectId);
            }

            project.setName(request.getName());
            project.setDescription(request.getDescription());
            project.setSourceLang(request.getSourceLang());
            project.setTargetLang(request.getTargetLang());
            collabPort.updateProject(project);

            return toProjectResponse(project);
        }

        /**
         * 变更项目状态
         */
        @Transactional
        public void changeProjectStatus(Long projectId, CollabProjectStatus targetStatus, Long userId) {
            CollabProject project = collabPort.findProjectById(projectId).orElse(null);
            if (project == null) {
                throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "项目不存在: " + projectId);
            }

            CollabProjectStatus current = CollabProjectStatus.fromValue(project.getStatus());
            collabStateMachine.transitionProject(project, targetStatus);
            if (targetStatus == CollabProjectStatus.COMPLETED) {
                project.setProgress(100);
            }
            collabPort.updateProject(project);

            log.info("项目状态变更: projectId={}, {} -> {}", projectId, current, targetStatus);
        }

        /**
         * 生成项目邀请码
         */
        @Transactional
        public CollabPort.InviteCodeResult generateInviteCode(Long projectId, Long operatorId) {
            CollabProject project = collabPort.findProjectById(projectId).orElse(null);
            if (project == null) {
                throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "项目不存在: " + projectId);
            }

            String code = generateRandomInviteCode();
            LocalDateTime expiresAt = LocalDateTime.now().plusHours(72);

            CollabInviteCode inviteCode = new CollabInviteCode();
            inviteCode.setProjectId(projectId);
            inviteCode.setCode(code);
            inviteCode.setExpiresAt(expiresAt);
            inviteCode.setUsed(0);
            collabPort.saveInviteCode(inviteCode);

            log.info("生成邀请码: projectId={}, code={}, expiresAt={}", projectId, code, expiresAt);
            return new CollabPort.InviteCodeResult(code, expiresAt);
        }

        private String generateRandomInviteCode() {
            String chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
            java.security.SecureRandom random = new java.security.SecureRandom();
            StringBuilder code = new StringBuilder(8);
            for (int i = 0; i < 8; i++) {
                code.append(chars.charAt(random.nextInt(chars.length())));
            }
            if (collabPort.findInviteCodeByCode(code.toString()) != null) {
                return generateRandomInviteCode();
            }
            return code.toString();
        }

        /**
         * 邀请成员
         */
        @Transactional
        public ProjectMemberResponse inviteMember(Long projectId, InviteMemberRequest request, Long inviterId) {
            User user = userPort.findByEmail(request.getEmail()).orElse(null);
            if (user == null) {
                throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "用户不存在: " + request.getEmail());
            }

            var existing = collabPort.findMemberByProjectAndUser(projectId, user.getId());
            if (existing != null) {
                throw new BusinessException(ErrorCodeEnum.INVALID_STATE, "该用户已是项目成员");
            }

            String inviteCode = UUID.randomUUID().toString().replace("-", "").substring(0, 16);

            CollabProjectMember member = new CollabProjectMember();
            member.setProjectId(projectId);
            member.setUserId(user.getId());
            member.setRole(request.getRole().getValue());
            member.setInviteCode(inviteCode);
            member.setInviteStatus("INVITED");
            collabPort.saveMember(member);

            log.info("邀请成员: projectId={}, email={}, role={}", projectId, request.getEmail(), request.getRole());
            return toMemberResponse(member, user);
        }

        /**
         * 通过邀请码加入项目
         */
        @Transactional
        public ProjectMemberResponse joinByInviteCode(String inviteCode, Long userId) {
            CollabInviteCode codeRecord = collabPort.findValidInviteCode(inviteCode);
            if (codeRecord == null) {
                CollabInviteCode anyCode = collabPort.findInviteCodeByCode(inviteCode);
                if (anyCode == null) {
                    throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "邀请码无效");
                }
                if (anyCode.getUsed() == 1) {
                    throw new BusinessException(ErrorCodeEnum.INVALID_STATE, "邀请码已被使用");
                }
                if (anyCode.getExpiresAt().isBefore(LocalDateTime.now())) {
                    throw new BusinessException(ErrorCodeEnum.INVALID_STATE, "邀请码已过期");
                }
                throw new BusinessException(ErrorCodeEnum.INVALID_STATE, "邀请码不可用");
            }

            collabPort.markInviteCodeAsUsed(codeRecord.getId());

            try {
                TenantContext.setBypassTenant(true);

                CollabProject project = collabPort.findProjectById(codeRecord.getProjectId()).orElse(null);
                if (project == null) {
                    throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "关联项目不存在");
                }
                if (!CollabProjectStatus.ACTIVE.getValue().equals(project.getStatus())) {
                    throw new BusinessException(ErrorCodeEnum.INVALID_STATE, "项目当前不可加入");
                }

                var existing = collabPort.findMemberByProjectAndUser(codeRecord.getProjectId(), userId);
                if (existing != null) {
                    throw new BusinessException(ErrorCodeEnum.INVALID_STATE, "您已是该项目成员");
                }

                CollabProjectMember member = new CollabProjectMember();
                member.setProjectId(codeRecord.getProjectId());
                member.setUserId(userId);
                member.setRole(ProjectMemberRole.TRANSLATOR.getValue());
                member.setInviteCode(inviteCode);
                member.setInviteStatus("ACTIVE");
                member.setJoinedTime(LocalDateTime.now());
                member.setTenantId(project.getTenantId());
                collabPort.saveMember(member);

                User user = userPort.findById(userId).orElse(null);
                log.info("加入项目: userId={}, projectId={}, inviteCode={}", userId, codeRecord.getProjectId(), inviteCode);
                return toMemberResponse(member, user);
            } finally {
                TenantContext.setBypassTenant(false);
            }
        }

        /**
         * 获取项目成员列表（分页）
         */
        public PageResponse<ProjectMemberResponse> getMembers(Long projectId, int page, int pageSize) {
            List<CollabProjectMember> allMembers;
            try {
                TenantContext.setBypassTenant(true);
                allMembers = collabPort.findMembersByProjectId(projectId);
            } finally {
                TenantContext.setBypassTenant(false);
            }
            long total = allMembers.size();
            int fromIndex = Math.min((page - 1) * pageSize, (int) total);
            int toIndex = Math.min(fromIndex + pageSize, (int) total);
            List<CollabProjectMember> pagedMembers = fromIndex < total
                    ? allMembers.subList(fromIndex, toIndex)
                    : List.of();

            Set<Long> userIds = new HashSet<>();
            for (CollabProjectMember m : pagedMembers) {
                if (m.getUserId() != null) userIds.add(m.getUserId());
            }
            Map<Long, User> userMap = new HashMap<>();
            for (Long uid : userIds) {
                userPort.findById(uid).ifPresent(u -> userMap.put(uid, u));
            }

            List<ProjectMemberResponse> responseList = pagedMembers.stream()
                    .map(m -> toMemberResponse(m, userMap.get(m.getUserId())))
                    .collect(Collectors.toList());
            return PageResponse.of(page, pageSize, total, responseList);
        }

        /**
         * 移除成员
         */
        @Transactional
        public void removeMember(Long projectId, Long memberId, Long operatorId) {
            var member = collabPort.findMemberById(memberId).orElse(null);
            if (member == null || !member.getProjectId().equals(projectId)) {
                throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "成员不存在");
            }

            if (ProjectMemberRole.OWNER.getValue().equals(member.getRole())) {
                throw new BusinessException(ErrorCodeEnum.INVALID_STATE, "所有者不能直接移除，需先转让项目");
            }

            member.setInviteStatus("REMOVED");
            collabPort.updateMember(member);
        }

        /**
         * 删除项目
         */
        @Transactional
        public void deleteProject(Long projectId, Long userId) {
            CollabProject project = collabPort.findProjectById(projectId).orElse(null);
            if (project == null) {
                throw new BusinessException(ErrorCodeEnum.NOT_FOUND, "项目不存在");
            }
            if (!project.getOwnerId().equals(userId)) {
                throw new BusinessException(ErrorCodeEnum.FORBIDDEN, "只有项目所有者可以删除项目");
            }

            // 级联逻辑删除：评论 → 章节 → 成员 → 项目
            List<CollabChapterTask> chapters = collabPort.findChapterTasksByProjectId(projectId);
            for (CollabChapterTask chapter : chapters) {
                collabPort.deleteCommentsByChapterTaskId(chapter.getId());
            }
            collabPort.deleteChapterTasksByProjectId(projectId);
            collabPort.deleteMembersByProjectId(projectId);
            collabPort.deleteProject(projectId);

            log.info("删除协作项目: projectId={}, name={}, ownerId={}", projectId, project.getName(), userId);
        }

        private CollabProjectResponse toProjectResponse(CollabProject project) {
            return toProjectResponse(project, Map.of());
        }

        private CollabProjectResponse toProjectResponse(CollabProject project, Map<Long, User> userMap) {
            CollabProjectResponse resp = new CollabProjectResponse();
            resp.setId(project.getId());
            resp.setName(project.getName());
            resp.setDescription(project.getDescription());
            resp.setOwnerId(project.getOwnerId());
            resp.setSourceLang(project.getSourceLang());
            resp.setTargetLang(project.getTargetLang());
            resp.setStatus(project.getStatus());
            resp.setProgress(project.getProgress());
            resp.setCreateTime(project.getCreateTime());
            resp.setUpdateTime(project.getUpdateTime());

            User owner = userMap.get(project.getOwnerId());
            if (owner == null) {
                owner = userPort.findById(project.getOwnerId()).orElse(null);
            }
            if (owner != null) {
                resp.setOwnerName(owner.getUsername());
            }

            int memberCount = collabPort.countMembersByProjectId(project.getId());
            resp.setMemberCount(memberCount);

            return resp;
        }

        private Map<Long, User> batchLoadOwnerUsers(List<CollabProject> projects) {
            Set<Long> userIds = new HashSet<>();
            for (CollabProject p : projects) {
                if (p.getOwnerId() != null) userIds.add(p.getOwnerId());
            }
            Map<Long, User> userMap = new HashMap<>();
            for (Long uid : userIds) {
                userPort.findById(uid).ifPresent(u -> userMap.put(uid, u));
            }
            return userMap;
        }

        private ProjectMemberResponse toMemberResponse(CollabProjectMember member, User user) {
            ProjectMemberResponse resp = new ProjectMemberResponse();
            resp.setId(member.getId());
            resp.setUserId(member.getUserId());
            resp.setRole(member.getRole());
            resp.setInviteStatus(member.getInviteStatus());
            resp.setJoinedTime(member.getJoinedTime());
            if (user != null) {
                resp.setUsername(user.getUsername());
                resp.setEmail(user.getEmail());
                resp.setAvatar(user.getAvatar());
            }
            return resp;
        }

    }