jichoi / lms_front star
PsHooN7979 2024-08-07
240807 박세훈 선생님 게시판
@c4cce0ff83b111afd2c37523247579685c1773cb
client/views/pages/teacher/Board.vue
--- client/views/pages/teacher/Board.vue
+++ client/views/pages/teacher/Board.vue
@@ -1,95 +1,224 @@
 <template>
-    <div class="title-box flex justify-between mb40">
-        <p class="title">게시판</p>
-        <select name="" id="">
-            <option value="">A반</option>
-        </select>
+  <div class="title-box flex justify-between mb40">
+    <p class="title">게시판</p>
+    <select name="" id="">
+      <option value="">A반</option>
+    </select>
+  </div>
+  <div class="search-wrap flex justify-end mb20">
+    <select v-model="selectedSearchOption" class="mr10 data-wrap">
+      <option value="bbsTtl">제목</option>
+      <option value="bbsCnt">내용</option>
+      <option value="userNm">작성자</option>
+      <option value="bbsCls">카테고리</option>
+    </select>
+    <input
+      v-model="searchKeyword"
+      type="text"
+      placeholder="검색하세요."
+      @keyup.enter="boardDataSearch"
+    />
+    <button type="button" @click="boardDataSearch()" title="게시글 검색">
+      <img src="../../../resources/img/look_t.png" alt="" />
+    </button>
+  </div>
+  <div class="table-wrap">
+    <table>
+      <thead>
+        <td>No.</td>
+        <td>제목</td>
+        <td>카테고리</td>
+        <td>작성자</td>
+        <td>등록일</td>
+      </thead>
+      <tbody>
+        <tr
+          v-for="(item, index) in dataList"
+          :key="item.id"
+          :class="{ 'selected-row': selectedRow == item.dataList }"
+          @click="[goToPage('noticeDetail'), selectBoardList(item)]"
+        >
+          <td>{{ totalBoard - index }}</td>
+          <td>{{ item.bbsTtl }}</td>
+          <td>{{ item.bbsCls }}</td>
+          <td>{{ userNm }}</td>
+          <td>{{ item.bbsTm }}</td>
+        </tr>
+      </tbody>
+    </table>
+    <article
+      class="table-pagination flex justify-center align-center mb20 mt30"
+      style="gap: 10px"
+    >
+      <button>
+        <img
+          src="../../../resources/img/btn27_90t_normal.png"
+          alt=""
+          @click="previousPage"
+          :disabled="page === 1"
+        />
+      </button>
+      <button class="selected-btn">{{ page }}</button>
+      <button>
+        <img
+          src="../../../resources/img/btn28_90t_normal.png"
+          alt=""
+          @click="nextPage"
+          :disabled="page === totalPages"
+        />
+      </button>
+    </article>
+    <div class="flex justify-end">
+      <button
+        type="button"
+        title="글쓰기"
+        class="new-btn"
+        @click="goToPage('noticeInsert')"
+      >
+        글쓰기
+      </button>
     </div>
-    <div class="search-wrap flex justify-end mb20">
-            <select name="" id="" class="mr10 data-wrap">
-                <option value="">전체</option>
-            </select>
-                <input  type="text" placeholder="검색하세요.">
-                <button type="button" title="위원회 검색">
-                    <img src="../../../resources/img/look_t.png" alt="">
-                </button>
-        </div>
-        <div class="table-wrap">
-            <table>
-                <thead>
-                    <td>No.</td>
-                    <td>제목</td>
-                    <td>카테고리</td>
-                    <td>작성자</td>
-                    <td>등록일</td>
-                </thead>
-                <tbody>
-                    <tr @click="goToPage('noticeDetail')">
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                    </tr>
-                </tbody>
-            </table>
-            <article class="table-pagination flex justify-center align-center mb20 mt30" style="gap: 10px;">
-                    <button><img src="../../../resources/img/btn27_90t_normal.png" alt=""></button>
-                    <button class="selected-btn">1</button>
-                    <button>2</button>
-                    <button>3</button>
-                    <button><img src="../../../resources/img/btn28_90t_normal.png" alt=""></button>
-                </article>
-                <div class="flex justify-end ">
-                <button type="button" title="글쓰기" class="new-btn" @click="goToPage('noticeInsert')">
-                    글쓰기
-                </button>
-        </div>
-        </div>
+  </div>
 </template>
 
 <script>
-import SvgIcon from '@jamescoyle/vue-icon';
-import { mdiMagnify} from '@mdi/js';
-
+import SvgIcon from "@jamescoyle/vue-icon";
+import { mdiMagnify } from "@mdi/js";
+import axios from "axios";
 
 export default {
-    data () {
-        return {
-            mdiMagnify: mdiMagnify,
-        }
-    },
-    methods: {
-        goToPage(page) {
-         this.$router.push({ name: page });
-      },
-      showConfirm(type) {
-            let message = '';
-            if (type === 'cancel') {
-                message = '삭제하시겠습니까?';
-            } else if (type === 'reset') {
-                message = '초기화하시겠습니까?';
-            } else if (type === 'save') {
-                message = '등록하시겠습니까?';
-            }
+  data() {
+    return {
+      mdiMagnify: mdiMagnify,
 
-            if (confirm(message)) {
-                this.goBack();
-            }
+      // 게시글 정보
+      dataList: [],
+      totalBoard: null,
+      selectedRow: "",
+
+      // 페이징
+      page: 1,
+      pageSize: 8,
+      totalPages: null,
+
+      // 반 아이디 (추후 세션에서 받는걸로 수정)
+      sclsId: "1",
+
+      // 검색어
+      searchKeyword: "",
+      selectedSearchOption: "bbsTtl",
+    };
+  },
+  methods: {
+    goToPage(page) {
+      this.$router.push({ name: page });
+    },
+    showConfirm(type) {
+      let message = "";
+      if (type === "cancel") {
+        message = "삭제하시겠습니까?";
+      } else if (type === "reset") {
+        message = "초기화하시겠습니까?";
+      } else if (type === "save") {
+        message = "등록하시겠습니까?";
+      }
+
+      if (confirm(message)) {
+        this.goBack();
+      }
+    },
+
+    // 게시글 전체 조회
+    boardList() {
+      const vm = this;
+      axios({
+        url: "/board/findAll.json",
+        method: "post",
+        headers: {
+          "Content-Type": "application/json; charset=UTF-8",
         },
+        data: { page: vm.page, pageSize: vm.pageSize, sclsId: vm.sclsId },
+      })
+        .then(function (res) {
+          console.log("dataList - response : ", res.data);
+          console.log(res.data.result[0].boardClass[0].board);
 
+          vm.dataList = res.data.result[0].boardClass[0].board;
+          vm.userNm = res.data.result[0].userNm;
+          vm.userId = res.data.result[0].userId;
+          vm.totalBoard = res.data.totalBoard;
+          vm.totalPages = Math.ceil(vm.totalBoard / vm.pageSize);
+        })
+        .catch(function (error) {
+          console.log("result - error : ", error);
+          alert("비상 비상!");
+        });
     },
-    watch: {
 
+    // 게시글 정보 세션에 저장
+    selectBoardList(item) {
+      sessionStorage.setItem("selectedBoardList", JSON.stringify(item));
     },
-    computed: {
-       
+
+    // 반 아이디 세션에 저장
+    setClassId() {
+      sessionStorage.setItem("sclsId", JSON.stringify(this.sclsId));
     },
-    components:{
-        SvgIcon
+
+    // 게시글 검색
+    boardDataSearch() {
+      const vm = this;
+      let searchPayload = {
+        keyword: vm.searchKeyword,
+        option: vm.selectedSearchOption,
+        page: vm.page,
+        pageSize: vm.pageSize,
+        sclsId: vm.sclsId,
+      };
+      axios({
+        url: "/board/search.json",
+        method: "post",
+        headers: {
+          "Content-Type": "application/json; charset=UTF-8",
+        },
+        data: searchPayload,
+      })
+        .then(function (res) {
+          console.log("boardDataSearch - response : ", res.data);
+          vm.dataList = res.data.result[0].boardClass[0].board;
+          vm.userNm = res.data.result[0].userNm;
+          vm.userId = res.data.result[0].userId;
+          vm.totalBoard = res.data.totalBoard;
+        })
+        .catch(function (error) {
+          console.log("dataSearch - error : ", error);
+          alert("게시글이 존재하지 않습니다.");
+        });
     },
-    mounted() {
-        console.log('Main2 mounted');
-    }
-}
-</script>
(No newline at end of file)
+
+    previousPage() {
+      if (this.page > 1) {
+        this.page -= 1;
+        this.boardList();
+      }
+    },
+
+    nextPage() {
+      if (this.page < this.totalPages) {
+        this.page += 1;
+        this.boardList();
+      }
+    },
+  },
+  watch: {},
+  computed: {},
+  components: {
+    SvgIcon,
+  },
+  mounted() {
+    console.log("Main2 mounted");
+    this.boardList();
+    this.setClassId();
+  },
+};
+</script>
client/views/pages/teacher/noticeInsert.vue
--- client/views/pages/teacher/noticeInsert.vue
+++ client/views/pages/teacher/noticeInsert.vue
@@ -1,57 +1,113 @@
 <template>
-    <div class="title-box flex justify-between mb40">
-        <p class="title">공지 등록</p>
-    </div>
-        <div class="board-wrap">
-            <div class="flex align-center">
-                <label for="" class="title2">제목</label>
-                <input type="text" class="data-wrap">
-            </div>
-            <hr>
-            <textarea name="" id=""></textarea>
-            <hr>
-            <div class="flex align-center">
-                <label for="" class="title2">첨부파일</label>
-                <input type="file" ref="fileInput" @change="handleFileUpload" />
-            </div>
-        </div>
-        <div class="flex justify-between mt50">
-                <button type="button" title="글쓰기" class="new-btn"  @click="goToPage('Board')">
-                    목록
-                </button>
-                <button type="button" title="글쓰기" class="new-btn"  @click="goToPage('Board')">
-                     등록
-                </button>
-        </div>
+  <div class="title-box flex justify-between mb40">
+    <p class="title">공지 등록</p>
+  </div>
+  <div class="board-wrap">
+    <form @submit.prevent="handleSubmit">
+      <div class="flex align-center">
+        <label for="title" class="title2">제목</label>
+        <input type="text" id="title" class="data-wrap" v-model="title" />
+      </div>
+      <hr />
+      <textarea name="" id="content" v-model="content"></textarea>
+      <hr />
+      <div class="flex align-center">
+        <label for="file" class="title2">첨부파일</label>
+        <input type="file" ref="fileInput" @change="handleFileUpload" />
+      </div>
+      <div class="flex justify-between mt50">
+        <button title="글쓰기" class="new-btn" @click="goToPage('Board')">
+          목록
+        </button>
+        <button title="글쓰기" class="new-btn">등록</button>
+      </div>
+    </form>
+  </div>
 </template>
 
 <script>
-import SvgIcon from '@jamescoyle/vue-icon';
-import { mdiMagnify} from '@mdi/js';
-
+import SvgIcon from "@jamescoyle/vue-icon";
+import { mdiMagnify } from "@mdi/js";
+import axios from "axios";
 
 export default {
-    data () {
-        return {
-            mdiMagnify: mdiMagnify,
-        }
-    },
-    methods: {
-        goToPage(page) {
-         this.$router.push({ name: page });
-      },
-    },
-    watch: {
+  data() {
+    return {
+      mdiMagnify: mdiMagnify,
 
+      title: "",
+      content: "",
+      category: "Notice",
+      sclsId: "",
+      selectedFile: null,
+    };
+  },
+  methods: {
+    goToPage(page) {
+      this.$router.push({ name: page });
     },
-    computed: {
-       
+
+    handleFileUpload(e) {
+      this.selectedFile = e.target.files[0];
+      console.log(this.selectedFile);
     },
-    components:{
-        SvgIcon
+
+    created() {
+      const vm = this;
+      const sclsId = JSON.parse(sessionStorage.getItem("sclsId"));
+
+      if (sclsId) {
+        vm.sclsId = sclsId;
+      }
+      console.log(sclsId);
     },
-    mounted() {
-        console.log('Main2 mounted');
-    }
-}
-</script>
(No newline at end of file)
+
+    async handleSubmit() {
+      const vm = this;
+      try {
+        // 파일 업로드
+        const formData = new FormData();
+        formData.append("files", this.selectedFile);
+
+        const fileUploadResponse = await axios.post(
+          "/file/upload.json",
+          formData,
+          {
+            headers: {
+              "Content-Type": "multipart/form-data",
+            },
+          }
+        );
+
+        // 업로드 후 파일 매니지 아이디 호출
+        const fileMngId = fileUploadResponse.data.fileMngId;
+
+        // 게시물 등록
+        const newData = {
+          bbsTtl: vm.title,
+          bbsCls: vm.category,
+          bbsCnt: vm.content,
+          fileMngId: fileMngId,
+          sclsId: vm.sclsId,
+        };
+
+        await axios.post("/board/insert.json", newData);
+
+        alert("게시물 등록 성공");
+      } catch (error) {
+        console.error("게시물 등록 실패 ", error);
+        alert("게시물 등록 실패");
+      }
+    },
+  },
+  watch: {},
+  computed: {},
+  components: {
+    SvgIcon,
+  },
+  mounted() {
+    console.log("Main2 mounted");
+    this.created();
+  },
+};
+</script>
Add a comment
List