feat(owner-frontend, category):

- category list얻어오는 로직 추가.
- owner frontend에서 카테고리 모달 눌렀을 시 category
list 얻어오고 draw하는 기능 추가.
This commit is contained in:
hoon7566
2022-02-04 22:15:16 +09:00
parent cbbfb6965e
commit fea2b8bbd8
15 changed files with 420 additions and 3 deletions

View File

@@ -0,0 +1,14 @@
package com.justpickup.ownerfrontendservice.domain.category.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class CategoryController {
@GetMapping("/category")
public String category(){
return "/domain/category/category";
}
}

View File

@@ -0,0 +1,171 @@
<!DOCTYPE html>
<html lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layouts/layout}"
>
<head></head>
<!-- Begin Page Content -->
<div layout:fragment="content" class="container-fluid">
<!-- Page Heading -->
<h1 class="h3 mb-2 text-gray-800">category </h1>
<p class="mb-4"> 버튼을 눌러 카테고리 등록</p>
<div class="row">
<div class="col-xl-12">
<a href="#" class="btn btn-info btn-icon-split" data-toggle="modal" data-target="#myModal" >
<span class="icon text-white-50">
<i class="fas fa-info-circle"></i>
</span>
<span class="text">카테고리 생성</span>
</a>
</div>
</div>
<!-- 카테고리 Modal -->
<div class="modal fade " id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">category 등록</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-8">
<h2>Category List </h2>
<ul id="categoryList" class="list-group border border-info">
<li class="list-group-item d-flex justify-content-between align-items-center" role="button">
<span class="list-element" contenteditable="true" data-value="1"> A list item</span>
<span class="badge badge-danger badge-pill remove-element" role="button" >삭제</span>
</li>
</ul>
</div>
</div>
<div class="row m-2 text-right">
<div class="col-8">
<a id="btn_addCategory" href="#" class="btn btn-primary btn-icon-split">
<span class="icon text-white-50">
<i class="fas fa-plus"></i>
</span>
</a>
<a id="btn_save" href="#" class="btn btn-success btn-icon-split">
<span class="icon text-white-50">
<i class="fas fa-save"></i>
</span>
</a>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">닫기</button>
</div>
</div>
</div>
</div>
<script>
function init(){
dragInit();
$(document).on("click","#btn_addCategory",function (){clickAddCategory();})
$(document).on("click","#btn_save",function (){clickSave();})
$(document).on("dblclick",".list-element",function(){ dblclickCategoryList(this);})
$(document).on("keydown",".list-element",function (event){
if (event.keyCode == 13) $("#btn_addCategory").focus()
})
$(document).on("click",".remove-element",function(){ clickRemoveElement(this);})
$('#myModal').on('shown.bs.modal', function () { initCategoryList(); })
}
function initCategoryList(){
$("#categoryList").empty();
$.ajax({
type: 'get'
, url: '/store-service/category'
, success: function (ajaxData, status, request) {
$(ajaxData.data).each(function (index,element) {
$("#categoryList").append("<li class=\"list-group-item d-flex justify-content-between align-items-center\" role=\"button\">\n" +
" <span class=\"list-element\" contenteditable=\"true\" data-value=\""+element.order+"\" > "+element.name+"</span>\n" +
" <span class=\"badge badge-danger badge-pill remove-element \" role=\"button\" >삭제</span>\n" +
" </li>");
});
}
});
}
function dragInit(){
$( "#categoryList" ).sortable({
revert: true,
revertDuration: 150
});
}
function clickAddCategory(){
$("#categoryList").append("<li class=\"list-group-item d-flex justify-content-between align-items-center\" role=\"button\">\n" +
" <span class=\"list-element\" contenteditable=\"true\" > A list item</span>\n" +
" <span class=\"badge badge-danger badge-pill remove-element \" role=\"button\" >삭제</span>\n" +
" </li>");
}
function clickSave(){
alert("저장되었습니다.");
let categoryArr =[];
let order = 1;
$("#categoryList li .list-element").each(function (index,element) {
let category = {
categoryId : $(element).attr('data-value'),
categoryName : $(element).text(),
ordered : order++
}
categoryArr.push(category)
});
console.log(categoryArr);
$("#myModal").modal('toggle');
}
function dblclickCategoryList(ele) {
$(ele).focus();
const newRange = document.createRange();
newRange.setStart(ele, 1);
newRange.setEnd(ele, 1);
const selection = document.getSelection();
selection.removeAllRanges();
selection.addRange(newRange);
}
function clickRemoveElement(item){
$(item).parent().remove()
}
</script>
</div>
</html>

View File

@@ -44,6 +44,7 @@
<!-- Bootstrap core JavaScript-->
<script src="vendor/jquery/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.0/jquery-ui.js"></script>
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Core plugin JavaScript-->

View File

@@ -0,0 +1,31 @@
package com.justpickup.storeservice.domain.category.dto;
import com.justpickup.storeservice.domain.category.entity.Category;
import com.justpickup.storeservice.domain.item.entity.Item;
import com.justpickup.storeservice.domain.store.entity.Store;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.List;
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CategoryDto {
private String name;
private Integer order;
private Store store;
private List<Item> items;
public CategoryDto(Category category) {
this.name = category.getName();
this.order = category.getOrder();
this.store = category.getStore();
this.items = category.getItems();
this.name = category.getName();
}
}

View File

@@ -8,7 +8,6 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.List;
import static javax.persistence.FetchType.LAZY;
@@ -24,7 +23,8 @@ public class Category extends BaseEntity {
private String name;
private Integer orders;
@Column(name = "orders")
private Integer order;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "store_id")

View File

@@ -0,0 +1,13 @@
package com.justpickup.storeservice.domain.category.repository;
import com.justpickup.storeservice.domain.category.entity.Category;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CategoryRepository extends JpaRepository<Category, Long> {
List<Category> findAllByStoreIdOrderByOrder(Long storeId);
}

View File

@@ -0,0 +1,28 @@
package com.justpickup.storeservice.domain.category.service;
import com.justpickup.storeservice.domain.category.dto.CategoryDto;
import com.justpickup.storeservice.domain.category.repository.CategoryRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class CategoryService {
private final CategoryRepository categoryRepository;
public List<CategoryDto> getCategoryList(Long storeId){
return categoryRepository.findAllByStoreIdOrderByOrder(storeId)
.stream()
.map(CategoryDto::new)
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,50 @@
package com.justpickup.storeservice.domain.category.web;
import com.justpickup.storeservice.domain.category.dto.CategoryDto;
import com.justpickup.storeservice.domain.category.service.CategoryService;
import com.justpickup.storeservice.global.dto.Result;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequiredArgsConstructor
@Slf4j
public class CategoryController {
private final CategoryService categoryService;
@GetMapping("/category")
public ResponseEntity getCategoryList( ){
Long storeId = 1L;
List<CategoryDto> categoryList = categoryService.getCategoryList(storeId);
List<CategoryResponse> categoryResponseList = categoryList.stream()
.map(CategoryResponse::new)
.collect(Collectors.toList());
return ResponseEntity.status(HttpStatus.OK)
.body(Result.createSuccessResult(categoryResponseList));
}
@Data
static class CategoryResponse{
private String name;
private Integer order;
public CategoryResponse (CategoryDto categoryDto){
this.name= categoryDto.getName();
this.order= categoryDto.getOrder();
}
}
}

View File

@@ -0,0 +1,12 @@
package com.justpickup.storeservice.global.client.exception;
import com.justpickup.storeservice.global.exception.CustomException;
import org.springframework.http.HttpStatus;
public class FeignClientException extends CustomException {
public FeignClientException(HttpStatus status, String message) {
super(status, message);
}
}

View File

@@ -0,0 +1,38 @@
package com.justpickup.storeservice.global.client.exception;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.justpickup.storeservice.global.dto.Result;
import feign.Response;
import feign.codec.ErrorDecoder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
@RequiredArgsConstructor
@Slf4j
public class FeignClientExceptionErrorDecoder implements ErrorDecoder {
private final ObjectMapper objectMapper;
@Override
public Exception decode(String methodKey, Response response) {
String message = null;
if (response.body() != null) {
try {
Result result = objectMapper.readValue(response.body().asInputStream(), Result.class);
message = result.getMessage();
} catch (IOException e) {
String catchErrorMessage = "Error Deserializing response body from failed feign request response.";
log.warn(methodKey + catchErrorMessage, e);
return new FeignClientException(HttpStatus.INTERNAL_SERVER_ERROR, "고객센터로 문의해주세요.");
}
}
return new FeignClientException(HttpStatus.INTERNAL_SERVER_ERROR, message);
}
}

View File

@@ -0,0 +1,10 @@
package com.justpickup.storeservice.global.client.user;
import lombok.Data;
@Data
public class GetCustomerResponse {
private Long userId;
private String userName;
private String phoneNumber;
}

View File

@@ -0,0 +1,13 @@
package com.justpickup.storeservice.global.client.user;
import com.justpickup.storeservice.global.dto.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name = "USER-SERVICE", url = "127.0.0.1:8001/user-service")
public interface UserClient {
@GetMapping("/customer/{userId}")
Result<GetCustomerResponse> getUser(@PathVariable("userId") Long userId);
}

View File

@@ -0,0 +1,14 @@
package com.justpickup.storeservice.global.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignClientConfig {
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}

View File

@@ -0,0 +1,22 @@
package com.justpickup.storeservice.global.config;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Configuration
@EnableJpaAuditing
public class QueryDslConfig {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(this.entityManager);
}
}

View File

@@ -7,7 +7,7 @@ spring:
jpa:
hibernate:
ddl-auto: create-drop
ddl-auto: validate
properties:
hibernate:
format_sql: true