20240405
(frontend)
-AddGallery.vue
-화면출력

// AddGallery.vue // vueInit
<template>
<div>
<div class="col-6 mx-auto">
<!-- {/* 이미지명(fileTitle) 입력 박스 시작 */} -->
<div class="row g-3 align-items-center mb-3">
<div class="col-3">
<label htmlFor="fileTitle" class="form-label"> 이미지명 </label>
</div>
<div class="col-9">
<input
type="text"
class="form-control"
id="galleryTitle"
name="galleryTitle"
v-model="gallery.galleryTitle"
/>
</div>
</div>
<!-- {/* 이미지명 입력 박스 끝 */} -->
<div class="input-group mb-3">
<!-- {/* upload 선택상자/버튼 start */} -->
<!-- TODO: 파일선택상자 v-model 안됨 -->
<!-- TODO: 사용법 : ref="변수명" -->
<!-- TODO: Vue 에서 html 태그에 변수명 부여해서 직접접근 -->
<!-- TODO: 파일선택상자 : files[번호] 배열속성이 있고,
선택한 파일이 배열에 저장됨
-->
<!-- 예) course.jpg -> files[0] = "course.jpg" -->
<input type="file" ref="file" @change="selectImage" />
<button
class="btn btn-outline-secondary"
type="button"
id="inputGroupFileAddon04"
@click="create"
>
Upload
</button>
</div>
<!-- {/* upload 선택상자/버튼 end */} -->
<!-- {/* upload 성공/실패 메세지 출력 시작 */} -->
<div v-if="message" class="alert alert-success" role="alert">
{{ message }}
</div>
<!-- {/* upload 성공/실패 메세지 출력 끝 */} -->
</div>
</div>
</template>
<script>
import GalleryService from '@/services/advanced/GalleryService';
export default {
// TODO: 데이터 바인딩 속성 정의
data() {
return {
currentImage: undefined, // 현재이미지
message: "", // 성공메세지 변수
gallery: {
uuid: null, // 기본키
galleryTitle: "", // 파일 제목
fileUrl: "", // 갤러리파일 url
}, // 파일 객체
};
},
methods: {
// TODO: 파일 선택상자에서 이미지 선택하면 변수에 저장하는 함수
selectImage() {
// 1) 파일선택상자에서 1st 로 선택한 이미지를 변수에 저장
// ref="file" 접근 -> 내부 속성 : files[번호]
// TODO: 사용법 : this.$refs.변수명 => input type="file" ref="변수명" 태그 접근
this.currentImage = this.$refs.file.files[0];
// 성공메세지 변수 초기화
this.message = "";
},
// TODO: insert(추가:파일업로드) 함수
async create() {
try {
// TODO: insert 요청 : 공통 추가 함수 : create()
// TODO: 비동기 코딩 : async ~ await
let response = await GalleryService.create(
this.gallery,
this.currentImage
);
// 로깅
console.log(response);
// 화면에 성공메세지 출력
this.message = response.data;
} catch (e) {
// 현재선택된 이미지 변수 초기화
this.currentImage = undefined;
this.message = ""
console.log(e);
}
},
},
};
</script>
<style></style>
-GalleryService.js
// TODO: 공통 insert 함수
// TODO: 1) 문서형태 : multipart/form-data
// TODO: 2) 파일업로드 : 오로지 form 태그 == FormData 객체만 전송 가능
create(gallery, image) {
let formData = new FormData(); // form 객체
formData.append("galleryTitle", gallery.galleryTitle); // 제목
formData.append("image", image); // 이미지
return http.post("/advanced/gallery/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
}
(backend)
-GalleryController.java
// 2) 이미지 다운로드 함수
@GetMapping("/gallery/{uuid}")
public ResponseEntity<byte[]> findDownload(@PathVariable String uuid) {
Gallery gallery = galleryService.findById(uuid).get(); // 상세조회
return ResponseEntity.ok()
// Todo : attachment: => attachment;
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + gallery.getGalleryFileName() + "\"")
.body(gallery.getGalleryData());
}
// 저장(insert) -> post 방식 -> @PostMapping
@PostMapping("/gallery/upload")
public ResponseEntity<Object> create(
@RequestParam(defaultValue = "") String galleryTitle,
@RequestParam MultipartFile image
) {
try {
// DB 서비스 함수 실행
galleryService.save(null, galleryTitle, image);
return new ResponseEntity<>("업로드 성공", HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>("업로드시 에러가 발생"
, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
-화면출력

-이미지추가 화면출력

-router -> index.js
// fileDb 상세조회 (== 수정페이지)
{
path: "/fileDb/:uuid",
component: () => import("../views/advanced/fileDb/FileDbDetail.vue"),
},
-FileDbDetail.vue
data() {
return {
currentImage: undefined, // 선택이미지
message: "", // 성공메세지 변수
fileDb: {
// 웹매개변수(url) 전달방식 :
// TODO: 사용법 : this.$router.params.uuid
// TODO: 참조) router/index.js => path: /fileDb/:uuid
// TODO: 2개의 변수명이 일치해야함 : uuid
uuid: this.$router.params.uuid,
fileTitle: "",
fileContent: "",
fileUrl: ""
}
}
},
methods: {
// TODO: 상세조회 함수
get(){},
// TODO: 파일선택상자에서 이미지를 선택할때 실행될함수
selectImage(){},
// TODO: 수정함수(update)
update(){}
},
// TODO: 화면이 뜰때 자동실행 함수
mounted() {
this.get(this.$router.params.uuid); // 상세조회 실행
this.message = ""; // 초기화
},
-FileDbDetail.vue
methods: {
// TODO: 상세조회 함수 (기본키 : uuid)
get(uuid) {
// TODO: 공통 상세조회 함수 : get()
},
-FileDcService.js
methods: {
// TODO: 상세조회 함수 (기본키 : uuid)
async get(uuid) {
try {
// TODO: 공통 상세조회 함수 : get()
// TODO: 비동기 코딩 : await ~ catch
let response = await FileDbService.get(uuid);
this.fileDb = response.data; // spring 결과 -> fileDb에 저장
// 로깅
console.log(response.data);
} catch (e) {
console.log(e);
}
},
-FileDbController.java
// 상세조회 함수
// 조회(select) -> get 방식 -> @GetMapping
@GetMapping("/gallery/get/{uuid}")
public ResponseEntity<Object> findById(
@PathVariable String uuid
) {
try {
// DB 상세조회 서비스 함수 실행
Optional<Gallery> optionalGallery = galleryService.findById(uuid);
if (optionalGallery.isEmpty() == true) {
// 데이터 없음(203)
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} else {
// 데이터 있음(200)
return new ResponseEntity<>(optionalGallery.get()
, HttpStatus.OK);
}
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
// TODO: 상세조회 함수
// 조회(select) -> get 방식 -> @GetMapping
get(uuid) {
return http.get(`/advanced/fileDb/get/${uuid}`);
}
// TODO: 수정 함수
// TODO: 수정(update) -> put 방식 -> @PutMapping
// TODO: 1) 문서형태 : multipart/form-data
// TODO: 2) 파일업로드 : 오로지 form 태그 == FormData 객체만 전송 가능
update(fileDb, image){
// 1) FormData 객체 생성
let formData = new FormData();
// 2) form 객체변수에 값 추가 : append("키", 값);
formData.append("fileTitle", fileDb.fileTitle);
formData.append("fileContent", fileDb.fileContent);
formData.append("image", image);
// 3) 벡엔드 통신 : put 방식 -> put()
return http.put(`/advanced/fileDb/${fileDb.uuid}`, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
}
// TODO: 파일선택상자에서 이미지를 선택할때 실행될함수
selectImage() {
// TODO: 파일선택상자에서 1st 선택한 이미지를 currentImage 변수에 저장
this.currentImage = this.$refs.file.files[0];
// 성공메세지 초기화
this.message = "";
},
// TODO: 수정함수(update)
async update() {
// TODO: 공통 수정(update) 함수 실행 : update()
try {
// TODO: 공통 수정함수 실행
// TODO: 비동기 코딩 : async ~ await
let response = await FileDbService
.update(this.fileDb, this.currentImage);
// 성공 메세지 출력
this.message = response.data;
} catch(e) {
this.currentImage = undefined; // 초기화
this.message = "에러 : " + e; // 에러 출력
console.log(e);
}
},
},
// TODO: 화면이 뜰때 자동실행 함수
mounted() {
this.get(this.$route.params.uuid); // 상세조회 실행
this.message = ""; // 초기화
},
// TODO: 수정함수
// 수정(update) -> put 방식 -> @PutMapping
@PutMapping("/fileDb/{uuid}")
public ResponseEntity<Object> update(
@PathVariable String uuid,
@RequestParam(defaultValue = "") String fileTitle,
@RequestParam(defaultValue = "") String fileContent,
@RequestParam MultipartFile image
) {
try {
// DB 수정 서비스 함수 실행
fileDbService.save(uuid, fileTitle, fileContent, image);
return new ResponseEntity<>("업로드 수정 성공"
,HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>("서버 에러"
,HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
-화면출력

-FileDbService.js
// TODO: 삭제 함수 : 기본키(uuid)
// TODO: 삭제(delete) -> delete 방식->@DeleteMapping
delete(uuid){
return http.delete(`/advanced/fileDb/deletion/${uuid}`);
}
-FileDbList.vue
// TODO: 삭제 함수
deleteFileDb() {},
// TODO: 공통함수(페이징)
// TODO: select 박스 변경시 실행될 함수
// TODO: select 태그 연결
pageSizeChange() {
this.page = 1; // 2) 현재 페이지번호 초기화(1)
this.retrieveFileDb(); // 3) 재조회 요청
},
},
// TODO: 화면이 뜰때 자동 실행 함수
mounted() {
// TODO: 화면이 뜰때 전체조회
this.retrieveFileDb();
},
-FileController.java
// TODO: 삭제함수
// 삭제(delete) -> delete 방식 -> @DeleteMapping
@DeleteMapping("/gallery/deletion/{uuid}")
public ResponseEntity<Object> delete(
@PathVariable String uuid
) {
try {
// DB 삭제 서비스 실행
boolean success = galleryService.removeById(uuid);
if(success == true) {
// 삭제 성공
return new ResponseEntity<>(HttpStatus.OK);
} else {
// 0건 삭제 => 삭제할 데이터 없음
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}