yjryu / KERIS star
Stormen123 2023-11-15
231115 김성훈 관리자단 - 전문가 협의체, 기술문서 추가
@b545ffe7b6f12bce8b133f0ee2dc85bb3741ff9c
client/views/component/pagination/PaginationButton.vue
--- client/views/component/pagination/PaginationButton.vue
+++ client/views/component/pagination/PaginationButton.vue
@@ -73,6 +73,9 @@
 			for (var i = this.startPage; i <= this.endPage; i++) {
 				range.push(i);
 			}
+			if (range.length == 0) {
+					range.push(1);
+			}
 			return range;
 		}
 	},
client/views/pages/AppRouter.js
--- client/views/pages/AppRouter.js
+++ client/views/pages/AppRouter.js
@@ -43,6 +43,7 @@
 import AdminTechSelectList from "../pages/admin/technology/TechSelectList.vue";
 import AdminTechSelectOne from "../pages/admin/technology/TechSelectOne.vue";
 import AdminTechInsert from "../pages/admin/technology/TechInsert.vue";
+import AdminTechUpdate from "../pages/admin/technology/TechUpdate.vue";
 import AdminDataSelectList from "../pages/admin/databook/DataSelectList.vue";
 import AdminDataSelectOne from "./admin/databook/DataSelectOne.vue";
 import AdminDataInsert from "../pages/admin/databook/DataInsert.vue";
@@ -102,6 +103,7 @@
   { path: "/adm/techSelectList.page", name: "AdminTechSelectList", component: AdminTechSelectList },
   { path: "/adm/techSelectOne.page", name: "AdminTechSelectOne", component: AdminTechSelectOne },
   { path: "/adm/techInsert.page", name: "AdminTechInsert", component: AdminTechInsert },
+  { path: "/adm/techUpdate.page", name: "AdminTechUpdate", component: AdminTechUpdate },
   { path: "/adm/dataSelectList.page", name: "AdminDataSelectList", component: AdminDataSelectList },
   { path: "/adm/dataSelectOne.page", name: "AdminDataSelectOne", component: AdminDataSelectOne },
   { path: "/adm/dataInsert.page", name: "AdminDataInsert", component: AdminDataInsert },
client/views/pages/admin/databook/DataInsert.vue
--- client/views/pages/admin/databook/DataInsert.vue
+++ client/views/pages/admin/databook/DataInsert.vue
@@ -78,7 +78,7 @@
                 post_content: null,
                 link_url: null,
                 // 카테고리가 없는 게시판에서는 null로 설정 부탁합니다!
-                ctgry_nm: 'policy',
+                ctgry_nm: null,
             },
             fileList: [],
             filecount: 0,
@@ -159,6 +159,11 @@
                 return false;
             }
 
+            if (COMMON_UTIL.isEmpty(this.post.ctgry_nm) === false) {
+                alert("카테고리를 선택해주세요.");
+                return false;
+            }
+
             if (COMMON_UTIL.isEmpty(this.post.post_content) === false || this.post.post_content === "<p><br></p>") {
                 alert("내용을 입력해주세요.");
                 return false;
@@ -171,13 +176,11 @@
         fileUpload: function () {
             this.fileList[this.filecount] = this.$refs.fileInput.files[0]
             this.filecount += 1
-            console.log("file", this.fileList);
         },
 
         //파일업로드 중 업로드 파일 삭제
         fileRemove(idx) {
             this.fileList.splice(idx, 1);
-            console.log("reMove_file", this.fileList);
             this.filecount = this.fileList.length;
         },
 
client/views/pages/admin/databook/DataSelectList.vue
--- client/views/pages/admin/databook/DataSelectList.vue
+++ client/views/pages/admin/databook/DataSelectList.vue
@@ -44,12 +44,12 @@
                     </div>
                 </div>
                 <div class="sort-wrap">
-                        <ul class="flex-end">
-                            <li>최신순</li>
-                            <li>등록순</li>
-                            <li>조회수순</li>
-                        </ul>
-                    </div>
+                    <ul class="flex-end">
+                        <li>최신순</li>
+                        <li>등록순</li>
+                        <li>조회수순</li>
+                    </ul>
+                </div>
                 <table class="select-table">
                     <thead>
                         <tr>
@@ -73,7 +73,7 @@
                             <td>{{ item.view_cnt }}</td>
                         </tr>
                         <tr v-if="postListCount == 0">
-                            <td style="font-size: 20px;" colspan="5">검색조건에 해당하는 데이터가 없습니다.</td>
+                            <td style="font-size: 20px;" colspan="6">검색조건에 해당하는 데이터가 없습니다.</td>
                         </tr>
                     </tbody>
                 </table>
client/views/pages/admin/databook/DataSelectOne.vue
--- client/views/pages/admin/databook/DataSelectOne.vue
+++ client/views/pages/admin/databook/DataSelectOne.vue
@@ -152,7 +152,8 @@
 
         downloadFile: function (item) {
             const vm = this;
-            let path = item.file_path + '\\' + item.file_nm + '.' + item.file_extn_nm;
+            let path = item.file_path + '/' + item.file_nm + '.' + item.file_extn_nm;
+            console.log(path);
             axios({
                 url: '/file/downloadFile.json',
                 method: 'post',
client/views/pages/admin/news/NewsInsert.vue
--- client/views/pages/admin/news/NewsInsert.vue
+++ client/views/pages/admin/news/NewsInsert.vue
@@ -19,7 +19,7 @@
                             <td><textarea name="smart" id="smart" style="width:100%"></textarea></td>
                         </tr>
                         <tr>
-                            <th>썸네일 파일</th>
+                            <th>썸네일</th>
                             <td>
                                 <div class="btn-upload" @click="openFileInput">파일 업로드하기</div>
                                 <input type="file" name="file" id="file" ref="fileInput" style="display: none"
client/views/pages/admin/technology/TechInsert.vue
--- client/views/pages/admin/technology/TechInsert.vue
+++ client/views/pages/admin/technology/TechInsert.vue
@@ -12,27 +12,26 @@
                     <tbody>
                         <tr>
                             <th>제목</th>
-                            <td><input type="text" name="" id="newsTitle"></td>
+                            <td><input type="text" name="" id="techTitle" v-model="post.post_title"></td>
                         </tr>
                         <tr>
                             <th>카테고리</th>
                             <td>
                                 <div class="flex-start">
                                     <div>
-                                        <input type="radio" name="category" id="api" style="display:none" checked>
+                                        <input type="radio" name="category" id="api"  value="api" style="display:none" checked
+                                            v-model="post.ctgry_nm">
                                         <label for="api" class="category">API</label>
                                     </div>
                                     <div>
-                                        <input type="radio" name="category" id="tech" style="display:none">
+                                        <input type="radio" name="category" id="tech" value="tech" style="display:none"
+                                            v-model="post.ctgry_nm">
                                         <label for="tech" class="category">기술리포트</label>
                                     </div>
                                     <div>
-                                        <input type="radio" name="category" id="issue" style="display:none">
-                                        <label for="issue" class="category">이슈리포트</label>
-                                    </div>
-                                    <div>
-                                        <input type="radio" name="category" id="edu" style="display:none">
-                                        <label for="edu" class="category">교육리포트</label>
+                                        <input type="radio" name="category" id="issue" value="standard" style="display:none"
+                                            v-model="post.ctgry_nm">
+                                        <label for="issue" class="category">기술규격문서</label>
                                     </div>
                                 </div>
                             </td>
@@ -55,43 +54,140 @@
                     </tbody>
                 </table>
                 <div class="btn-wrap">
-                    <button class="dark-gray-btn" @click="selectList">이전</button>
-                    <button class="blue-btn">글쓰기</button>
+                    <button class="dark-gray-btn" @click="postSelectListPage()">이전</button>
+                    <button class="blue-btn" @click="postInsertCheck()">등록</button>
                 </div>
             </div>
         </div>
     </div>
 </template>
 <script>
-import '@toast-ui/editor/dist/toastui-editor.css';
+import axios from 'axios';
+import COMMON_UTIL from '../../../../resources/js/commonUtil.js';
 
 export default {
     data() {
         return {
+            post: {
+                bbs_id: '3',
+                post_title: null,
+                post_content: null,
+                link_url: null,
+                // 카테고리가 없는 게시판에서는 null로 설정 부탁합니다!
+                ctgry_nm: 'api',
+            },
+            fileList: [],
+            filecount: 0,
             oEditors: [], // oEditors는 스마트에디터용
         };
     },
     methods: {
-        selectList: function () {
+
+        //게시글 및 첨부파일 등록
+        postInsert: function () {
+            const vm = this;
+            let formData = new FormData();
+
+            if (vm.fileList.length > 0) {
+                for (let i = 0; i < vm.fileList.length; i++) {
+                    formData.append('file', vm.fileList[i]);
+                    console.log(formData.get('file'));
+                }
+                formData.append("post", JSON.stringify(vm.post));
+
+                axios({
+                    url: '/post/postFileInsert.file',
+                    method: 'post',
+                    headers: {
+                        'Content-Type': 'multipart/form-data',
+                    },
+                    data: formData
+                }).then(function (response) {
+                    console.log("qnaInsert - response : ", response);
+                    let result = response.data;
+                    if (result > 0) {
+                        alert("등록을 완료하였습니다.");
+                        vm.postSelectListPage()
+                    } else {
+                        alert("등록 실패, 관리자에게 문의해주세요.");
+                    }
+                }).catch(function (error) {
+                    console.log("qnaInsert - error : ", error);
+                    alert("등록 오류, 관리자에게 문의해주세요.");
+                });
+            } else {
+
+                axios({
+                    url: '/post/postInsert.json',
+                    method: 'post',
+                    headers: {
+                        'Content-Type': "application/json; charset=UTF-8",
+                    },
+                    data: vm.post
+                }).then(function (response) {
+                    console.log("noticeInsert - response : ", response);
+                    let result = response.data;
+                    if (result > 0) {
+                        alert("등록을 완료하였습니다.");
+                        vm.postSelectListPage()
+                    } else {
+                        alert("등록 실패, 관리자에게 문의해주세요.");
+                    }
+                }).catch(function (error) {
+                    console.log("noticeInsert - error : ", error);
+                    alert("등록 오류, 관리자에게 문의해주세요.");
+                });
+            }
+        },
+
+        //등록 유효성 검사
+        postInsertCheck: function () {
+            const oEditors = this.oEditors;
+            oEditors.getById["smart"].exec("UPDATE_CONTENTS_FIELD", []);
+            // 스마트에디터의 iframe에 있는 내용을 textarea로. 
+            this.post.post_content = document.getElementById("smart").value;
+            console.log(document.getElementById("smart").value);
+            console.log(this.post.post_content);
+            console.log(COMMON_UTIL.isEmpty(this.post.post_title));
+
+            if (COMMON_UTIL.isEmpty(this.post.post_title) === false) {
+                alert("제목을 입력해주세요.");
+                return false;
+            }
+
+            if (COMMON_UTIL.isEmpty(this.post.ctgry_nm) === false) {
+                alert("카테고리를 선택해주세요.");
+                return false;
+            }
+            
+            if (COMMON_UTIL.isEmpty(this.post.post_content) === false || this.post.post_content === "<p><br></p>") {
+                alert("내용을 입력해주세요.");
+                return false;
+            }
+
+            this.postInsert();
+        },
+
+        //파일업로드
+        fileUpload: function () {
+            this.fileList[this.filecount] = this.$refs.fileInput.files[0]
+            this.filecount += 1
+        },
+
+        //파일업로드 중 업로드 파일 삭제
+        fileRemove(idx) {
+            this.fileList.splice(idx, 1);
+            this.filecount = this.fileList.length;
+        },
+
+        //게시글 리스트로 이동
+        postSelectListPage: function () {
             this.$router.push({ path: '/adm/techSelectList.page' });
         },
 
         // 파일 업로드 커스텀을 위한 함수
         openFileInput: function () {
             this.$refs.fileInput.click(); // 파일 업로드 input 요소를 클릭
-        },
-        //파일업로드
-        fileUpload: function () {
-            this.fileList[this.filecount] = this.$refs.fileInput.files[0]
-            this.filecount += 1
-            console.log("file", this.fileList);
-        },
-
-        //파일업로드 중 업로드 파일 삭제
-        fileRemove(idx) {
-            this.fileList.splice(idx, 1);
-            console.log("reMove_file", this.fileList);
-            this.filecount = this.fileList.length;
         },
     },
     watch: {},
client/views/pages/admin/technology/TechSelectList.vue
--- client/views/pages/admin/technology/TechSelectList.vue
+++ client/views/pages/admin/technology/TechSelectList.vue
@@ -8,71 +8,157 @@
                 </div>
             </div>
             <div class="content-wrap">
-                <div class="btn-wrap">
-                    <div class="data-select">
-                        <select  name="data-table-sild" id="data-table-sild">
-                            <option :value=null selected>전체</option>
-                            <option value="title">제목</option>
-                            <option value="user">작성자</option>
-                            <option value="조회순">조회순</option>
-                        </select>
-                        <div class="input-group">
-                            <input type="text" class="input" placeholder="검색어를 입력해주세요." >
-                            <button class="button--submit">검색</button>
+                <div class="top-bar">
+                    <div class="flex">
+                        <div class="category-bar flex-start">
+                            <div>
+                                <input type="radio" name="category" id="all" :value= null style="display:none" checked @click="ctgry($event)">
+                                <label for="all" class="category">전체</label>
+                            </div>
+                            <div>
+                                <input type="radio" name="category" id="policy" value="api" style="display:none" @click="ctgry($event)">
+                                <label for="policy" class="category">API</label>
+                            </div>
+                            <div>
+                                <input type="radio" name="category" id="research" value="tech" style="display:none" @click="ctgry($event)">
+                                <label for="research" class="category">기술리포트</label>
+                            </div>
+                            <div>
+                                <input type="radio" name="category" id="guide" value="standard" style="display:none" @click="ctgry($event)">
+                                <label for="guide" class="category">기술규격문서</label>
+                            </div>
+                        </div>
+                        <div class="data-select">
+                            <select v-model="postListSearch.searchType" name="data-table-sild" id="data-table-sild">
+                                <option :value=null selected>전체</option>
+                                <option value="title">제목</option>
+                                <option value="content">내용</option>
+                                <option value="writer">작성자</option>
+                            </select>
+                            <div class="input-group">
+                                <input type="text" class="input" placeholder="검색어를 입력해주세요."
+                                    v-model="postListSearch.searchText" @keyup.enter="postSelectList()">
+                                <input class="button--submit" value="검색" type="submit" @click="postSelectList()">
+                            </div>
                         </div>
                     </div>
                 </div>
                 <div class="sort-wrap">
-                        <ul class="flex-end">
-                            <li>최신순</li>
-                            <li>등록순</li>
-                            <li>조회수순</li>
-                        </ul>
-                    </div>
+                    <ul class="flex-end">
+                        <li>최신순</li>
+                        <li>등록순</li>
+                        <li>조회수순</li>
+                    </ul>
+                </div>
                 <table class="select-table">
                     <thead>
                         <tr>
                             <th style="width:5%">no</th>
-                            <th style="width:65%">제목</th>
+                            <th style="width:10%">카테고리</th>
+                            <th style="width:55%">제목</th>
                             <th style="width:10%">작성자</th>
                             <th style="width:10%">작성일자</th>
                             <th style="width:10%">조회수</th>
                         </tr>
                     </thead>
                     <tbody>
-                        <tr>
-                            <td>1</td>
-                            <td>제목이 들어가는 부분입니다.</td>
-                            <td>관리자</td>
-                            <td>2023/11/01</td>
-                            <td>100</td>
+                        <tr v-for="(item, idx) in postList" :key="idx" @click="postSelectOnePage(item)">
+                            <td>{{ postIdx - idx }}</td>
+                            <td v-if="item.ctgry_nm === 'api'"><span class="category-zone">API</span></td>
+                            <td v-else-if="item.ctgry_nm === 'tech'"><span class="category-zone">기술리포트</span></td>
+                            <td v-else><span class="category-zone">기술규격문서</span></td>
+                            <td>{{ item.post_title }}</td>
+                            <td>{{ item.rgtr_id }}</td>
+                            <td>{{ yyyymmdd(item.reg_dt) }}</td>
+                            <td>{{ item.view_cnt }}</td>
+                        </tr>
+                        <tr v-if="postListCount == 0">
+                            <td style="font-size: 20px;" colspan="6">검색조건에 해당하는 데이터가 없습니다.</td>
                         </tr>
                     </tbody>
                 </table>
                 <div class="btn-wrap">
-                    <button class="blue-btn" @click="selectInsert">글쓰기</button>
+                    <button class="blue-btn"  @click="postInsertPage()">글쓰기</button>
+                </div>
+                <div class="bottom-wrap">
+                    <PaginationButton v-model:currentPage="postListSearch.currentPage" :perpage="postListSearch.perPage"
+                        :total-count="postListCount" :max-range="5" :click="postSelectList" />
                 </div>
             </div>
         </div>
     </div>
 </template>
 <script>
-
+import axios from 'axios';
+import COMMON_UTIL from '../../../../resources/js/commonUtil.js';
+import PaginationButton from '../../../component/pagination/PaginationButton.vue';
 
 export default {
 
     data() {
-        return {};
+        return {
+            postListSearch: {
+                currentPage: 1,
+                perPage: 10,
+                searchType: null,
+                searchText: null,
+                bbs_id: '3',
+                ctgry_nm: null
+            },
+            postList: [],
+            postListCount: 0,
+            postIdx: 0
+        };
     },
     methods: {
-        selectInsert: function () {
+        postSelectList: function () {
+            const vm = this;
+
+            axios({
+                url: '/post/postSelectList.json',
+                method: 'post',
+                hearder: {
+                    'Content-Type': "application/json; charset=UTF-8",
+                },
+                data: vm.postListSearch
+            }).then(function (response) {
+                vm.postList = response.data.postSelectList;
+                vm.postListCount = response.data.postSelectListCount;
+                vm.postIdx = vm.postListCount - (vm.postListSearch.currentPage - 1) * vm.postListSearch.perPage;
+            }).catch(function (error) {
+                alert('자료집 목록 조회 오류, 관리자에게 문의하세요.');
+            })
+        },
+
+        //날짜 시,분,초 자르기
+        yyyymmdd: function (date) {
+            return COMMON_UTIL.yyyymmdd(date);
+        },
+
+        //게시글 상세조회 페이지로 이동
+        postSelectOnePage: function (item) {
+            this.$router.push({ path: '/adm/techSelectOne.page', query: { 'post_id': item.post_id, 'file_id': item.file_id } });
+        },
+
+        postInsertPage: function () {
             this.$router.push({ path: '/adm/techInsert.page', query: {} })
+        },
+
+        ctgry: function(e) {
+            this.postListSearch.ctgry_nm = e.target.value;
+            if(this.postListSearch.ctgry_nm === 'on') {
+                this.postListSearch.ctgry_nm = null
+            }
+            this.postSelectList();
         }
     },
     watch: {},
     computed: {},
-    components: {},
+    components: {
+        PaginationButton: PaginationButton,
+    },
     mounted() {
+        this.postSelectList();
     }
 };
 </script>
client/views/pages/admin/technology/TechSelectOne.vue
--- client/views/pages/admin/technology/TechSelectOne.vue
+++ client/views/pages/admin/technology/TechSelectOne.vue
@@ -11,41 +11,221 @@
                 <table class="insert-table">
                     <tbody>
                         <tr>
-                            <th>제목</th>
-                            <td><input type="text" name="" id="newsTitle"></td>
+                            <td class="title-zone" colspan="2">
+                                <p class="flex">
+                                    <span class="post-title">{{ post.post_title }}</span>
+                                    <span v-if="post.ctgry_nm === 'api'" class="category-zone">API</span>
+                                    <span v-else-if="post.ctgry_nm === 'tech'" class="category-zone">기술리포트</span>
+                                    <span v-else class="category-zone">기술규격문서</span>
+                                </p>
+                                <p class="flex-end write-info"><span class="writer">작성자</span>
+                                    <span>{{ post.rgtr_id}}</span>
+                                    <span class="view">조회수</span>
+                                    <span>{{ post.view_cnt }}</span>
+                                </p>
+                            </td>
                         </tr>
                         <tr>
-                            <th>내용</th>
-                            <td><textarea name="" id="" cols="30" rows="10"></textarea></td>
+                            <td colspan="2" style="border-bottom: 1px solid #007aff;">
+                                <div id="viewer" ref="viewer" class="viewer"></div>
+                            </td>
+                        </tr>
+                        <tr>
+                            <th style="width: 10%;">첨부파일명</th>
+                            <td>
+                                <div v-if="fileList.length == 0">
+                                    <label>첨부된 파일이 없습니다.</label>
+                                </div>
+                                <ul v-else v-for="(item, idx) in fileList" :key="idx">
+                                    <li @click="downloadFile(item)">{{ item.real_file_nm }}</li>
+                                </ul>
+                            </td>
                         </tr>
                     </tbody>
                 </table>
+                <div class="article-list">
+                    <ul>
+                        <li><span class="next">다음글</span>
+                            <span>
+                                <span v-if="nextPost" @click="movePost(nextPost)" class="sub-content-title">
+                                    {{ nextPost.post_title }}
+                                </span>
+                                <span v-else class="sub-content-title">다음글이 없습니다.</span>
+                            </span>
+                        </li>
+                        <li><span class="prev">이전글</span>
+                            <span>
+                                <span v-if="prevPost" @click="movePost(prevPost)" class="sub-content-title">
+                                    {{ prevPost.post_title }}
+                                </span>
+                                <span v-else class="sub-content-title">이전글이 없습니다.</span>
+                            </span>
+                        </li>
+                    </ul>
+                </div>
                 <div class="btn-wrap">
-                    <button class="red-btn" @click="selectList">삭제</button>
-                    <button class="dark-gray-btn" @click="selectList">목록</button>
-                    <button class="blue-btn">수정</button>
+                    <button class="red-btn" @click="postDelete()">삭제</button>
+                    <button class="dark-gray-btn" @click="postSelectListPage()">목록</button>
+                    <button class="blue-btn" @click="postUpdatePage()">수정</button>
                 </div>
             </div>
         </div>
     </div>
 </template>
 <script>
-
+import axios from 'axios';
+import COMMON_UTIL from '../../../../resources/js/commonUtil.js';
+import { useRoute } from 'vue-router';
+import Viewer from '@toast-ui/editor/dist/toastui-editor-viewer';
+import '@toast-ui/editor/dist/toastui-editor.css';
+import '@toast-ui/editor/dist/i18n/ko-kr';
+import * as FileSaver from 'file-saver';
 
 export default {
 
     data() {
-        return {};
+        return {
+            post: {
+                post_id: null,
+                post_title: null,
+                post_content: null,
+                notice_yn: null,
+                notice_start_dt: null,
+                notice_end_dt: null,
+                reg_dt: null,
+                mdfcn_dt: null,
+                link_url: null,
+                view_cnt: null,
+                file_id: null,
+                bbs_id: null,
+                rgtr_id: null,
+                mdfr_id: null,
+                ctgry_nm: null,
+            },
+            fileList: [],
+            oEditors: [], // oEditors는 스마트에디터용
+            route: useRoute(),
+        };
     },
     methods: {
-        selectList:function(){
-            this.$router.push({ path: '/adm/techSelectList.page'});
-        }
+        postSelectOne: function () {
+            const vm = this;
+            axios({
+                url: '/post/postSelectOne.json',
+                method: 'post',
+                hearder: {
+                    'Content-Type': "application/json; charset=UTF-8",
+                },
+                data: { 'post_id': vm.route.query.post_id, 'file_id': vm.route.query.file_id }
+            }).then(function (response) {
+                vm.post = response.data.postSelectOne.post;
+
+                if (response.data.selectFileList.length != 0) {
+                    vm.fileList = response.data.selectFileList;
+                }
+                vm.getViewer(vm.post.post_content)
+            }).catch(function (error) {
+                console.log("error - ", error)
+                alert("게시글 상세보기 조회 오류, 관리자에게 문의하세요.");
+            })
+        },
+
+        getViewer(data) {
+            this.viewer = new Viewer({
+                el: this.$refs.viewer,
+                initialEditType: 'wysiwyg',
+                previewStyle: 'vertical',
+                initialValue: data,
+                customHTMLRenderer: {
+                    htmlBlock: {
+                        iframe(node) {
+                            return [
+                                { type: 'openTag', tagName: 'iframe', outerNewLine: true, attributes: node.attrs },
+                                { type: 'html', content: node.childrenHTML },
+                                { type: 'closeTag', tagName: 'iframe', outerNewLine: true },
+                            ];
+                        },
+                    }
+                },
+            });
+        },
+
+        downloadFile: function (item) {
+            const vm = this;
+            let path = item.file_path + '/' + item.file_nm + '.' + item.file_extn_nm;
+            console.log(path);
+            axios({
+                url: '/file/downloadFile.json',
+                method: 'post',
+                headers: {
+                    "Content-Type": "application/x-www-form-urlencoded",
+                },
+                responseType: 'blob',
+                data: `file_path=${encodeURIComponent(path)}`
+            }).then((response) => {
+                const blob = new Blob([response.data]);
+
+                const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+
+                if (isSafari) {
+                    FileSaver.saveAs(blob, item.real_file_nm);
+                } else {
+                    const url = window.URL.createObjectURL(blob);
+                    const a = document.createElement('a');
+                    a.style.display = 'none';
+                    a.href = url;
+                    a.download = item.real_file_nm;
+                    document.body.appendChild(a);
+                    a.click();
+                    window.URL.revokeObjectURL(url);
+                }
+
+                this.$router.go(0);
+
+            }).catch(function (error) {
+                console.log('error - ', error)
+                alert('에러발생');
+            });
+        },
+
+        postDelete: function () {
+            const vm = this;
+
+            axios({
+                url: "/post/postDelete.json",
+                method: "post",
+                headers: {
+                    "Content-Type": "application/json; charset=UTF-8",
+                },
+                data: vm.post
+            }).then(function (response) {
+                console.log("postDelete - response : ", response.data);
+                let result = response.data;
+                if (result > 0) {
+                    alert("삭제가 완료 되었습니다.");
+                    vm.postSelectListPage();
+                } else {
+                    alert("삭제실패, 다시 시도 해주세요.");
+                }
+            }).catch(function (error) {
+                console.log("postDelete - error : ", error);
+                alert("삭제 오류, 관리자에게 문의해주세요.");
+            });
+        },
+
+        postSelectListPage: function () {
+            this.$router.push({ path: '/adm/techSelectList.page' });
+        },
+
+        postUpdatePage: function () {
+            this.$router.push({ path: '/adm/techUpdate.page', query: { 'post_id': this.post.post_id, 'file_id': this.post.file_id } });
+        },
     },
     watch: {},
     computed: {},
     components: {},
     mounted() {
+        this.postSelectOne();
     }
 };
 </script>
 
client/views/pages/admin/technology/TechUpdate.vue (added)
+++ client/views/pages/admin/technology/TechUpdate.vue
@@ -0,0 +1,291 @@
+<template>
+    <div class="admin-wrap">
+        <div class="content-box">
+            <div class="title-wrap">
+                <div class="flex-start">
+                    <img src="../../../../resources/jpg/data-img-text.png" alt="자료집 아이콘" class="title-icon">
+                    <h2 class="main-title">자료집</h2>
+                </div>
+            </div>
+            <div class="content-wrap dataUpdate">
+                <table class="insert-table">
+                    <tbody>
+                        <tr>
+                            <th>제목</th>
+                            <td><input type="text" name="" id="newsTitle" v-model="post.post_title"></td>
+                        </tr>
+                        <tr>
+                            <th>카테고리</th>
+                            <td>
+                                <div class="flex-start">
+                                    <div>
+                                        <input type="radio" name="category" id="api"  value="api" style="display:none" checked
+                                            v-model="post.ctgry_nm">
+                                        <label for="api" class="category">API</label>
+                                    </div>
+                                    <div>
+                                        <input type="radio" name="category" id="tech" value="tech" style="display:none"
+                                            v-model="post.ctgry_nm">
+                                        <label for="tech" class="category">기술리포트</label>
+                                    </div>
+                                    <div>
+                                        <input type="radio" name="category" id="issue" value="standard" style="display:none"
+                                            v-model="post.ctgry_nm">
+                                        <label for="issue" class="category">기술규격문서</label>
+                                    </div>
+                                </div>
+                            </td>
+                        </tr>
+                        <tr>
+                            <th>게시물 상단고정 사용여부</th>
+                            <td><input type="checkbox" name="" id=""><label>사용</label></td>
+                        </tr>
+                        <tr>
+                            <th>내용</th>
+                            <td><textarea name="smart" id="smart"></textarea></td>
+                        </tr>
+                        <tr>
+                            <th>등록된 첨부파일</th>
+                            <td colspan="6">
+                                <div v-if="fileList.length == 0">
+                                    <label>첨부된 파일이 없습니다.</label>
+                                </div>
+                                <ul v-else v-for="(item, idx) in fileList" :key="idx">
+                                    <li class="flex file-list">
+                                        <p>{{ item.real_file_nm }}</p>
+                                        <button class="red-btn" @click="fileRemove(item, idx)">삭제</button>
+                                    </li>
+                                </ul>
+                            </td>
+                        </tr>
+                        <tr>
+                            <th>추가 첨부파일</th>
+                            <td colspan="6">
+                                <div class="btn-upload" @click="openFileInput">파일 업로드하기</div>
+                                <input type="file" name="file" id="file" ref="fileInput" style="display: none"
+                                    @change="fileUpload()">
+                                <ul v-for="(item, idx) in insertFileList" :key="idx">
+                                    <li v-if="insertFileList.length != 0" class="flex file-list">{{ item.name }} <button
+                                            class="red-border-btn" @click="fileRemove(item, idx)">삭제</button></li>
+                                </ul>
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+                <div class="btn-wrap">
+                    <button class="dark-gray-btn" @click="postSelectListPage()">이전</button>
+                    <button class="blue-btn" @click="postUpdateCheck()">수정</button>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+import axios from 'axios';
+import COMMON_UTIL from '../../../../resources/js/commonUtil.js';
+import { useRoute } from 'vue-router';
+
+export default {
+    data() {
+        return {
+            post: {
+                post_id: null,
+                post_title: null,
+                post_content: null,
+                notice_yn: null,
+                notice_start_dt: null,
+                notice_end_dt: null,
+                reg_dt: null,
+                mdfcn_dt: null,
+                link_url: null,
+                view_cnt: null,
+                file_id: null,
+                bbs_id: null,
+                rgtr_id: null,
+                mdfr_id: null,
+                ctgry_nm: null,
+            },
+            fileList: [],
+            deleteFileList: [],
+            insertFileList: [],
+            filecount: 0,
+            insertCount: 0,
+            deleteCount: 0,
+            oEditors: [], // oEditors는 스마트에디터용
+            route: useRoute(),
+        };
+    },
+    methods: {
+        postSelectOne: function () {
+            const vm = this;
+            axios({
+                url: '/post/postSelectOne.json',
+                method: 'post',
+                hearder: {
+                    'Content-Type': "application/json; charset=UTF-8",
+                },
+                data: { 'post_id': vm.route.query.post_id, 'file_id': vm.route.query.file_id }
+            }).then(function (response) {
+                vm.post = response.data.postSelectOne.post;
+
+                if (response.data.selectFileList.length != 0) {
+                    vm.fileList = response.data.selectFileList;
+                    vm.filecount = response.data.selectFileList.length;
+                }
+
+                vm.initEditor(vm.post.post_content)
+            }).catch(function (error) {
+                console.log("error - ", error)
+                alert("게시글 상세보기 조회 오류, 관리자에게 문의하세요.");
+            })
+        },
+
+        //게시글 및 첨부파일 등록
+        postUpdate: function () {
+            const vm = this;
+            let formData = new FormData();
+
+            if (vm.insertFileList.length > 0 || vm.deleteFileList.length > 0) {
+                if (vm.insertFileList.length > 0) {
+                    for (let i = 0; i < vm.insertFileList.length; i++) {
+                        formData.append('file', vm.insertFileList[i]);
+                        console.log('file - ', formData.get('file'));
+                    }
+                }
+
+                if (vm.deleteFileList.length > 0) {
+                    formData.append('deleteFile', JSON.stringify(vm.deleteFileList));
+                    console.log('deleteFile - ', formData.get('deleteFile'));
+                }
+
+                formData.append("post", JSON.stringify(vm.post));
+
+                axios({
+                    url: '/post/postFileUpdate.file',
+                    method: 'post',
+                    headers: {
+                        'Content-Type': 'multipart/form-data',
+                    },
+                    data: formData
+                }).then(function (response) {
+                    console.log("qnaInsert - response : ", response);
+                    let result = response.data;
+                    if (result > 0) {
+                        alert("수정을 완료하였습니다.");
+                        vm.postSelectListPage()
+                    } else {
+                        alert("수정 실패, 관리자에게 문의해주세요.");
+                    }
+                }).catch(function (error) {
+                    console.log("qnaInsert - error : ", error);
+                    alert("수정 오류, 관리자에게 문의해주세요.");
+                });
+            } else {
+
+                axios({
+                    url: '/post/postFileUpdate.json',
+                    method: 'post',
+                    headers: {
+                        'Content-Type': "application/json; charset=UTF-8",
+                    },
+                    data: vm.post
+                }).then(function (response) {
+                    console.log("noticeInsert - response : ", response);
+                    let result = response.data;
+                    if (result > 0) {
+                        alert("수정을 완료하였습니다.");
+                        vm.postSelectListPage()
+                    } else {
+                        alert("수정 실패, 관리자에게 문의해주세요.");
+                    }
+                }).catch(function (error) {
+                    console.log("noticeInsert - error : ", error);
+                    alert("수정 오류, 관리자에게 문의해주세요.");
+                });
+            }
+        },
+
+        //등록 유효성 검사
+        postUpdateCheck: function () {
+            const oEditors = this.oEditors;
+            oEditors.getById["smart"].exec("UPDATE_CONTENTS_FIELD", []);
+            // 스마트에디터의 iframe에 있는 내용을 textarea로. 
+            this.post.post_content = document.getElementById("smart").value;
+
+            if (COMMON_UTIL.isEmpty(this.post.post_title) === false) {
+                alert("제목을 입력해주세요.");
+                return false;
+            }
+
+            if (COMMON_UTIL.isEmpty(this.post.post_content) === false || this.post.post_content === "<p><br></p>") {
+                alert("내용을 입력해주세요.");
+                return false;
+            }
+
+            this.postUpdate();
+        },
+
+        // 에디터 만들기 
+        initEditor: function (initData) {
+            // 스마트 에디터 적용
+            const oEditors = this.oEditors;
+            nhn.husky.EZCreator.createInIFrame({
+                oAppRef: oEditors,
+                elPlaceHolder: "smart",
+                sSkinURI: "/client/smarteditor2-2.8.2.3/SmartEditor2Skin.html",
+                htParams: {
+                    bSkipXssFilter: true,
+                    bUseVerticalResizer: true,
+                    bUseModeChanger: true
+                },
+                fOnAppLoad: function () {
+                    oEditors.getById["smart"].exec("PASTE_HTML", [initData]);
+                },
+                fCreator: "createSEditor2"
+            });
+        },
+        //파일업로드
+        fileUpload: function () {
+
+            this.insertFileList[this.insertCount] = this.$refs.fileInput.files[0];
+            this.insertCount += 1;
+            console.log("insertFile - ", this.insertFileList);
+        },
+
+        //파일업로드 중 업로드 파일 삭제
+        fileRemove(item, idx) {
+            if (item.file_path === undefined) {
+                this.insertFileList.splice(idx, 1);
+                this.insertCount = this.insertFileList.length;
+                console.log("insertfile", this.insertFileList);
+
+            } else {
+                this.fileList.splice(idx, 1);
+                this.deleteFileList[this.deleteCount] = item
+                this.deleteCount += 1
+                this.filecount = this.fileList.length;
+                console.log("deleteFile - ", this.deleteFileList);
+            }
+
+        },
+
+        //게시글 리스트로 이동
+        postSelectListPage: function () {
+            this.$router.push({ path: '/adm/techSelectList.page' });
+        },
+
+        // 파일 업로드 커스텀을 위한 함수
+        openFileInput: function () {
+            this.$refs.fileInput.click(); // 파일 업로드 input 요소를 클릭
+        }
+    },
+    watch: {},
+    computed: {},
+    components: {},
+    mounted() {
+        this.postSelectOne();
+        // 스마트 에디터 적용
+    }
+
+};
+</script>
client/views/pages/admin/wgcommunity/WgInsert.vue
--- client/views/pages/admin/wgcommunity/WgInsert.vue
+++ client/views/pages/admin/wgcommunity/WgInsert.vue
@@ -17,8 +17,8 @@
                         <tr>
                             <th>워킹그룹</th>
                             <td>
-                                <select name="" id="">
-                                    <option value="null">선택해주세요</option>
+                                <select name="" id="" v-model="post.ctgry_nm">
+                                    <option value=null>선택해주세요</option>
                                     <option value="WG1">교육과정 표준체계</option>
                                     <option value="WG2">맞춤학습지원 기능</option>
                                     <option value="WG3">접근성/UDL</option>
@@ -66,12 +66,12 @@
     data() {
         return {
             post: {
-                bbs_id: '0',
+                bbs_id: '4',
                 post_title: null,
                 post_content: null,
                 link_url: null,
                 // 카테고리가 없는 게시판에서는 null로 설정 부탁합니다!
-                ctgry_nm: 'policy',
+                ctgry_nm: null,
             },
             fileList: [],
             filecount: 0,
@@ -143,12 +143,18 @@
             oEditors.getById["smart"].exec("UPDATE_CONTENTS_FIELD", []);
             // 스마트에디터의 iframe에 있는 내용을 textarea로. 
             this.post.post_content = document.getElementById("smart").value;
-            console.log(document.getElementById("smart").value);
-            console.log(this.post.post_content);
-            console.log(COMMON_UTIL.isEmpty(this.post.post_title));
+
+            // if(this.post.ctgry_nm = 'null') {
+            //     this.post.ctgry_nm = null;
+            // }
 
             if (COMMON_UTIL.isEmpty(this.post.post_title) === false) {
                 alert("제목을 입력해주세요.");
+                return false;
+            }
+
+            if (COMMON_UTIL.isEmpty(this.post.ctgry_nm) === false) {
+                alert("워킹그룹을 선택해주세요.");
                 return false;
             }
 
@@ -176,7 +182,7 @@
 
         //게시글 리스트로 이동
         postSelectListPage: function () {
-            this.$router.push({ path: '/adm/dataSelectList.page' });
+            this.$router.push({ path: '/adm/wgSelectList.page' });
         },
 
         // 파일 업로드 커스텀을 위한 함수
client/views/pages/admin/wgcommunity/WgSelectList.vue
--- client/views/pages/admin/wgcommunity/WgSelectList.vue
+++ client/views/pages/admin/wgcommunity/WgSelectList.vue
@@ -11,8 +11,8 @@
                 <div class="top-bar">
                     <div class="flex-end">
                         <div class="data-select">
-                            <select name="" id="">
-                                    <option value="null">워킹그룹</option>
+                            <select name="" id="" v-model="postListSearch.ctgry_nm">
+                                    <option value=null >워킹그룹</option>
                                     <option value="WG1">교육과정 표준체계</option>
                                     <option value="WG2">맞춤학습지원 기능</option>
                                     <option value="WG3">접근성/UDL</option>
@@ -50,26 +50,34 @@
                     <thead>
                         <tr>
                             <th style="width:5%">no</th>
-                            <th style="width:10%">워킹그룹</th>
-                            <th style="width:55%">제목</th>
+                            <th style="width:18%">워킹그룹</th>
+                            <th style="width:50%">제목</th>
                             <th style="width:10%">작성자</th>
                             <th style="width:10%">작성일자</th>
-                            <th style="width:10%">조회수</th>
+                            <th style="width:7%">조회수</th>
                         </tr>
                     </thead>
                     <tbody>
                         <tr v-for="(item, idx) in postList" :key="idx" @click="postSelectOnePage(item)">
                             <td>{{ postIdx - idx }}</td>
-                            <td v-if="item.ctgry_nm === 'policy'"><span class="category-zone">정책자료</span></td>
-                            <td v-else-if="item.ctgry_nm === 'research'"><span class="category-zone">연구자료</span></td>
-                            <td v-else><span class="category-zone">가이드라인</span></td>
+                            <td v-if="item.ctgry_nm === 'WG1'"><span class="category-zone">(WG1)교육과정 표준체계</span></td>
+                            <td v-else-if="item.ctgry_nm === 'WG2'"><span class="category-zone">(WG2)맞춤학습지원 기능</span></td>
+                            <td v-else-if="item.ctgry_nm === 'WG3'"><span class="category-zone">(WG3)접근성/UDL</span></td>
+                            <td v-else-if="item.ctgry_nm === 'WG4'"><span class="category-zone">(WG4)클라우드 보안인증</span></td>
+                            <td v-else-if="item.ctgry_nm === 'WG5'"><span class="category-zone">(WG5)통합인증체계</span></td>
+                            <td v-else-if="item.ctgry_nm === 'WG6'"><span class="category-zone">(WG6)학습이력데이터/통합대시보드</span></td>
+                            <td v-else-if="item.ctgry_nm === 'WG7'"><span class="category-zone">(WG7)AI 트레이닝 데이터</span></td>
+                            <td v-else-if="item.ctgry_nm === 'WG8'"><span class="category-zone">(WG8)국가수준 학습분석</span></td>
+                            <td v-else-if="item.ctgry_nm === 'WG9'"><span class="category-zone">(WG9)학교 인프라</span></td>
+                            <td v-else-if="item.ctgry_nm === 'WG10'"><span class="category-zone">(WG10)서비스 품질관리</span></td>
+                            <td v-else><span class="category-zone">(WG11)서비스 정책</span></td>
                             <td>{{ item.post_title }}</td>
                             <td>{{ item.rgtr_id }}</td>
                             <td>{{ yyyymmdd(item.reg_dt) }}</td>
                             <td>{{ item.view_cnt }}</td>
                         </tr>
                         <tr v-if="postListCount == 0">
-                            <td style="font-size: 20px;" colspan="5">검색조건에 해당하는 데이터가 없습니다.</td>
+                            <td style="font-size: 20px;" colspan="6">검색조건에 해당하는 데이터가 없습니다.</td>
                         </tr>
                     </tbody>
                 </table>
@@ -98,7 +106,7 @@
                 perPage: 10,
                 searchType: null,
                 searchText: null,
-                bbs_id: '0',
+                bbs_id: '4',
                 ctgry_nm: null
             },
             postList: [],
@@ -110,6 +118,10 @@
         postSelectList: function () {
             const vm = this;
 
+            if(vm.postListSearch.ctgry_nm === 'null') {
+                vm.postListSearch.ctgry_nm = null
+            }
+            
             axios({
                 url: '/post/postSelectList.json',
                 method: 'post',
@@ -139,14 +151,6 @@
         postInsertPage: function () {
             this.$router.push({ path: '/adm/wgInsert.page', query: {} })
         },
-
-        ctgry: function(e) {
-            this.postListSearch.ctgry_nm = e.target.value;
-            if(this.postListSearch.ctgry_nm === 'on') {
-                this.postListSearch.ctgry_nm = null
-            }
-            this.postSelectList();
-        }
     },
     watch: {},
     computed: {},
client/views/pages/admin/wgcommunity/WgSelectOne.vue
--- client/views/pages/admin/wgcommunity/WgSelectOne.vue
+++ client/views/pages/admin/wgcommunity/WgSelectOne.vue
@@ -14,9 +14,17 @@
                             <td class="title-zone" colspan="2">
                                 <p class="flex">
                                     <span class="post-title">{{ post.post_title }}</span>
-                                    <span v-if="post.ctgry_nm === 'policy'" class="category-zone">정책자료</span>
-                                    <span v-else-if="post.ctgry_nm === 'research'" class="category-zone">연구자료</span>
-                                    <span v-else class="category-zone">가이드라인</span>
+                                    <span v-if="post.ctgry_nm === 'WG1'" class="category-zone">(WG1)교육과정 표준체계</span>
+                                    <span v-else-if="post.ctgry_nm === 'WG2'" class="category-zone">(WG2)맞춤학습지원 기능</span>
+                                    <span v-else-if="post.ctgry_nm === 'WG3'" class="category-zone">(WG3)접근성/UDL</span>
+                                    <span v-else-if="post.ctgry_nm === 'WG4'" class="category-zone">(WG4)클라우드 보안인증</span>
+                                    <span v-else-if="post.ctgry_nm === 'WG5'" class="category-zone">(WG5)통합인증체계</span>
+                                    <span v-else-if="post.ctgry_nm === 'WG6'" class="category-zone">(WG6)학습이력데이터/통합대시보드</span>
+                                    <span v-else-if="post.ctgry_nm === 'WG7'" class="category-zone">(WG7)AI 트레이닝 데이터</span>
+                                    <span v-else-if="post.ctgry_nm === 'WG8'" class="category-zone">(WG8)국가수준 학습분석</span>
+                                    <span v-else-if="post.ctgry_nm === 'WG9'" class="category-zone">(WG9)학교 인프라</span>
+                                    <span v-else-if="post.ctgry_nm === 'WG10'" class="category-zone">(WG10)서비스 품질관리</span>
+                                    <span v-else class="category-zone">(WG11)서비스 정책</span>
                                 </p>
                                 <p class="flex-end write-info"><span class="writer">작성자</span>
                                     <span>{{ post.rgtr_id}}</span>
@@ -213,11 +221,11 @@
         },
 
         postSelectListPage: function () {
-            this.$router.push({ path: '/adm/dataSelectList.page' });
+            this.$router.push({ path: '/adm/wgSelectList.page' });
         },
 
         postUpdatePage: function () {
-            this.$router.push({ path: '/adm/dataUpdate.page', query: { 'post_id': this.post.post_id, 'file_id': this.post.file_id } });
+            this.$router.push({ path: '/adm/wgUpdate.page', query: { 'post_id': this.post.post_id, 'file_id': this.post.file_id } });
         },
     },
     watch: {},
client/views/pages/admin/wgcommunity/WgUpdate.vue
--- client/views/pages/admin/wgcommunity/WgUpdate.vue
+++ client/views/pages/admin/wgcommunity/WgUpdate.vue
@@ -17,8 +17,8 @@
                         <tr>
                             <th>워킹그룹</th>
                             <td>
-                                <select name="" id="">
-                                    <option value="null">선택해주세요</option>
+                                <select name="" id="" v-model="post.ctgry_nm">
+                                    <option value=null disabled>선택해주세요</option>
                                     <option value="WG1">교육과정 표준체계</option>
                                     <option value="WG2">맞춤학습지원 기능</option>
                                     <option value="WG3">접근성/UDL</option>
@@ -61,39 +61,86 @@
 <script>
 import axios from 'axios';
 import COMMON_UTIL from '../../../../resources/js/commonUtil.js';
+import { useRoute } from 'vue-router';
 
 export default {
     data() {
         return {
             post: {
-                bbs_id: '0',
+                post_id: null,
                 post_title: null,
                 post_content: null,
+                notice_yn: null,
+                notice_start_dt: null,
+                notice_end_dt: null,
+                reg_dt: null,
+                mdfcn_dt: null,
                 link_url: null,
-                // 카테고리가 없는 게시판에서는 null로 설정 부탁합니다!
-                ctgry_nm: 'policy',
+                view_cnt: null,
+                file_id: null,
+                bbs_id: null,
+                rgtr_id: null,
+                mdfr_id: null,
+                ctgry_nm: null,
             },
             fileList: [],
+            deleteFileList: [],
+            insertFileList: [],
             filecount: 0,
+            insertCount: 0,
+            deleteCount: 0,
             oEditors: [], // oEditors는 스마트에디터용
+            route: useRoute(),
         };
     },
     methods: {
 
+        postSelectOne: function () {
+            const vm = this;
+            axios({
+                url: '/post/postSelectOne.json',
+                method: 'post',
+                hearder: {
+                    'Content-Type': "application/json; charset=UTF-8",
+                },
+                data: { 'post_id': vm.route.query.post_id, 'file_id': vm.route.query.file_id }
+            }).then(function (response) {
+                vm.post = response.data.postSelectOne.post;
+
+                if (response.data.selectFileList.length != 0) {
+                    vm.fileList = response.data.selectFileList;
+                    vm.filecount = response.data.selectFileList.length;
+                }
+
+                vm.initEditor(vm.post.post_content)
+            }).catch(function (error) {
+                console.log("error - ", error)
+                alert("게시글 상세보기 조회 오류, 관리자에게 문의하세요.");
+            })
+        },
+
         //게시글 및 첨부파일 등록
-        postInsert: function () {
+        postUpdate: function () {
             const vm = this;
             let formData = new FormData();
 
-            if (vm.fileList.length > 0) {
-                for (let i = 0; i < vm.fileList.length; i++) {
-                    formData.append('file', vm.fileList[i]);
-                    console.log(formData.get('file'));
+            if (vm.insertFileList.length > 0 || vm.deleteFileList.length > 0) {
+                if (vm.insertFileList.length > 0) {
+                    for (let i = 0; i < vm.insertFileList.length; i++) {
+                        formData.append('file', vm.insertFileList[i]);
+                        console.log('file - ', formData.get('file'));
+                    }
                 }
+
+                if (vm.deleteFileList.length > 0) {
+                    formData.append('deleteFile', JSON.stringify(vm.deleteFileList));
+                    console.log('deleteFile - ', formData.get('deleteFile'));
+                }
+
                 formData.append("post", JSON.stringify(vm.post));
 
                 axios({
-                    url: '/post/postFileInsert.file',
+                    url: '/post/postFileUpdate.file',
                     method: 'post',
                     headers: {
                         'Content-Type': 'multipart/form-data',
@@ -103,19 +150,19 @@
                     console.log("qnaInsert - response : ", response);
                     let result = response.data;
                     if (result > 0) {
-                        alert("등록을 완료하였습니다.");
+                        alert("수정을 완료하였습니다.");
                         vm.postSelectListPage()
                     } else {
-                        alert("등록 실패, 관리자에게 문의해주세요.");
+                        alert("수정 실패, 관리자에게 문의해주세요.");
                     }
                 }).catch(function (error) {
                     console.log("qnaInsert - error : ", error);
-                    alert("등록 오류, 관리자에게 문의해주세요.");
+                    alert("수정 오류, 관리자에게 문의해주세요.");
                 });
             } else {
 
                 axios({
-                    url: '/post/postInsert.json',
+                    url: '/post/postFileUpdate.json',
                     method: 'post',
                     headers: {
                         'Content-Type': "application/json; charset=UTF-8",
@@ -125,27 +172,24 @@
                     console.log("noticeInsert - response : ", response);
                     let result = response.data;
                     if (result > 0) {
-                        alert("등록을 완료하였습니다.");
+                        alert("수정을 완료하였습니다.");
                         vm.postSelectListPage()
                     } else {
-                        alert("등록 실패, 관리자에게 문의해주세요.");
+                        alert("수정 실패, 관리자에게 문의해주세요.");
                     }
                 }).catch(function (error) {
                     console.log("noticeInsert - error : ", error);
-                    alert("등록 오류, 관리자에게 문의해주세요.");
+                    alert("수정 오류, 관리자에게 문의해주세요.");
                 });
             }
         },
 
         //등록 유효성 검사
-        postInsertCheck: function () {
+        postUpdateCheck: function () {
             const oEditors = this.oEditors;
             oEditors.getById["smart"].exec("UPDATE_CONTENTS_FIELD", []);
             // 스마트에디터의 iframe에 있는 내용을 textarea로. 
             this.post.post_content = document.getElementById("smart").value;
-            console.log(document.getElementById("smart").value);
-            console.log(this.post.post_content);
-            console.log(COMMON_UTIL.isEmpty(this.post.post_title));
 
             if (COMMON_UTIL.isEmpty(this.post.post_title) === false) {
                 alert("제목을 입력해주세요.");
@@ -157,26 +201,56 @@
                 return false;
             }
 
-            this.postInsert();
+            this.postUpdate();
         },
 
+        // 에디터 만들기 
+        initEditor: function (initData) {
+            // 스마트 에디터 적용
+            const oEditors = this.oEditors;
+            nhn.husky.EZCreator.createInIFrame({
+                oAppRef: oEditors,
+                elPlaceHolder: "smart",
+                sSkinURI: "/client/smarteditor2-2.8.2.3/SmartEditor2Skin.html",
+                htParams: {
+                    bSkipXssFilter: true,
+                    bUseVerticalResizer: true,
+                    bUseModeChanger: true
+                },
+                fOnAppLoad: function () {
+                    oEditors.getById["smart"].exec("PASTE_HTML", [initData]);
+                },
+                fCreator: "createSEditor2"
+            });
+        },
         //파일업로드
         fileUpload: function () {
-            this.fileList[this.filecount] = this.$refs.fileInput.files[0]
-            this.filecount += 1
-            console.log("file", this.fileList);
+
+            this.insertFileList[this.insertCount] = this.$refs.fileInput.files[0];
+            this.insertCount += 1;
+            console.log("insertFile - ", this.insertFileList);
         },
 
         //파일업로드 중 업로드 파일 삭제
-        fileRemove(idx) {
-            this.fileList.splice(idx, 1);
-            console.log("reMove_file", this.fileList);
-            this.filecount = this.fileList.length;
+        fileRemove(item, idx) {
+            if (item.file_path === undefined) {
+                this.insertFileList.splice(idx, 1);
+                this.insertCount = this.insertFileList.length;
+                console.log("insertfile", this.insertFileList);
+
+            } else {
+                this.fileList.splice(idx, 1);
+                this.deleteFileList[this.deleteCount] = item
+                this.deleteCount += 1
+                this.filecount = this.fileList.length;
+                console.log("deleteFile - ", this.deleteFileList);
+            }
+
         },
 
         //게시글 리스트로 이동
         postSelectListPage: function () {
-            this.$router.push({ path: '/adm/dataSelectList.page' });
+            this.$router.push({ path: '/adm/wgSelectList.page' });
         },
 
         // 파일 업로드 커스텀을 위한 함수
@@ -188,21 +262,7 @@
     computed: {},
     components: {},
     mounted() {
-        // 스마트 에디터 적용
-        const oEditors = this.oEditors;
-        nhn.husky.EZCreator.createInIFrame({
-            oAppRef: oEditors,
-            elPlaceHolder: "smart",
-            sSkinURI: "/client/smarteditor2-2.8.2.3/SmartEditor2Skin.html",
-            htParams: {
-                bUseToolbar: true,				// 툴바 사용 여부 (true:사용/ false:사용하지 않음)
-                bSkipXssFilter: true,
-                bUseVerticalResizer: true,
-                bUseModeChanger: true
-            },
-            fCreator: "createSEditor2"
-        });
-
+        this.postSelectOne();
     }
 };
 </script>
client/views/pages/user/Data/Technology.vue
--- client/views/pages/user/Data/Technology.vue
+++ client/views/pages/user/Data/Technology.vue
@@ -70,6 +70,17 @@
 export default {
     data() {
         return {
+            postListSearch: {
+                currentPage: 1,
+                perPage: 10,
+                searchType: null,
+                searchText: null,
+                ctgry_nm: 'policy',
+                bbs_id: '3'
+            },
+            postList: [],
+            postListCount: 0,
+            postIdx: 0,
         }
     },
     methods: {
Add a comment
List