[Admin_공지사항] enum 공지사항 유형 / 조회수 증가 / 다중 검색 기능(1)

2024. 1. 20. 23:01Project/ShoppingMall

반응형

 

 

🟢 Constant

▪️ 공지사항 유형 설정

public enum NoticeRole {

  POINT("적립금"),
  DELIVERY("배송공지"),
  PRODUCT("상품공지"),
  EVENT("이벤트"),
  ETC("기타"),
  TIP("청소꿀팁");

  private final String description;

  NoticeRole(String description) {
    this.description = description;
  }

  public String getDescription() {
    return description;
  }
  
}

 

 

🟢 Entity

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table(name = "notice")
@SequenceGenerator(
    name = "notice_SEQ",
    sequenceName = "notice_SEQ",
    initialValue = 1,
    allocationSize = 1)
public class NoticeEntity extends BaseEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "notice_SEQ")
  @Column(name="noticeId")
  private Integer noticeId;

  @Column(name="noticeCategory", nullable = false)
  private String noticeCategory;       //공지유형

  @Column(name="noticeTitle",nullable = false,length = 50)
  private String noticeTitle;          //제목

  @Column(name="noticeWriter", nullable = false,length = 20)
  private String noticeWriter;         //작성자

  @Column(name="noticeContent", nullable = false,length = 2000)
  private String noticeContent;        //공지내용

  @Column(name = "noticeView")
  private Integer noticeView;

  @Column(name="noticeRole")
  @Enumerated(EnumType.STRING)
  private NoticeRole noticeRole;

}

 

 

🟢 DTO

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class NoticeDTO {

    private Integer noticeId;

    private NoticeRole noticeRole;

    @NotEmpty(message="제목은 생략할 수 없습니다.")
    private String noticeTitle;          //제목

    @NotEmpty(message="작성자는 생략할 수 없습니다.")
    private String noticeWriter;         //작성자

    @NotEmpty(message="공지내용은 생략할 수 없습니다.")
    private String noticeContent;        //공지내용

    private Integer noticeView;         //조회수

    private LocalDateTime reDate;      //생성날짜

    private LocalDateTime modDate;      //수정날짜

}

 

 

🟢 Repository

▪️ 검색조건 : 공지유형, 제목 또는 내용

@Repository
public interface NoticeRepository extends JpaRepository<NoticeEntity, Integer> {

  //검색조건
  //공지 유형
  @Query("SELECT n FROM NoticeEntity n WHERE n.noticeRole = :noticeRole")
  Page<NoticeEntity> findByNoticeRole (@Param("noticeRole")NoticeRole noticeRole, Pageable pageable);

  //제목 또는 내용
  @Query("SELECT n FROM NoticeEntity n WHERE n.noticeTitle LIKE %:keyword% OR n.noticeContent like %:keyword%")
  Page<NoticeEntity> findByNoticeTitleOrNoticeContent (@Param("keyword") String keyword, Pageable pageable);

}

 

 

🟢 Service

@Service
@RequiredArgsConstructor
@Transactional
public class NoticeService {

  private final NoticeRepository noticeRepository;
  private final CommentRepository commentRepository;
  private final ModelMapper modelMapper = new ModelMapper();

  //공지등록
  public NoticeEntity insert(NoticeDTO noticeDTO) throws Exception {

    NoticeEntity noticeEntity = modelMapper.map(noticeDTO, NoticeEntity.class);
    noticeRepository.save(noticeEntity);

    return noticeEntity;

  }


  //공지목록 (관리자)
  public Page<NoticeDTO> findAll(String type, String keyword, String noticeRole, Pageable page) throws  Exception {

    int currentpage = page.getPageNumber()-1;
    int blockLimit = 10;

    Pageable pageable = PageRequest.of(currentpage, blockLimit, Sort.by(Sort.Direction.DESC, "noticeId"));

    Page<NoticeEntity> noticeEntityPage;

    if("tc".equals(type) && keyword != null && !keyword.isEmpty()) {
      noticeEntityPage = noticeRepository.findByNoticeTitleOrNoticeContent(keyword, pageable);
    } else if("r".equals(type) && noticeRole != null  && !noticeRole.isEmpty()) {
      noticeEntityPage = noticeRepository.findByNoticeRole(NoticeRole.valueOf(noticeRole), pageable);
    } else {
      noticeEntityPage = noticeRepository.findAll(pageable);
    }

    List<NoticeDTO> noticeDTOS = noticeEntityPage.stream()
        .map(noticeEntity -> modelMapper.map(noticeEntity, NoticeDTO.class))
        .collect(Collectors.toList());

    return new PageImpl<>(noticeDTOS, pageable, noticeEntityPage.getTotalElements());

  }


  //공지상세 (관리자)
  public NoticeDTO findOne(Integer noticeId) throws Exception {

    Optional<NoticeEntity> noticeEntity = noticeRepository.findById(noticeId);

    NoticeDTO noticeDTO = modelMapper.map(noticeEntity, NoticeDTO.class);

    return noticeDTO;

  }


  //공지수정
  //작성일, 조회수 유지
  public void update(NoticeDTO noticeDTO) throws Exception {

    Integer noticeId = noticeDTO.getNoticeId();
    Optional<NoticeEntity> noticeEntity = noticeRepository.findById(noticeId);

    if(noticeEntity.isPresent()) {
      NoticeEntity update = noticeEntity.get();

      LocalDateTime creationDate = update.getReDate();
      Integer noticeView = update.getNoticeView();

      modelMapper.map(noticeDTO, update);

      update.setReDate(creationDate);
      update.setNoticeView(noticeView);

      noticeRepository.save(update);
    }

  }


  //공지삭제
  //댓글 삭제 후, 글 삭제
  public void delete(Integer noticeId) throws Exception {

    commentRepository.deleteAll();

    noticeRepository.deleteById(noticeId);

  }


}

 

🟢 Controller

@Controller
@Transactional
@RequiredArgsConstructor
public class NoticeController {

  private final NoticeService noticeService;
  private final CommentService commentService;

  //관리자
  //공지등록폼
  @GetMapping("/admin_noticeinsert")
  public String noticeForm(Model model) throws Exception {

    NoticeDTO noticeDTO = new NoticeDTO();

    model.addAttribute("noticeDTO", noticeDTO);
    model.addAttribute("noticeRole", NoticeRole.values());

    return "admin/notice_insert";
  }
  
  //공지등록처리
  @PostMapping("/admin_noticeinsert")
  public String noticeProc(@Valid NoticeDTO noticeDTO, BindingResult bindingResult, Model model) throws Exception {

    if(bindingResult.hasErrors()) {
      model.addAttribute("noticeRole", NoticeRole.values());
      return "admin/notice_insert";
    } noticeService.insert(noticeDTO);

    return "redirect:/admin_noticelist";

  }
  
  //공지목록
  @GetMapping("/admin_noticelist")
  public String noticeList(@RequestParam(value = "type", defaultValue = "") String type,
                           @RequestParam(value = "keyword", defaultValue = "") String keyword,
                           @RequestParam(value = "noticeRole", defaultValue = "") String noticeRole,
                           @PageableDefault(page = 1) Pageable pageable,
                           Model model) throws Exception {

    Page<NoticeDTO> noticeDTOS = noticeService.findAll(type, keyword, noticeRole, pageable);

    int blockLimit = 5;
    int startPage = (((int)(Math.ceil((double) pageable.getPageNumber() / blockLimit))) - 1) * blockLimit + 1;
    int endPage = Math.min(startPage + blockLimit - 1, noticeDTOS.getTotalPages());

    int prevPage = noticeDTOS.getNumber();
    int currentPage = noticeDTOS.getNumber() + 1;
    int nextPage = noticeDTOS.getNumber() + 2;
    int lastPage = noticeDTOS.getTotalPages();

    model.addAttribute("noticeDTOS", noticeDTOS);

    model.addAttribute("startPage", startPage);
    model.addAttribute("endPage", endPage);
    model.addAttribute("prevPage", prevPage);
    model.addAttribute("currentPage", currentPage);
    model.addAttribute("nextPage", nextPage);
    model.addAttribute("lastPage", lastPage);

    model.addAttribute("type", type);
    model.addAttribute("keyword", keyword);

    return "/admin/notice_list";
  }


  //공지상세
  @GetMapping("/admin_noticeread")
  public String detail(Integer noticeId, Model model) throws Exception {

    NoticeDTO noticeDTO = noticeService.findOne(noticeId);

    model.addAttribute("noticeDTO", noticeDTO);

    return "admin/notice_read";

  }


  //공지수정 폼
  @GetMapping("/admin_noticeupdate")
  public String noticeDetailForm(Integer noticeId, Model model) throws Exception {

    NoticeDTO noticeDTO = noticeService.findOne(noticeId);

    model.addAttribute("noticeDTO", noticeDTO);
    model.addAttribute("noticeRole", NoticeRole.values());

    return "/admin/notice_update";
  }
  //수정처리
  @PostMapping("/admin_noticeupdate")
  public String noticeDetailProc(@Valid NoticeDTO noticeDTO,
                                 BindingResult bindingResult,
                                 Model model) throws Exception {

    if(bindingResult.hasErrors()){
      model.addAttribute("noticeRole", NoticeRole.values());
      return "/admin/notice_update";
    } noticeService.update(noticeDTO);

    return "redirect:/admin_noticelist";
  }


  //공지삭제
  @GetMapping("/admin_noticeremove")
  public String noticeDelete(Integer noticeId) throws Exception{

    noticeService.delete(noticeId);

    return "redirect:/admin_noticelist";
  }

}

 

 


 

🟢 insert.html

더보기
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layouts/adminlayout}">

<head>
    <meta charset="utf-8">
    <title>ADMIN - Notice Insert</title>
</head>

<body>
<div layout:fragment="content">
    <div class="main-wrapper wrapper-2">

        <div class="breadcrumb-area breadcrumb-padding-8">
            <div class="container">
                <div class="breadcrumb-content text-center">
                    <div class="breadcrumb-title">
                        <h2>Notice</h2>
                    </div>
                </div>
            </div>
        </div>

        <div class="notice-area bg-white pb-130">
            <div class="container">
                <div class="notice-info-wrap">
                    <form th:action="@{/admin_noticeinsert}" method="post" th:object="${noticeDTO}">
                        <input type="hidden" name="noticeView" value="0">
                        <table class="table notice-table">
                            <tbody>
                            <tr>
                                <th scope="row" class="notice-padding">제목</th>
                                <td class="notice-info">
                                    <input type="text" name="noticeTitle" id="noticeTitle">
                                    <span class="text-danger" th:if="${#fields.hasErrors('noticeTitle')}" th:errors="*{noticeTitle}"></span>
                                </td>
                            </tr>
                            <tr>
                                <th scope="row" class="notice-padding">작성자</th>
                                <td class="notice-info">
                                    <input type="text" name="noticeWriter" id="noticeWriter">
                                    <span class="text-danger" th:if="${#fields.hasErrors('noticeWriter')}" th:errors="*{noticeWriter}"></span>
                                </td>
                            </tr>
                            <tr>
                                <th scope="row" class="notice-padding">공지유형</th>
                                <td>
                                    <div class="sidebar-widget update">
                                        <div class="sidebar-archive-wrap">
                                            <select name="noticeRole" id="noticeRole">
                                                <option value="" th:selected="${noticeRole == ''}"> == 선택 == </option>
                                                <option value="DELIVERY" th:selected="${noticeRole=='DELIVERY'}">배송공지</option>
                                                <option value="PRODUCT" th:selected="${noticeRole=='PRODUCT'}">상품공지</option>
                                                <option value="TIP" th:selected="${noticeRole=='TIP'}">청소꿀팁</option>
                                                <option value="EVENT" th:selected="${noticeRole=='EVENT'}">이벤트</option>
                                                <option value="POINT" th:selected="${noticeRole=='POINT'}">적립금</option>
                                                <option value="ETC" th:selected="${noticeRole=='ETC'}">기타</option>
                                            </select>
                                            <span class="text-danger" th:if="${#fields.hasErrors('noticeRole')}" th:errors="*{noticeRole}"></span>
                                        </div>
                                    </div>
                                </td>
                            </tr>
                            <tr>
                                <th scope="row" class="notice-padding">공지내용</th>
                                <td class="notice-info">
                                    <textarea rows="15" name="noticeContent" id="noticeContent"></textarea>
                                    <span class="text-danger" th:if="${#fields.hasErrors('noticeContent')}" th:errors="*{noticeContent}"></span>
                                </td>
                            </tr>
                            </tbody>
                        </table>
                        <div class="row">
                            <div class="col d-flex justify-content-center">
                                <div class="notice-button-container">
                                    <div class="notice-content">
                                        <div class="notice-btn-date-wrap list-btn">
                                            <div class="notice-btn">
                                                <button type="submit" class="btn btn-lg">등록</button>
                                                <button type="reset" class="btn btn-lg">다시</button>
                                                <button type="button" class="btn btn-lg" th:onclick="|location.href='@{/admin_noticelist}'|">취소</button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

 

 

 

🟢 list.html

 

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layouts/adminlayout}">

<head>
  <meta charset="utf-8">
  <title>ADMIN - Notice List</title>
</head>

<body>
<div layout:fragment="content">
  <div class="main-wrapper wrapper-2">
    <div class="breadcrumb-area breadcrumb-padding-8">

      <div class="container">
        <div class="breadcrumb-content text-center">
          <div class="breadcrumb-title">
            <h2>PRODUCT</h2>
          </div>
          <ul>
            <li>
              <a href="/admin_noticelist">공지목록</a>
            </li>
            <li>
              |
            </li>
            <li>
              <a href="/admin_noticeinsert">공지등록</a>
            </li>
          </ul>
        </div>
      </div>
    </div>

    <div class="wishlist-area bg-white pb-130">
      <div class="container">
        <div class="row justify-content-center">
          <div class="col-sm-4"></div>
          <div class="col-sm-8">
            <!-- 검색 폼 -->
            <form th:action="@{/admin_noticelist}" method="get" id="searchForm">
              <input type="hidden" name="page" value="1">
              <div class="input-group mb-3 mt-5">
                <!-- 대분류 셀렉트 리스트 -->
                <select class="form-select" name="type" id="searchType">
                  <option value="" th:selected="${type == ''}">== 선택 ==</option>
                  <option value="tc" th:selected="${type == 'tc'}">제목+내용</option>
                  <option value="r" th:selected="${type == 'r'}">공지유형</option>
                </select>

                <!-- 검색창 -->
                <input type="text" class="form-control" name="keyword" id="keyword" th:value="${keyword}" style="display: none;"></input>

                <!-- 중분류(공지유형) 셀렉트 리스트 -->
                <select class="form-select" name="noticeRole" id="noticeRole" style="display: none;">
                  <option value="" th:selected="${noticeRole == ''}">== 선택 ==</option>
                  <option value="DELIVERY" th:selected="${noticeRole == 'DELIVERY'}">배송공지</option>
                  <option value="PRODUCT" th:selected="${noticeRole == 'LIVING'}">상품공지</option>
                  <option value="TIP" th:selected="${noticeRole == 'TIP'}">청소꿀팁</option>
                  <option value="EVENT" th:selected="${noticeRole == 'EVENT'}">이벤트</option>
                  <option value="POINT" th:selected="${noticeRole == 'POINT'}">적립금</option>
                  <option value="ETC" th:selected="${noticeRole == 'ETC'}">기타</option>
                </select>

                <!-- 검색 버튼 -->
                <button type="submit" class="btn btn-primary admin-dart" name="searchButton">검색</button>

                <!-- 리셋 버튼 -->
                <button type="button" class="btn btn-light admin-light " name="searchButton" th:onclick="|location.href='@{/admin_noticelist}'|">다시</button>
              </div>
            </form>

            <!-- JavaScript 코드 -->
            <script>
                document.getElementById('searchType').addEventListener('change', function () {
                    resetSearchForm();
                });

                function resetSearchForm() {
                    var selectedSearchType = document.getElementById('searchType').value;
                    var selectedNoticeRole = document.getElementById('noticeRole').value;

                    applyStylesAfterSearch(selectedSearchType, selectedNoticeRole);
                    toggleElementDisplay('keyword', selectedSearchType === 'tc');
                }

                function applyStylesAfterSearch(searchType, noticeRole) {
                    toggleElementDisplay('noticeRole', searchType === 'r');

                    // 검색 타입이 제목+내용일 때 keyword 입력 필드를 보이게 설정
                    toggleElementDisplay('keyword', searchType === 'tc');

                    if (searchType === 'r') {
                        var noticeRoleElement = document.getElementById('noticeRole');
                        if (noticeRoleElement.value === '') {
                            noticeRoleElement.value = localStorage.getItem('selectedNoticeRole') || noticeRole;
                        }
                    }
                }

                function toggleElementDisplay(elementId, condition) {
                    var element = document.getElementById(elementId);
                    element.style.display = condition ? 'block' : 'none';
                }

                // 페이지 로드 시 초기 스타일 적용
                applyStylesAfterSearch(
                    document.getElementById('searchType').value,
                    document.getElementById('noticeRole').value
                );

                // 페이지 로드 시 localStorage에서 이전 선택 값을 가져와 적용
                window.onload = function () {
                    applyStylesAfterSearch(
                        document.getElementById('searchType').value,
                        document.getElementById('noticeRole').value,
                    );
                }

                // 페이지 언로드 시 localStorage에 현재 선택 값을 저장
                window.onbeforeunload = function () {
                    localStorage.setItem('selectedNoticeRole', document.getElementById('noticeRole').value);
                }
            </script>
          </div>
        </div>
      </div>

      <div class="row mb-20"></div>
      <div class="container">
        <div class="row">
          <div class="col-12">
            <form action="#">
              <div class="wishlist-table-content">
                <span class="table-content">
                  <table>
                    <thead>
                    <tr>
                      <th class="width-price">번호</th>
                      <th class="width-price">공지종류</th>   <!-- 정책공지, 배송공지, 상품공지, 이벤트, 기타 -->
                      <th class="width-price">제목</th>
                      <th class="width-price">작성자</th>
                      <th class="width-price">작성날짜</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr th:each="data:${noticeDTOS}">
                      <td th:text="${data.noticeId}"></td>

                      <td th:if="${data != null}">
                        <div th:if="${data.noticeRole != null}">
                          <div th:text="${data.noticeRole.description}"></div>
                        </div>
                        <div th:unless="${data.noticeRole != null}"></div>
                      </td>

                      <td>
                        <a th:href="@{/admin_noticeread(noticeId=${data.noticeId})}" th:text="${data.noticeTitle}"></a>
                      </td>

                      <td th:text="${data.noticeWriter}"></td>

                      <td>
                        <span th:text="${#temporals.format(data.reDate, 'yyyy-MM-dd')}"></span>
                      </td>
                    </tr>
                    </tbody>
                  </table>

                  <!-- 페이지 번호 추가 -->
                  <div class="pagination-style text-center mt-30" th:if="${lastPage > 1}">
                    <ul>
                      <li th:unless="${startPage == 1}">
                        <a th:href="@{/admin_noticelist(type=${type}, keyword=${keyword}, page=1)}">처음</a>
                      </li>
                      <li th:unless="${currentPage == 1}">
                        <a th:href="@{/admin_noticelist(type=${type}, keyword=${keyword}, page=${prevPage})}">&lt;</a>
                      </li>

                      <li th:each="page: ${#numbers.sequence(startPage, endPage)}">
                        <a th:if="${currentPage != page}" th:href="@{/admin_noticelist(type=${type}, keyword=${keyword}, page=${page})}">[[${page}]]</a>
                        <a th:if="${currentPage == page}" href="#" class="active">[[${page}]]</a>&nbsp;
                      </li>

                      <li th:unless="${currentPage == lastPage}">
                        <a th:href="@{/admin_noticelist(type=${type}, keyword=${keyword}, page=${nextPage})}">&gt;</a>
                      </li>
                      <li th:unless="${endPage == lastPage}">
                        <a th:href="@{/admin_noticelist(type=${type}, keyword=${keyword}, page=${lastPage})}">끝</a>
                      </li>
                    </ul>
                  </div>
                  <!-- 페이지 번호 추가 끝 -->
                </div>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- Main JS -->
  <script src="assets/js/main.js"></script>
</div>
</body>
</html>

 

 

🟢 detail.html

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layouts/adminlayout}">
<head>
  <meta charset="UTF-8">
  <title>Notice</title>
</head>

<body>
<div layout:fragment="content">
  <div class="main-wrapper wrapper-2">
    <div class="breadcrumb-area breadcrumb-padding-8">
      <div class="container">
        <div class="breadcrumb-content text-center">
          <div class="breadcrumb-title">
            <h2>Notice</h2>
          </div>
        </div>
      </div>
    </div>

    <div class="notice-area bg-white pb-130">
      <div class="container">
        <div class="notice-info-wrap">
          <table class="table notice-table">
            <tbody>
            <tr>
              <input type="hidden" name="noticeId" th:value="${noticeDTO.noticeId}">
              <th scope="row" class="notice-padding">제목</th>
              <td th:text="${noticeDTO.noticeTitle}" readonly></td>
            </tr>
            <tr>
              <th scope="row" class="notice-padding">작성자</th>
              <td th:text="${noticeDTO.noticeWriter}" readonly></td>
            </tr>
            <tr>
              <th scope="row" class="notice-padding">공지유형</th>
              <td th:text="${noticeDTO.noticeRole.description}" readonly></td>
            </tr>
            <tr>
              <th scope="row" class="notice-padding">공지내용</th>
              <td class="notice-info">
                  <textarea rows="15" th:text="${noticeDTO.noticeContent}" name="noticeContent" readonly></textarea>
              </td>
            </tr>
            </tbody>
          </table>
          <div class="row">
            <div class="col d-flex justify-content-center">
              <div class="notice-button-container">
                <div class="notice-content">
                  <div class="notice-btn-date-wrap list-btn">
                    <div class="notice-btn">
                      <button type="button" class="btn btn-lg"
                              th:onclick="|location.href='@{/admin_noticeupdate(noticeId=${noticeDTO.noticeId})}'|">수정</button>
                      <button type="button" class="btn btn-lg"
                              th:onclick="|location.href='@{/admin_noticelist}'|">목록</button>
                      <button type="button" class="btn btn-lg"
                              th:onclick="|location.href='@{/admin_noticeremove(noticeId=${noticeDTO.noticeId})}'|">삭제</button>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- Main JS -->
  <script src="assets/js/main.js"></script>
</div>
</body>
</html>

 

🟢 update.html

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layouts/adminlayout}">

<head>
    <meta charset="utf-8">
    <title>ADMIN - Notice Update</title>
</head>

<body>
<div layout:fragment="content">
    <div class="main-wrapper wrapper-2">
        <div class="breadcrumb-area breadcrumb-padding-8">
            <div class="container">
                <div class="breadcrumb-content text-center">
                    <div class="breadcrumb-title">
                        <h2>Notice</h2>
                    </div>
                </div>
            </div>
        </div>

        <div class="notice-area bg-white pb-130">
            <div class="container">
                <div class="notice-info-wrap">
                    <form th:action="@{/admin_noticeupdate}" method="post" th:object="${noticeDTO}">
                        <input type="hidden" name="noticeId" th:value="*{noticeId}">
                        <input type="hidden" name="reDate" th:value="*{reDate}">
                        <input type="hidden" name="modDate" th:value="*{modDate}">
                        <table class="table notice-table">
                            <tbody>
                            <tr>
                                <th scope="row" class="notice-padding">제목</th>
                                <td class="notice-info">
                                    <input type="text" id="noticeTitle" name="noticeTitle" th:field="*{noticeTitle}">
                                    <span class="text-danger" th:if="${#fields.hasErrors('noticeTitle')}" th:errors="*{noticeTitle}"></span>
                                </td>
                            </tr>
                            <tr>
                                <th scope="row" class="notice-padding">작성자</th>
                                <td class="notice-info">
                                    <input type="text" id="noticeWriter" name="noticeWriter" th:field="*{noticeWriter}" >
                                    <span class="text-danger" th:if="${#fields.hasErrors('noticeWriter')}" th:errors="*{noticeWriter}"></span>
                                </td>
                            </tr>

                            <tr>
                                <th scope="row" class="notice-padding">공지유형</th>
                                <td>
                                    <div class="sidebar-widget update">
                                        <div class="sidebar-archive-wrap">
                                            <select id="noticeRole" name="noticeRole">
                                                <option th:each="state : ${noticeRole}"
                                                        th:value="${state.name()}"
                                                        th:text="${state.getDescription()}"
                                                        th:selected="${state.name() eq noticeDTO.noticeRole?.name()}">
                                                </option>
                                            </select>
                                        </div>
                                    </div>
                                    <span class="text-danger" th:if="${#fields.hasErrors('noticeRole')}" th:errors="*{noticeRole}"></span>
                                </td>
                            </tr>
                            <tr>
                                <th scope="row" class="notice-padding">공지내용</th>
                                <td class="notice-info">
                                    <textarea rows="15" th:field="*{noticeContent}" name="noticeContent">
                                        공지내용
                                    </textarea>
                                    <span class="text-danger" th:if="${#fields.hasErrors('noticeContent')}" th:errors="*{noticeContent}"></span>
                                </td>
                            </tr>
                            </tbody>
                        </table>
                        <div class="row">
                            <div class="col d-flex justify-content-center">
                                <div class="notice-button-container">
                                    <div class="notice-content">
                                        <div class="notice-btn-date-wrap list-btn">
                                            <div class="notice-btn">
                                                <button type="submit" class="btn btn-lg">수정</button>
                                                <button type="reset" class="btn btn-lg">다시</button>
                                                <button type="button" class="btn btn-lg" th:onclick="|location.href='@{/admin_noticelist}'|">취소</button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>
반응형