---
# System prepended metadata

title: 기능 B 구현

---

# 기능 B 구현

## 참가자 - 3주차
| **김세영** | **신우진** | **신효근** | **이용광** | **이재영** | **이태욱** | **박태현** | **정지승** | 
| :-------: | :-------: | :-------: | :-------: | :-------: | :-------: | :-------: | :-------: |
| <img src="https://avatars.githubusercontent.com/u/63814960?v=4" width="80"> | <img src="https://avatars.githubusercontent.com/u/76616101?v=4" width="80"> | <img src="https://avatars.githubusercontent.com/u/52554235?v=4" width="80"> | <img src="https://avatars.githubusercontent.com/u/48857296?s=400&v=4" width="80"> | <img src="https://avatars.githubusercontent.com/u/42104898?s=400&v=4" width="80"> | <img src="https://avatars.githubusercontent.com/u/72855455?v=4" width="80"> | <img src="https://avatars.githubusercontent.com/u/37128456?v=4" width="80"> | <img src="https://avatars.githubusercontent.com/u/49086747?v=4" width="80">
| [J034 김세영](https://github.com/se030) | [J113 신우진](https://github.com/gintooooonic) | [J116 신효근](https://github.com/dldydrhkd) | [J147 이용광](https://github.com/yjooooo) | [J157 이재영](https://github.com/lee-3-8) | [J167 이태욱](https://github.com/Najeong-Kim) | [K025 박태현](https://github.com/CrewDaniel) | [S053 정지승](https://github.com/JungJiSeung)

## 프론트엔드 구현사항
기능 | 상태 | 관련 파일
--- | --- | ---
이미지 표시 | 완료 | ```stargram/main```
이미지 링크 복사 | 완료 | ```stargram/main```
페이지 이동 | 완료 | ```stargram/main``` ```stargram/upload_image``` 


### 메인페이지에서 랜덤으로 이미지 전시
[`flutter_staggered_grid_view`](https://pub.dev/packages/flutter_staggered_grid_view) 패키지를 활용하여 메인 페이지 UI를 구성하였습니다.

#### Retrofit으로 서버에서 이미지 url 다운로드
```.dart
  loadImage() {
    // 전체 이미지 다운로드
    var imageData = server.getImages('');

    imageData.then((imageList) {
      this.imageList = imageList;

      setState(() {
        isLoaded = true;
      });
    });
  }
```

#### `flutter_staggered_grid_view`로 UI 구성, 이미지 표시
```.dart
body: isLoaded
          ? StaggeredGridView.countBuilder(
              primary: false,
              itemCount: imageList.length,
              crossAxisCount: 4,
              mainAxisSpacing: 4,
              crossAxisSpacing: 4,
              itemBuilder: (context, index) =>
                  _Tile(index, imageList[index].image),
              staggeredTileBuilder: (index) => const StaggeredTile.fit(2),
            )
```
itemCount로 아이템의 수와, itemBuilder로 내부 컴포넌트를 참조합니다.

```.dart
Center(
                  child: InkWell(
                child: Image.network(
                  url,
                ),
                onLongPress: () {
                  FlutterClipboard.copy(url).then((value) => {
                        ScaffoldMessenger.of(context).showSnackBar(
                          SnackBar(
                            content: const Text('이미지 주소가 복사 되었습니다.'),
                            duration: Duration(milliseconds: 5000),
                          ),
                        )
                      });
                },
              )),
```
서버에서 받아온 URL을 ```Image.network(url)``` 으로 불러와 표시합니다.
이미지를 길게 누르게 되면 이미지 주소(url)를 복사하고 Snackbar로 표시합니다.


### 이미지 다운로드
[`clipboard`](https://pub.dev/packages/clipboard) 패키지를 활용하여 메인페이지에서 이미지를 길게 누르면(long press) '이미지가 주소가 복사 되었습니다'라는 Snackbar와 함께 해당 이미지의 주소가 복사됩니다.


### 메인페이지 - 업로드 페이지 연결
메인 페이지 상단 우측에서 업로드 버튼을 통해 업로드 페이지로 이동합니다. (Navigator 활용)
```.dart
Widget build(BuildContext context) {
    loadImage();
    return Scaffold(
      appBar: AppBar(),
      body: isLoaded ? StaggeredGridView.countBuilder() : Text(''),
     );}

```


### C 기능 작업시 변경해야할 사항
1. 서버 연동 IP 변경
    * lib/retrofit/DiService.dart - BASE_URL 변경
    * lib/retrofit/RetrofitService.dart - @RestApi 파라미터
    * lib/retrofit/RetrofitService.g.dart - _RetrofitService 생성자 내부
    * lib/upload_image.dart - uploadImageData() 함수 내부


</br>

## 백엔드 구현사항
기능 | 상태 | 관련 파일
--- | --- | ---
API를 위한 Express 서버 | 완료 | ```backend/```
데이터베이스 연동 | 완료 | ```backend/modules/db```
엘라스틱 서치를 사용한 동의어 검색 | 완료 | ```backend/modules/search```
이미지 업로드 | 완료 | ```backend/middleware/multer```

</br>

### /images 라우터
- `/images`로 `HTTP GET`을 받으면, MYSQL에 저장된 이미지들의 정보를 JSON으로 반환합니다.


![](https://i.imgur.com/Je3KoPF.png)


</br>

### /upload 라우터
- `/upload`로 `HTTP GET`을 받으면, 이미지 업로드 폼을 띄웁니다.
  - [PUG 템플릿 엔진](https://www.npmjs.com/package/pug)을 이용하였습니다.
- `/upload`로 `HTTP POST`을 받으면, 폼에 입력된 이미지의 정보를 백엔드 서버의 MYSQL에 저장합니다.
  - 이미지 파일 저장은 [multer 미들웨어](https://www.npmjs.com/package/multer)를 이용하였습니다. 


![](https://i.imgur.com/zbnklAt.png)

<br />

## 실행화면

![](https://user-images.githubusercontent.com/49086747/128632882-6df4e580-f1c1-4aad-b1c2-92aa47415642.png)