본문 바로가기

개인프로젝트(수강프로그램)

강좌관리

# 강좌별 강좌 신청내역

 

강좌를 기준으로 필터링하는 로직 추가

 

- AdminTakeCoursrController

 

전체강좌를 가지고 오는 listAll 메서드를 만들고 가져온다

@GetMapping("/admin/takecourse/list")
public String list(Model model, TakeCourseParam param){

    param.init();

    List<TakeCourseDto> courseList = takeCourseService.list(param);


    long totalCount = 0;
    if(courseList != null && courseList.size() > 0){
        totalCount = courseList.get(0).getTotalCount();
    }

    String queryString = param.getQueryString();
    String pagerHtml = getPapaerHtml(totalCount, param.getPageSize(), param.getPageIndex(), queryString);

    model.addAttribute("list", courseList);
    model.addAttribute("pager", pagerHtml);
    model.addAttribute("totalCount", totalCount);

    List<CourseDto> courseAllList = courseService.listAll();
    model.addAttribute("courseAllList", courseAllList);

    return "admin/takecourse/list";
}

 

 

- CourseService

 

// 전체 강좌정보 목록
 List<CourseDto> listAll();

 

- CourseServiceImpl

 

@Override
public List<CourseDto> listAll() {

    List<Course> courseList = courseRepository.findAll();
    return CourseDto.of(courseList);

}

 

이제 강좌를 select할때마다 정보를 가져오는 로직구현(이벤트를 잡아서 동적변화를 줄 것)

 

 

- list.html 

강좌가 선택된 후 해당 내용을 유지하기 위해 selected 사용

 

- TakeCourseParam

 

서버에서는 클라이언트 값에서 넘어온 값으로 검색이 되어야 한다

 

@Data
public class TakeCourseParam extends CommonParam {
    long id;
    String status;
    String userId;

    // 검색을 위한 아이디
    String searchCourseId;

}

 

- TakeCourseMapper

 

 

<sql id="selectListWhere">

    <if test="searchCourseId > 0">
        and c.id = #{searchCourseId}
    </if>

</sql>


<select id="selectListCount"
        parameterType="com.zerobase.fastlms.course.model.TakeCourseParam"
        resultType="long">
    select count(*)
    from take_course tc
    join course c on tc.course_id = c.id
    join member m on tc.user_id = m.user_id
    where 1 = 1
        <include refid="selectListWhere" />
</select>

 

 


# 파일업로드

 

파일을 서버로 보내기 위해서는 form태그에 enctype을 줘야한다

 

- admin/course/add.html

 

- AdminCourseController

 

파일을 서버에서 받기 위해서는 MultipartFile을 추가하고 여러개를 받을 시에는 List로 감싸면 된다

 

파일을 Db에 저장하는 것이 아닌 하드디스크 상에 저장되도록 구현(특정폴더에 넣음)

에러를 출력하기 위해 상단에 SLf4j 작성

 

@Slf4j
@RequiredArgsConstructor
@Controller
public class AdminCourseController extends BaseController{

 

@PostMapping(value = {"/admin/course/add", "/admin/course/edit"})
public String addSubmit(Model model, CourseInput param,
                        HttpServletRequest request,
                        MultipartFile file){

    if(file != null){
        String localPath = "C:\\Users\\user\\IdeaProjects\\Pfastlms\\files\\abd.png";

        try {
            File newfile = new File(localPath);
            FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(newfile));
        } catch (IOException e) {
            log.info("####에러발생");
            log.info(e.getMessage());
        }


    }

 

올린 파일에 대해서는 파일정보를 통해서 DB에 저장후 파일을 가져오게 할 것

 

파일이름을 파일이름마다 다르게 저장해야하는데 파일이 같을수도 있고 다를수도 있다.

그렇기에 원래 원본이름과 실제 저장되는 파일명을 다르게 해주며 파일관리를 진행한다

 

먼저 파일을 저장하기 위해서는 저장되는 경로를 세팅해야 한다(초기화작업)

 

@PostMapping(value = {"/admin/course/add", "/admin/course/edit"})
public String addSubmit(Model model, CourseInput param,
                        HttpServletRequest request,
                        MultipartFile file){

    String saveFiles = "";

    if(file != null){

        String originalFileNames = file.getOriginalFilename();

        String basePath = "C:\\Users\\user\\IdeaProjects\\Pfastlms\\files";
        saveFiles = getNewSaveFiles(basePath, originalFileNames);

        try {
            File newfile = new File(saveFiles);
            FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(newfile));
        } catch (IOException e) {
            log.info("####에러발생");
            log.info(e.getMessage());
        }
    }

    param.setFilename(saveFiles);

    boolean editMode = request.getRequestURI().contains("/edit");

    if(editMode){
        long id = param.getId();
        CourseDto existCourse = courseService.getById(id);
        // 수정할 데이터가 없으면
        if(existCourse == null){
            // 에러처리
            model.addAttribute("message", "강좌정보가 존재하지 않습니다");
            return "common/error";
        }
        // edit모드일때는 수정
        boolean result = courseService.set(param);

    }else {
        // edit모드가 아닐때는 등록
        boolean result = courseService.add(param);
    }

    return "redirect:/admin/course/list";
}

 

String getNewSaveFiles(String basePath, String originalFileNames){

    LocalDate now = LocalDate.now();

    // 현재 경로에 연도를 추가한 것
    String[] dirs = {
            String.format("%s/%d/", basePath, now.getYear()),
            String.format("%s/%d/%02d/", basePath, now.getYear(),  now.getMonthValue()),
            String.format("%s/%d/%02d/%02d/", basePath, now.getYear(),  now.getMonthValue(), now.getDayOfMonth())
    };

    for (String dir : dirs) {
        File file = new File(dir);
        if(!file.isDirectory()){
            file.mkdir();
        }
    }

    // originalFileNames의 확장자
    String fileExtension = "";
    if(originalFileNames != null){
        // .에 대한 위치를 가져와서
        int dotPots = originalFileNames.lastIndexOf(".");
        if(dotPots > -1){
            fileExtension = originalFileNames.substring(dotPots + 1);
        }
    }

    // 생성이 된 이후에 newfIle까지 리턴
    String uuid = UUID.randomUUID().toString().replace("-", "");
    String newFiienamse = String.format("%s%s", dirs[2], uuid); // 여기까지 파일명
    if(fileExtension.length() > 0){
        newFiienamse += "." + fileExtension;
    }

    return newFiienamse;
}

 

 

- 결과

 

 

 

이제 파일이 정상적으로 생겼으니 저장을 해야한다(저장된 파일명을 course 저장할때 같이 저장하도록 구현)

 

- CourseInput

 

// 파일 ADD
String filename;

 

- Course

 

추가

String filename;

 

- CourseServiceImpl

 

@Override
public boolean add(CourseInput param) {

    LocalDate saleEndDt = getLocalDate(param.getSaleEndDtText());

    Course course = Course.builder()
            ...
            .filename(param.getFilename())
            .build();
    courseRepository.save(course);


    return true;
}

@Override
public boolean set(CourseInput param) {

    LocalDate saleEndDt = getLocalDate(param.getSaleEndDtText());

    Optional<Course> optionalCourse = courseRepository.findById(param.getId());

    // null 이면 수정할 데이터가 없는것
    if(!optionalCourse.isPresent()){
        return false;
    }
    // 수정할 데이터가 있다면
    ...
    course.setFilename(param.getFilename());
    courseRepository.save(course);

    return false;
}

 

 


 

저장은 되었지만 이 파일이 보여지는 것은 별개의 문제, 웹에서 파일이 보여지게 하려면 URL이 노출되어야함

실제로 파일이 보여지려면 target폴더에 static이라는 곳에서 만들어져야 한다

하지만 이는 이슈가 있기 때문에 tomcat폴더에 올려서 진행할 것

 

톰캣설정

 

files가 올라갈 경로 설정

 

파일 적용이 끝나면 인텔리제이 내에 파일 디렉토리 모양이 web 모양을 바뀐다

이 경로가 webapp의 루트가 되는것 

 

- SecurityConfiguration

 

files에 대한 경로를 허용해줘야 파일을 볼 수 있음

 

@Override
public void configure(WebSecurity web) throws Exception {

    web.ignoring().antMatchers("favicon.ico", "/files/**");

    super.configure(web);
}

 

이제 올라간 이미지에 대해서 경로설정이 되어야하는데

basePath는 저장된 경로이고 url경로(실질적인 파일의 위치)가 필요하다

 

리턴 경로가 두개니 배열로 getNewSaveFiles를 리턴

 

- AdminCourseController

 

// getNewSaveFiles을 배열로 받아준다
private String[] getNewSaveFiles(String baseLocalPath,String baseUrlPath, String originalFileNames){

    LocalDate now = LocalDate.now();

    // 현재 경로에 연도를 추가한 것
    String[] dirs = {
            String.format("%s/%d/", baseLocalPath, now.getYear()),
            String.format("%s/%d/%02d/", baseLocalPath, now.getYear(),  now.getMonthValue()),
            String.format("%s/%d/%02d/%02d/", baseLocalPath, now.getYear(),  now.getMonthValue(), now.getDayOfMonth())
    };

    // urlDir은 dirs의 포맷과 동일하지만 baseUrlPath의 경로로 적용
    String urlDir = String.format("%s/%d/%02d/%02d/", baseUrlPath, now.getYear(),  now.getMonthValue(), now.getDayOfMonth());

    for (String dir : dirs) {
        File file = new File(dir);
        if(!file.isDirectory()){
            file.mkdir();
        }
    }

    // originalFileNames의 확장자
    String fileExtension = "";
    if(originalFileNames != null){
        // .에 대한 위치를 가져와서
        int dotPots = originalFileNames.lastIndexOf(".");
        if(dotPots > -1){
            fileExtension = originalFileNames.substring(dotPots + 1);
        }
    }

    // 생성이 된 이후에 newfIle까지 리턴
    String uuid = UUID.randomUUID().toString().replace("-", "");
    String newFiienamse = String.format("%s%s", dirs[2], uuid); // 여기까지 파일명
    String newUrlFilename = String.format("%s%s", urlDir, uuid); // url경로에 대한 파일명
    if(fileExtension.length() > 0){
        newFiienamse += "." + fileExtension;
        newUrlFilename += "." + fileExtension;
    }

    String[] returnFimename = {newFiienamse, newUrlFilename};
    return returnFimename;
}

 

@PostMapping(value = {"/admin/course/add", "/admin/course/edit"})
public String addSubmit(Model model, CourseInput param,
                        HttpServletRequest request,
                        MultipartFile file){

    String saveFiles = "";
    String urlFilenames = "";


    if(file != null){
        String originalFileNames = file.getOriginalFilename();

        String baseLocalPath = "C:\\Users\\user\\IdeaProjects\\Pfastlms\\files";
        String baseUrlPath = "/files";
		
        // getNewSaveFiles 로 받아온 배열값
        String[] arrFilenames = getNewSaveFiles(baseLocalPath,baseUrlPath, originalFileNames);

        saveFiles = arrFilenames[0];
        urlFilenames = arrFilenames[1];


        try {
            File newfile = new File(saveFiles);
            FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(newfile));
        } catch (IOException e) {
            log.info("####에러발생");
            log.info(e.getMessage());
        }
    }
	
    // 배열값으로 받아온 값들을 저장
    param.setFilename(saveFiles);
    param.setUrlFilenames(urlFilenames);

    boolean editMode = request.getRequestURI().contains("/edit");

    if(editMode){
        long id = param.getId();
        CourseDto existCourse = courseService.getById(id);
        // 수정할 데이터가 없으면
        if(existCourse == null){
            // 에러처리
            model.addAttribute("message", "강좌정보가 존재하지 않습니다");
            return "common/error";
        }
        // edit모드일때는 수정
        boolean result = courseService.set(param);

    }else {
        // edit모드가 아닐때는 등록
        boolean result = courseService.add(param);
    }

    return "redirect:/admin/course/list";
}

 

- CourseInput

 

+ Course 엔티티에도 urlFilenames 필드 생성

+ add, set 메서드에도 아까 했던것과 동일하게 urlFilenames 값을 저장해준다

+ CourseDto에 리스트를 가져올때도 of메서드에 저장

// 파일 ADD
String filename;
String urlFilenames;

 

실제 DB에 저장된 이름

// filename
C:\Users\user\IdeaProjects\Pfastlms\files/2022/05/12/df12db29d60d44669a8b00d56180d2b8.jpg
// url
/files/2022/05/12/df12db29d60d44669a8b00d56180d2b8.jpg

 

이제 저장이 되었다면 실제로 강의 목록에 사진이 나와야 하는 로직 구현

 

- course/detail

 

<div>
    <img th:src="${detail.urlFilenames}">
</div>

 

 

 

 

 

 

 

 

 

'개인프로젝트(수강프로그램)' 카테고리의 다른 글

회원정보 수정  (0) 2022.05.03
백오피스 - 강좌신청 처리구현  (0) 2022.05.02
강좌신청  (0) 2022.04.25
강좌 목록 구현  (0) 2022.04.25
강좌 목록 구현, 강좌 신청  (0) 2022.04.22