Skip to content

Commit

Permalink
무한 스크롤 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
doozi316 committed Oct 12, 2022
1 parent a08b2bf commit 96212eb
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 49 deletions.
30 changes: 18 additions & 12 deletions frontend/src/components/MainMap.vue
Expand Up @@ -38,6 +38,7 @@ import Overlay from 'ol/Overlay.js';
import ProgressSpinner from '@/components/ProgressSpinner.vue';
import { toLonLat, transform } from 'ol/proj.js';
import { defaults } from 'ol/control.js';
import { mapState } from 'vuex';
const EPSG_3857 = 'EPSG:3857';
const EPSG_4326 = 'EPSG:4326';
Expand All @@ -49,6 +50,7 @@ export default {
},
data() {
return {
processingCount: 0,
olMap: undefined,
overlay: undefined,
isShowOverlay: false,
Expand All @@ -57,19 +59,27 @@ export default {
address: undefined,
vectorSource: undefined,
iconsSource: undefined,
processingCount: 0,
};
},
computed: {
reviews() {
return this.$store.state.reviews;
},
...mapState({
reviewsForMap: (state) => state.reviewsForMap,
curReview: (state) => state.curReview,
curLon: (state) => state.curLon,
curLat: (state) => state.curLat,
}),
},
watch: {
async reviews() {
async reviewsForMap() {
if (this.vectorSource) this.vectorSource.clear();
this.drawFeatures();
},
curReview() {
if (!this.curReview || !this.curLon || !this.curLat) return;
const coordinate = [this.curLon, this.curLat];
this.olMap.getView().setZoom(18);
this.olMap.getView().setCenter(this.coordi4326To3857(coordinate));
},
},
async mounted() {
const that = this;
Expand Down Expand Up @@ -98,7 +108,7 @@ export default {
}),
});
await this.$store.dispatch('setReviews', this);
await this.$store.dispatch('setReviewsForMap', this);
this.drawFeatures();
Expand Down Expand Up @@ -154,13 +164,9 @@ export default {
);
const existFeature = that.olMap.forEachFeatureAtPixel(e.pixel, (feature) => {
this.$store.commit('setCurTitle', feature.get('title'));
this.$store.commit('setCurAddress', feature.get('address'));
this.$store.commit('setCurGrade', feature.get('grade'));
this.$store.commit('setCurReview', feature.get('review'));
this.$store.commit('setCurReviewId', feature.get('reviewId'));
this.$store.commit('setIsDisabledInput', true);
this.$store.dispatch('setFileList', this);
this.$store.dispatch('setReview', this);
return true;
});
Expand Down Expand Up @@ -200,7 +206,7 @@ export default {
src: require('../assets/images/spot.png'),
}),
});
const features = this.reviews.map((review) => {
const features = this.reviewsForMap.map((review) => {
const point = this.coordi4326To3857([review.lon, review.lat]);
const feature = new OlFeature({
geometry: new OlPoint(point),
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ProgressSpinner.vue
Expand Up @@ -13,7 +13,7 @@ export default {

<style lang="scss" scoped>
.progress-spinner {
position: fixed;
position: absolute;
top: 0;
right: 0;
bottom: 0;
Expand Down
6 changes: 2 additions & 4 deletions frontend/src/components/ReviewForm.vue
Expand Up @@ -278,8 +278,7 @@ export default {
});
await ok(this, '삭제되었습니다.');
await this.$store.dispatch('setReviews', this);
await this.$store.dispatch('setReviewsByKeySet', { that: this });
});
},
saveReview() {
Expand Down Expand Up @@ -317,8 +316,7 @@ export default {
);
await ok(this, '저장 완료되었습니다.');
this.fileList = [];
await this.$store.dispatch('setReviews', this);
await this.$store.dispatch('setFileList', this);
await this.$store.dispatch('setReview', this);
this.$store.commit('setIsDisabledInput', true);
});
},
Expand Down
53 changes: 51 additions & 2 deletions frontend/src/components/ReviewList.vue
Expand Up @@ -37,7 +37,10 @@
선택 삭제
</BButton>
</div>
<div class="review-list-area">
<div
class="review-list-area"
@scroll="onScroll"
>
<BCheckbox
v-if="isEditMode"
v-model="isAllSelected"
Expand Down Expand Up @@ -94,6 +97,12 @@
</div>
</div>
</li>
<li
v-if="processingCount > 0"
class="progress-list"
>
<ProgressSpinner />
</li>
</ul>
<div
v-else
Expand All @@ -111,23 +120,58 @@ import { utcDateStrToVisualLocalDateStr } from '@/common/DateUtil.js';
import { process } from '@/common/Api.js';
import { confirm, ok } from '@/common/Dialog.js';
import axios from 'axios';
import ProgressSpinner from '@/components/ProgressSpinner.vue';
export default {
name: 'ReviewList',
data() {
return {
processingCount: 0,
imgDirPath: IMG_DIR_PATH,
isEditMode: false,
checkedReviewIds: [],
isAllSelected: false,
reviewUpdateDate: undefined,
reviewId: undefined,
};
},
components: {
ProgressSpinner,
},
computed: {
reviews() {
return this.$store.state.reviews;
},
isEndOfList() {
return this.$store.state.isEndOfList;
},
},
created() {
this.getReviews();
},
methods: {
async onScroll(e) {
if (this.isEndOfList) return;
let { scrollTop, clientHeight, scrollHeight } = e.target;
if (scrollTop + clientHeight >= scrollHeight) {
await this.getReviews();
}
},
async getReviews() {
const params = {
that: this,
reviewUpdateDate: this.reviewUpdateDate,
reviewId: this.reviewId,
};
await this.$store.dispatch('setReviewsByKeySet', params);
if (this.reviews.length > 0) {
console.log('# reviews', this.reviews);
const lastReview = this.reviews[this.reviews.length - 1];
console.log('# lastReview', lastReview);
this.reviewUpdateDate = lastReview.reviewUpDateStr;
this.reviewId = lastReview.id;
}
},
checkAllReviews() {
this.checkedReviewIds = [];
if (this.isAllSelected) this.checkedReviewIds = this.reviews.map((re) => re.id);
Expand All @@ -147,8 +191,8 @@ export default {
});
await ok(this, '삭제되었습니다.');
await this.$store.dispatch('setReviews', this);
this.toggleEditMode();
await this.$store.dispatch('setReviewsByKeySet', { that: this });
});
},
toggleEditMode() {
Expand Down Expand Up @@ -267,6 +311,11 @@ export default {
}
}
}
> .progress-list {
position: relative;
padding: 50px 0;
}
}
> .no-review-notice {
Expand Down
14 changes: 5 additions & 9 deletions frontend/src/components/SideBar.vue
Expand Up @@ -8,8 +8,8 @@
:width="500"
class="resizable-side-bar"
>
<ReviewList v-if="isVisibleReviewList" />
<ReviewForm v-else />
<ReviewList v-show="isVisibleReviewList" />
<ReviewForm v-show="!isVisibleReviewList" />
</VueResizable>
<BButton
class="side-bar-active-btn"
Expand All @@ -25,7 +25,6 @@
import VueResizable from 'vue-resizable';
import ReviewForm from '@/components/ReviewForm.vue';
import ReviewList from '@/components/ReviewList.vue';
import { mapState } from 'vuex';
export default {
name: 'SideBar',
Expand All @@ -36,16 +35,13 @@ export default {
},
data() {
return {
processingCount: 0,
isVisibleSideBar: true,
};
},
computed: {
...mapState({
curReviewId: (state) => state.curReviewId,
isDisabledInput: (state) => state.isDisabledInput,
isVisibleReviewList: (state) => state.isVisibleReviewList,
}),
isVisibleReviewList() {
return this.$store.state.isVisibleReviewList;
},
},
methods: {
showSideBar() {
Expand Down
54 changes: 41 additions & 13 deletions frontend/src/store/index.js
Expand Up @@ -8,6 +8,7 @@ Vue.use(Vuex);
export default new Vuex.Store({
state: {
reviews: [],
reviewsForMap: [],
curLon: undefined,
curLat: undefined,
curReviewId: undefined,
Expand All @@ -18,6 +19,7 @@ export default new Vuex.Store({
isDisabledInput: true,
curFileList: [],
isVisibleReviewList: true,
isEndOfList: false,
},
mutations: {
setIsDisabledInput: (state, bool) => {
Expand All @@ -39,17 +41,15 @@ export default new Vuex.Store({
setCurReview: (state, review) => {
state.curReview = review;
},
setReviews: (state, reviews) => {
if (state.reviews && reviews && state.reviews.length !== reviews.length) {
const ids = state.reviews.map((re) => re.id);
const curReview = reviews.find((review) => !ids.includes(review.id));
if (curReview) state.curReviewId = curReview.id;
}
setReviewsByKeySet: (state, reviews) => {
state.reviews = reviews;

const review = reviews.find((review) => review.id === state.curReviewId);

setReview(state, review);
setIsVisibleReviewList(state, true);
},
addReviewsByKeySet: (state, reviews) => {
state.reviews.push(...reviews);
},
setReviewsForMap: (state, reviews) => {
state.reviewsForMap = reviews;
},
setReview: (state, review) => {
setReview(state, review);
Expand All @@ -69,12 +69,40 @@ export default new Vuex.Store({
setIsDisabledInput(state, false);
setReview(state);
},
setIsEndOfList(state, bool) {
state.isEndOfList = bool;
},
},
actions: {
async setReviews({ commit }, that) {
async setReview({ state, dispatch }, that) {
await process(that, async () => {
const result = await axios.get('/api/review/getReview', {
params: {
reviewId: state.curReviewId,
},
});
setReview(state, result.data);
dispatch('setFileList', that);
});
},
async setReviewsForMap({ commit }, that) {
await process(that, async () => {
const result = await axios.get('/api/review/getReviews');
await commit('setReviews', result.data);
const result = await axios.get('/api/review/getReviewsForMap');
await commit('setReviewsForMap', result.data);
});
},
async setReviewsByKeySet({ commit }, { that, reviewUpdateDate, reviewId }) {
await process(that, async () => {
const result = await axios.get('/api/review/getReviewsByKeySet', {
params: {
reviewUpdateDate: reviewUpdateDate,
reviewId: reviewId,
},
});
if (!reviewUpdateDate && !reviewId) commit('setReviewsByKeySet', result.data);
else commit('addReviewsByKeySet', result.data);
if (!result.data.length) commit('setIsEndOfList', true);
else commit('setIsEndOfList', false);
});
},
async setFileList({ commit, state }, that) {
Expand Down
18 changes: 15 additions & 3 deletions src/main/java/com/map/restaurant/good/controller/ReviewCtrl.java
Expand Up @@ -26,9 +26,21 @@ public void saveReview(ReviewDTO reviewDTO) {
fileService.saveFiles(reviewDTO);
}

@GetMapping("/getReviews")
public List<ReviewDTO> getReviews() {
return reviewService.getReviews();
@GetMapping("/getReview")
public ReviewDTO getReview(@RequestParam String reviewId) {
return reviewService.getReview(reviewId);
}

@GetMapping("/getReviewsByKeySet")
public List<ReviewDTO> getReviewsByKeySet(
@RequestParam(value = "reviewUpdateDate", required = false) String reviewUpdateDate,
@RequestParam(value = "reviewId", required = false) String reviewId) {
return reviewService.getReviewsByKeySet(reviewUpdateDate, reviewId);
}

@GetMapping("/getReviewsForMap")
public List<ReviewDTO> getReviewsForMap() {
return reviewService.getReviewsForMap();
}

@DeleteMapping("/deleteReviews")
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/map/restaurant/good/dao/ReviewDAO.java
Expand Up @@ -6,6 +6,9 @@
import java.util.List;
public interface ReviewDAO {
void saveReview(ReviewDTO reviewDTO);
List<ReviewDTO> getReviews();
ReviewDTO getReview(@Param("reviewId") String reviewId);
List<ReviewDTO> getReviewsByKeySet(@Param("reviewUpdateDate") String reviewUpdateDate,
@Param("reviewId") String reviewId);
List<ReviewDTO> getReviewsForMap();
void deleteReviews(@Param("reviewIds") List<String> reviewIds);
}
12 changes: 10 additions & 2 deletions src/main/java/com/map/restaurant/good/service/ReviewService.java
Expand Up @@ -24,8 +24,16 @@ public void saveReview(ReviewDTO reviewDTO) {
reviewDAO.saveReview(reviewDTO);
}

public List<ReviewDTO> getReviews() {
return reviewDAO.getReviews();
public ReviewDTO getReview(String reviewId) {
return reviewDAO.getReview(reviewId);
}

public List<ReviewDTO> getReviewsByKeySet(String reviewUpdateDate, String reviewId) {
return reviewDAO.getReviewsByKeySet(reviewUpdateDate, reviewId);
}

public List<ReviewDTO> getReviewsForMap() {
return reviewDAO.getReviewsForMap();
}

@Transactional
Expand Down

0 comments on commit 96212eb

Please sign in to comment.