瀏覽代碼

관리자 페이지 공지 관리 개발

inkoreakim 2 年之前
父節點
當前提交
993bf1132c

+ 26 - 4
src/main/java/com/example/ili_web/board/controller/BoardController.java

@@ -71,8 +71,8 @@ public class BoardController {
      @return -> insertBoard
      date -> 2024.03.14
      **/
-    @PostMapping("/board/add")
-    public ResponseEntity insertBoard (BoardInfoReq req, @RequestPart("files") List<MultipartFile> files) throws IOException {
+    @PostMapping("/board")
+    public ResponseEntity insertBoard (BoardInfoReq req, @RequestPart(value = "files", required = false) List<MultipartFile> files) throws IOException {
         log.info("========== Insert Board Data ==========");
         boardService.insertBoard(req, files);
         return ResponseEntity.ok(null);
@@ -107,7 +107,6 @@ public class BoardController {
     /**
      * method -> getBoardDetail
      * description -> 게시판 상세 가져오기
-     *
      * @return -> BoardRes
      * date -> 2024.03.20
      * @author -> 김주한
@@ -117,5 +116,28 @@ public class BoardController {
         log.info("========== Get Board Detail ==========");
         return ResponseEntity.ok(boardService.getBoardDetail(req));
     }
-    
+
+    /**
+     * method -> updateBoardDetail
+     * description -> 게시판 내용 수정
+     * @return -> SuccessRes
+     * date -> 2024.03.26
+     * @author -> 김주한
+     **/
+    @PatchMapping("/board/detail")
+    public ResponseEntity<?> updateBoardDetail (@RequestBody BoardReq req) {
+        return ResponseEntity.ok(boardService.updateBoardDetail(req));
+    }
+
+    /**
+     * method -> deleteBoard
+     * description -> 게시판 내용 삭제
+     * @return -> SuccessRes
+     * date -> 2024.03.26
+     * @author -> 김주한
+     **/
+    @DeleteMapping("/board")
+    public ResponseEntity<?> deleteBoard (BoardReq req) {
+        return ResponseEntity.ok(boardService.deleteBoard(req));
+    }
 }

+ 5 - 1
src/main/java/com/example/ili_web/board/domain/Board.java

@@ -19,7 +19,7 @@ public class Board {
     private Long id;
     @Column(nullable = false)
     private String userName;
-    @Column(nullable = false)
+    @Column
     private String password;
     @Column
     private String company;
@@ -62,5 +62,9 @@ public class Board {
         this.upDt = LocalDateTime.now();
     }
 
+    public void updateContent (String content) {
+        this.content = content;
+        this.upDt = LocalDateTime.now();
+    }
 
 }

+ 2 - 0
src/main/java/com/example/ili_web/board/dto/BoardReq.java

@@ -5,9 +5,11 @@ import lombok.Data;
 @Data
 public class BoardReq {
     private Long id;
+    private String title;
     private String password;
     private String userName;
     private String type;
+    private String content;
     private int page;
     private int offset;
     private int limit;

+ 3 - 2
src/main/java/com/example/ili_web/board/repository/BoardCustomRepository.java

@@ -1,9 +1,10 @@
 package com.example.ili_web.board.repository;
 
 import com.example.ili_web.board.dto.BoardFileDTO;
+import org.springframework.stereotype.Repository;
 
 import java.util.List;
-
+@Repository
 public interface BoardCustomRepository {
-    void boardFileInsert(List<BoardFileDTO> list);
+
 }

+ 2 - 0
src/main/java/com/example/ili_web/board/repository/BoardFileRepository.java

@@ -2,6 +2,8 @@ package com.example.ili_web.board.repository;
 
 import com.example.ili_web.board.domain.BoardFile;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
 
+@Repository
 public interface BoardFileRepository extends JpaRepository<BoardFile, Long> {
 }

+ 0 - 21
src/main/java/com/example/ili_web/board/repository/BoardRepositoryImpl.java

@@ -1,21 +0,0 @@
-package com.example.ili_web.board.repository;
-
-import com.example.ili_web.board.dto.BoardFileDTO;
-import jakarta.persistence.EntityManager;
-import jakarta.persistence.PersistenceContext;
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-
-@Repository
-public class BoardRepositoryImpl implements BoardCustomRepository{
-    @PersistenceContext
-    private EntityManager em;
-
-    @Transactional
-    @Override
-    public void boardFileInsert(List<BoardFileDTO> list) {
-        String sql = "INSERT INTO board_file (board_id, file_path, use_yn, reg_dt, up_dt) VALUES (?, ?, ?, ?, ?)";
-    }
-}

+ 29 - 15
src/main/java/com/example/ili_web/board/service/BoardService.java

@@ -100,21 +100,23 @@ public class BoardService {
         Board board = new Board(req);
         repository.save(board);
 
-        List<BoardFileDTO> fileList = new ArrayList<>();
-        for (int i = 0; i < file.size(); i++) {
-            BoardFileDTO dto = new BoardFileDTO();
-            dto.setFilePath("/"+req.getType()+"/Board" + board.getId()+"/"+file.get(i).getOriginalFilename());
-            dto.setBoardId(board);
-            fileList.add(dto);
+        if (file != null) {
+            List<BoardFileDTO> fileList = new ArrayList<>();
+            for (MultipartFile multipartFile : file) {
+                BoardFileDTO dto = new BoardFileDTO();
+                dto.setFilePath("/" + req.getType() + "/Board" + board.getId() + "/" + multipartFile.getOriginalFilename());
+                dto.setBoardId(board);
+                fileList.add(dto);
+            }
+
+            insertFile(fileList);
+
+            String osPath = osProperty();
+            if (!file.isEmpty()) {
+                String filePath = osPath + "/" + req.getType() + "/Board" + board.getId()+"/";
+                fileUpload(filePath, file);
+            }
         }
-        insertFile(fileList);
-
-        String osPath = osProperty();
-        if (!file.isEmpty()) {
-            String filePath = osPath + "/" + req.getType() + "/Board" + board.getId()+"/";
-            fileUpload(filePath, file);
-        }
-
     }
 
     @Transactional
@@ -124,7 +126,6 @@ public class BoardService {
             BoardFile file = new BoardFile(dto);
             fList.add(file);
         }
-        log.info(fList.get(0).getFilePath());
         fileRepository.saveAll(fList);
     }
 
@@ -163,4 +164,17 @@ public class BoardService {
     public Optional<Board> getBoardDetail(BoardReq req) {
         return repository.findById(req.getId());
     }
+
+    @Transactional
+    public SuccessRes updateBoardDetail(BoardReq req) {
+        Board board = repository.findById(req.getId()).orElseThrow(() -> new EntityNotFoundException("Board Not Found"));
+        board.updateContent(req.getContent());
+        return new SuccessRes("200", "update success");
+    }
+
+    public SuccessRes deleteBoard(BoardReq req) {
+        Board board = repository.findById(req.getId()).orElseThrow(() -> new EntityNotFoundException("Board Not Found"));
+        repository.delete(board);
+        return new SuccessRes("200", "delete success");
+    }
 }

+ 27 - 2
src/main/resources/static/js/admin/adminChangeInner.js

@@ -5,17 +5,42 @@ async function adminChangeInner(name) {
     if (name === 'admin-notice') {
         code = 'NT';
         target = 'notice_list_table';
+    } else {
+        code = 'LG';
+        target = 'admin_advice_table';
     }
     // html 가져오기
     await axios.get(`/html/admin/${name}.html`)
         .then(async (res) => {
             element.innerHTML = res.data;
             const list = await getList(code, 1);
-            console.log(list);
             target = document.getElementById(target);
             adminMakeTable(list.data.dataList, target, code);
             adminMakePagenation(list.data, code);
-            //clearModal();
+        })
+}
+
+async function goToDetail(id, type) {
+    const target = document.getElementById('admin_section');
+    let htmlName = '';
+    if (type === 'NT' || type === 'GD') {
+        htmlName = 'admin-notice-detail';
+    } else {
+        htmlName = 'admin-advice-detail';
+    }
+    await axios.get(`/html/admin/${htmlName}.html`)
+        .then(res => {
+            target.innerHTML = res.data;
+        })
+    let response = await getDetail(id);
+    bindNotice(response.data);
+}
+
+function goToInsert() {
+    const element = document.getElementById('admin_section');
+    axios.get(`/html/admin/admin-notice-insert.html`)
+        .then(async (res) => {
+            element.innerHTML = res.data;
         })
 }
 

+ 15 - 2
src/main/resources/static/js/admin/adminGetData.js

@@ -6,6 +6,19 @@ async function getList(type, page) {
     }
 }
 
-async function goToDetail(title, userName, regDt, content) {
-    console.log(title);
+function getDetail(id) {
+    return axios.get('/api/v1/board/detail', {params : {id}})
+
+}
+
+function bindNotice (data) {
+    document.getElementById('board_id').value = data.id;
+    document.getElementById('board_title').innerText = data.title;
+    document.getElementById('board_info').innerText = makeInfo(data.userName, data.regDt);
+    document.getElementById('board_content').innerText = data.content;
+    document.getElementById('board_edit_content').innerText = data.content;
+}
+
+function makeInfo (userName, regDt) {
+    return `${userName} - ${regDt}`;
 }

+ 1 - 1
src/main/resources/static/js/admin/adminMakeHtml.js

@@ -2,7 +2,7 @@ function adminMakeTable(list, target, code) {
     let html = '';
     for (let data of list) {
         html += '<tr>';
-        html += `<td><a href="javascript:void(0);" onclick="goToDetail('${data.title}', '${data.userName}', '${data.regDt}','${data.content}')">${data.title}</a></td>`;
+        html += `<td><a href="javascript:void(0);" onclick="goToDetail('${data.id}','${data.type}')">${data.title}</a></td>`;
         html += `<td>${data.userName}</td>`;
         html += `<td>${data.type === 'NT' ? '공지' : '안내'}</td>`;
         html += `<td>${formatDate(data.regDt)}</td>`;

+ 0 - 0
src/main/resources/static/js/admin/adminNotice.js


+ 65 - 0
src/main/resources/static/js/admin/adminPublic.js

@@ -0,0 +1,65 @@
+function editBoard () {
+    document.getElementById('board_edit_content').style.display = 'flex';
+    document.getElementById('saveBtn').style.display = 'inline-block';
+    document.getElementById('board_content').style.display = 'none';
+    document.getElementById('editBtn').style.display = 'none';
+}
+
+function saveEdit() {
+    const id = document.getElementById('board_id').value;
+    const content = document.getElementById('board_edit_content').value;
+    axios.patch('/api/v1/board/detail', {id, content})
+        .then(res => {
+            if (res.status === 200) {
+                adminChangeInner('admin-notice');
+            }
+        })
+        .catch(error => {
+
+        })
+}
+
+function deleteBoard() {
+    if (confirm('정말 삭제 하시겠습니까?')) {
+        const id = document.getElementById('board_id').value;
+        axios.delete('/api/v1/board', {params : {id}})
+            .then(res => {
+                if (res.status === 200) {
+                    alert('삭제가 완료되었습니다.')
+                    adminChangeInner('admin-notice');
+                }
+            })
+            .catch(error => {
+                console.log(error)
+            })
+    }
+}
+
+function insertBoard() {
+    const content = document.getElementById('board_content').value;
+    const title = document.getElementById('board_title').value;
+    const userName = document.getElementById('board_user_name').value;
+    const type = document.getElementById('board_type').value;
+    if (nullCheck(title)) {alert('제목을 입력하세요.'); return false}
+    if (nullCheck(content)) {alert('내용을 입력하세요.'); return false}
+    if (nullCheck(userName)) {alert('이름을 입력하세요.'); return false}
+    if (nullCheck(type)) {alert('타입을 입력하세요.'); return false}
+    let formData = new FormData();
+    formData.append('title', title);
+    formData.append('content', content);
+    formData.append('userName', userName);
+    formData.append('type', type);
+    axios.post('/api/v1/board', formData)
+        .then(res=>{
+            alert('저장이 완료되었습니다.')
+            adminChangeInner('admin-notice');
+
+        })
+        .catch(error=>{
+
+        })
+}
+
+function nullCheck (data) {
+    return !data || !data.trim();
+}

+ 1 - 1
src/main/resources/static/js/contact/advice.js

@@ -41,7 +41,7 @@ function subForm() {
                 formData.append('files', file[0]);
             }
         }
-        axios.post('api/v1/board/add', formData)
+        axios.post('api/v1/board', formData)
             .then(function (res) {
                 alert('신청이 완료되었습니다.');
                 clearApply();

+ 22 - 0
src/main/resources/templates/html/admin/admin-advice.html

@@ -0,0 +1,22 @@
+<div style="display: flex; justify-content: space-between; align-items: center;">
+    <h2>물류상담</h2>
+    <button type="button" class="btn btn-success" onclick="goToInsert()">게시글 작성</button>
+</div>
+<div class="table-responsive" id="admin_advice_table">
+    <table class="table table-striped table-sm" >
+        <thead>
+        <tr>
+            <th scope="col" >제목</th>
+            <th scope="col">작성자</th>
+            <th scope="col">구분</th>
+            <th scope="col">등록일</th>
+        </tr>
+        </thead>
+        <tbody id="notice_list_table">
+
+        </tbody>
+    </table>
+    <nav aria-label="Page navigation" id="page_tag">
+
+    </nav>
+</div>

+ 15 - 7
src/main/resources/templates/html/admin/admin-notice-detail.html

@@ -1,11 +1,19 @@
-<div class="card">
-    <div class="card-header">
-        게시글 제목
-        <button type="button" class="btn btn-primary">수정</button>
-        <button type="button" class="btn btn-danger">삭제</button>
+<div class="card my-4">
+    <input type="hidden" id="board_id">
+    <div class="card-header d-flex justify-content-between align-items-center">
+        <div>
+            <span class="fw-bold" id="board_title">게시글 제목</span>
+            <span class="mx-2">|</span>
+            <span class="text-muted" id="board_info">작성자명 - 2024-03-12</span>
+        </div>
+        <div>
+            <button type="button" class="btn btn-primary" onclick="editBoard()" id="editBtn">수정</button>
+            <button type="button" class="btn btn-success" onclick="saveEdit()" id="saveBtn" style="display: none">저장</button>
+            <button type="button" class="btn btn-danger" id="delBtn" onclick="deleteBoard()">삭제</button>
+        </div>
     </div>
     <div class="card-body">
-        <h5 class="card-title">작성자명 - <small>2024-03-12</small></h5>
-        <p class="card-text">게시글 내용이 여기에 들어갑니다. 게시글에 대한 상세한 내용을 추가하세요.</p>
+        <p class="card-text" id="board_content">게시글 내용이 여기에 들어갑니다. 게시글에 대한 상세한 내용을 추가하세요.</p>
+        <textarea class="form-control" id="board_edit_content" rows="15" style="display: none"></textarea>
     </div>
 </div>

+ 24 - 0
src/main/resources/templates/html/admin/admin-notice-insert.html

@@ -0,0 +1,24 @@
+<div class="container mt-5">
+    <form>
+        <div class="row mb-5">
+            <div class="col-md-4">
+                <input type="text" class="form-control" id="board_title" placeholder="제목">
+            </div>
+            <div class="col-md-4">
+                <input type="text" class="form-control" id="board_user_name" placeholder="작성자">
+            </div>
+            <div class="col-md-4">
+                <select class="form-control" id="board_type">
+                    <option value="NT">공지</option>
+                    <option value="GD">안내</option>
+                </select>
+            </div>
+        </div>
+
+
+        <div class="form-group mb-5 mt-5">
+            <textarea class="form-control" id="board_content" rows="5" placeholder="내용을 입력하세요"></textarea>
+        </div>
+        <button type="button" class="btn btn-success" onclick="insertBoard()">저장</button>
+    </form>
+</div>

+ 5 - 113
src/main/resources/templates/html/admin/admin-notice.html

@@ -1,4 +1,7 @@
-<h2>공지 목록</h2>
+<div style="display: flex; justify-content: space-between; align-items: center;">
+    <h2>공지 / 안내</h2>
+    <button type="button" class="btn btn-success" onclick="goToInsert()">게시글 작성</button>
+</div>
 <div class="table-responsive" id="admin_notice_table">
     <table class="table table-striped table-sm" >
         <thead>
@@ -10,118 +13,7 @@
         </tr>
         </thead>
         <tbody id="notice_list_table">
-        <tr>
-            <td>1,001</td>
-            <td>random</td>
-            <td>data</td>
-            <td>placeholder</td>
-            <td>text</td>
-        </tr>
-        <tr>
-            <td>1,002</td>
-            <td>placeholder</td>
-            <td>irrelevant</td>
-            <td>visual</td>
-            <td>layout</td>
-        </tr>
-        <tr>
-            <td>1,003</td>
-            <td>data</td>
-            <td>rich</td>
-            <td>dashboard</td>
-            <td>tabular</td>
-        </tr>
-        <tr>
-            <td>1,003</td>
-            <td>information</td>
-            <td>placeholder</td>
-            <td>illustrative</td>
-            <td>data</td>
-        </tr>
-        <tr>
-            <td>1,004</td>
-            <td>text</td>
-            <td>random</td>
-            <td>layout</td>
-            <td>dashboard</td>
-        </tr>
-        <tr>
-            <td>1,005</td>
-            <td>dashboard</td>
-            <td>irrelevant</td>
-            <td>text</td>
-            <td>placeholder</td>
-        </tr>
-        <tr>
-            <td>1,006</td>
-            <td>dashboard</td>
-            <td>illustrative</td>
-            <td>rich</td>
-            <td>data</td>
-        </tr>
-        <tr>
-            <td>1,007</td>
-            <td>placeholder</td>
-            <td>tabular</td>
-            <td>information</td>
-            <td>irrelevant</td>
-        </tr>
-        <tr>
-            <td>1,008</td>
-            <td>random</td>
-            <td>data</td>
-            <td>placeholder</td>
-            <td>text</td>
-        </tr>
-        <tr>
-            <td>1,009</td>
-            <td>placeholder</td>
-            <td>irrelevant</td>
-            <td>visual</td>
-            <td>layout</td>
-        </tr>
-        <tr>
-            <td>1,010</td>
-            <td>data</td>
-            <td>rich</td>
-            <td>dashboard</td>
-            <td>tabular</td>
-        </tr>
-        <tr>
-            <td>1,011</td>
-            <td>information</td>
-            <td>placeholder</td>
-            <td>illustrative</td>
-            <td>data</td>
-        </tr>
-        <tr>
-            <td>1,012</td>
-            <td>text</td>
-            <td>placeholder</td>
-            <td>layout</td>
-            <td>dashboard</td>
-        </tr>
-        <tr>
-            <td>1,013</td>
-            <td>dashboard</td>
-            <td>irrelevant</td>
-            <td>text</td>
-            <td>visual</td>
-        </tr>
-        <tr>
-            <td>1,014</td>
-            <td>dashboard</td>
-            <td>illustrative</td>
-            <td>rich</td>
-            <td>data</td>
-        </tr>
-        <tr>
-            <td>1,015</td>
-            <td>random</td>
-            <td>tabular</td>
-            <td>information</td>
-            <td>text</td>
-        </tr>
+
         </tbody>
     </table>
     <nav aria-label="Page navigation" id="page_tag">

+ 1 - 1
src/main/resources/templates/html/admin/backoffice.html

@@ -73,7 +73,7 @@
     </div>
 </div>
 <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
-<script src="/js/admin/adminNotice.js"></script>
+<script src="/js/admin/adminPublic.js"></script>
 <script src="/js/admin/adminGetData.js"></script>
 <script src="/js/admin/adminChangeInner.js"></script>
 <script src="/js/admin/adminMakeHtml.js"></script>