2021. 12. 8. 16:52ㆍ스프링부트
주문 시 db에 저장 할 주문 정보는 order테이블에 메뉴정보는 order_detail테이블에 json으로 저장합니다
json을 편하게 변환하기 위해 gson라이브러리를 사용하겠습니다
<!-- json 변환 --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency>
저장 후 maven 업데이트를 해도 에러가 뜰때가 있는데 이럴땐 서버를 완전히 종료 후 재실행하면 적용됩니다
JSON 변환하기 (Gson , json-simple)
1. Gson 라이브러리로 변환하기 2. json-simple 라이브러리로 변환하기 1. Gson maven 라이브러리 추가 com.google.code.gson gson 변환할 클래스 class Student { String name; int age; public Student(String n..
sumin2.tistory.com
메뉴 정보를 담을 클래스를 생성합니다
@Getter @Setter @ToString @AllArgsConstructor public class OrderDetail { private String orderNum; private String foodInfoJSON; }
OrderController payment메서드의 주문처리 부분을 주석 해제하고 service, dao를 추가합니다
orderService
public String order(CartList cart, OrderInfo info, LoginService user, HttpSession session);
orderServiceImp
@Transactional @Override public String order(CartList cart, OrderInfo info, LoginService user, HttpSession session) { Gson gson = new Gson(); System.out.println("info = " + info); int total = cart.getCartTotal(); info.setStoreId(cart.getStoreId()); info.setTotalPrice(total); long userId = 0; if (user != null) { userId = user.getUser().getId(); info.setUserId(userId); } List<Cart> cartList = cart.getCart(); OrderDetail[] detail = new OrderDetail[cartList.size()]; for(int i=0;i<detail.length;i++) { String cartJSON = gson.toJson(cartList.get(i)); detail[i] = new OrderDetail(info.getOrderNum(), cartJSON); } orderDAO.order(info); orderDAO.orderDetail(detail, userId); return null; }
주문정보와 메뉴정보를 db에 입력하다 에러가 날 경우 전부 취소하기 위해 @Transactional를 붙여줍니다
orderDAO
// 주문 정보 입력 void order(OrderInfo info); // 주문 상세정보 입력 void orderDetail(OrderDetail[] detail, long userId);
orderDAOImp
@Override public void order(OrderInfo info) { sql.insert("order.order", info); } @Override public void orderDetail(OrderDetail[] detail, long userId) { Map<String, Object> map = new HashMap<>(); map.put("userId", userId); map.put("detail", detail); sql.insert("order.orderDetail", map); }
orderMappler.xml
<insert id="order"> <if test="userId == 0"> INSERT INTO BM_ORDER_NON_USER ( ORDER_NUM ,STORE_ID ,USER_ID ,PAY_METHOD ,PHONE ,DELEVERY_ADDRESS1 ,DELEVERY_ADDRESS2 ,DELEVERY_ADDRESS3 ,TOTAL_PRICE ,USED_POINT ,REQUEST ) VALUES ( ${orderNum } ,#{storeId } ,#{userId } ,#{payMethod } ,#{phone } ,#{deleveryAddress1 } ,#{deleveryAddress2 } ,#{deleveryAddress3 } ,#{totalPrice } ,#{usedPoint } ,#{request } ) </if> <if test="userId != 0"> INSERT INTO BM_ORDER_USER ( ORDER_NUM ,STORE_ID ,USER_ID ,PAY_METHOD ,PHONE ,DELEVERY_ADDRESS1 ,DELEVERY_ADDRESS2 ,DELEVERY_ADDRESS3 ,TOTAL_PRICE ,USED_POINT ,REQUEST ) VALUES ( ${orderNum } ,#{storeId } ,#{userId } ,#{payMethod } ,#{phone } ,#{deleveryAddress1 } ,#{deleveryAddress2 } ,#{deleveryAddress3 } ,#{totalPrice } ,#{usedPoint } ,#{request } ) </if> </insert>
insert all문은 하나의 쿼리로 insert를 여러번 할 수 있는데 select문의 들어가야 하기 때문에 SELECT * FROM DUAL을 붙여 주었습니다
실행 결과

로그인 이용자는 주문 완료 시 포인트 적립이 되야 합니다
OrderServiceImp의 order메서드 아래에 코드를 추가합니다
// 회원 포인트 적립 if (user != null) { String storeName = cart.getStoreName(); int point = (int)(total * 0.01); int result = adminDAO.pointUpdate(userId, storeName, point); if(result == 1) { UserInfoSessionUpdate.sessionUpdate(point+"", "point", user, session); } }
포인트 업데이트 관련 메서드는 adminDAO를 따로 만들어서 추가하겠습니다
OrderServiceImp에 의존성을 추가하고 adminDAO를 생성합니다
@Autowired private AdminDAO adminDAO;
public interface AdminDAO { int pointUpdate(long userId, String info, int point); }
@Repository public class AdminDAOImp implements AdminDAO { @Autowired private SqlSession sql; @Override public int pointUpdate(long userId, String info, int point) { Map<String, Object> map = new HashMap<>(); map.put("userId", userId); map.put("info", info); map.put("point", point); return sql.insert("admin.pointUpdate", map); } }
adminMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="admin"> <insert id="pointUpdate" > INSERT INTO BM_POINT ( USER_ID ,INFO ,POINT ) VALUES ( #{userId } ,#{info } ,#{point } ) </insert> </mapper>
이제 db에는 포인트가 업데이트 되지만 아직 세션이 업데이트되지 않아 재로그인 하기 전까진 포인트사용을 할 수 없습니다
세션 업데이트를 위해 util패키지에 클래스를 추가합니다
public class UserInfoSessionUpdate { public static void sessionUpdate(String value, String valueType, LoginService user, HttpSession session) { LoginService loginService = (LoginService) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if(valueType.equals("nickname")) { loginService.getUser().setNickname(value); } else if(valueType.equals("password")) { loginService.getUser().setPassword(value); } else if(valueType.equals("point")) { int point = loginService.getUser().getPoint() + Integer.parseInt(value); loginService.getUser().setPoint(point); } SecurityContext sc = SecurityContextHolder.getContext(); sc.setAuthentication(new UsernamePasswordAuthenticationToken(loginService, null, user.getAuthorities())); session.setAttribute("SPRING_SECURITY_CONTEXT", sc); } }
나중에 구현할 닉네임, 비밀번호 업데이트 코드를 미리 추가했습니다
이제 주문시 포인트가 적립되는 걸 볼 수 있습니다
-- 그런데 이 기능은 주문 시가 아니라 가게에서 주문을 수락하고 배달 완료가 될 때 적립되도록 변경 하는게 좋을거같습니다


마찬가지로 포인트를 사용하면 포인트가 차감되야 합니다
OrderServiceImp의 order메서드 아래에 코드를 추가합니다
// 로그인 사용자가 포인트 사용했을때 if(info.getUsedPoint() != 0 ) { String storeName = cart.getStoreName(); int usedPoint = -info.getUsedPoint(); int result = adminDAO.pointUpdate(userId, storeName, usedPoint); if(result == 1) { UserInfoSessionUpdate.sessionUpdate(usedPoint+"", "point", user, session); } }
실행 결과

주문 완료후 주문 목록을 보기 위해 Controller에 추가합니다
@GetMapping("/orderList") public String orderList(@AuthenticationPrincipal LoginService user, Model model) { if (user == null) { System.out.println("비로그인"); } else { System.out.println("로그인"); long userId = user.getUser().getId(); List<OrderList> orderList = orderService.orderList(userId); if (orderList.size() == 0) { return "order/orderList"; } List<List<Cart>> cartList = new ArrayList<>(); for (int i=0;i<orderList.size();i++) { cartList.add(FoodInfoFromJson.foodInfoFromJson(orderList.get(i).getFoodInfo())); } model.addAttribute("user", user.getUser()); model.addAttribute("cartList", cartList); model.addAttribute("orderList", orderList); } return "order/orderList"; }
service, dao를 추가합니다
orderService
// 주문목록 List<OrderList> orderList(long userId);
orderServiceImp
@Override public List<OrderList> orderList(long userId) { return orderDAO.orderList(userId); }
orderDAO
List<OrderList> orderList(long userId);
orderDAOImp
@Override public List<OrderList> orderList(long userId) { return sql.selectList("order.orderList", userId); }
orderMapper.xml
<select id="orderList" resultType="OrderList"> SELECT * FROM ( SELECT ROWNUM R ,O.* FROM (SELECT count(*) over() list_count, o.order_num, o.user_id, o.order_date, o.pay_method, o.delevery_status, o.delevery_address1, o.delevery_address2, o.delevery_address3, o.store_id, o.total_price, o.used_point, o.request, d.food_info, s.store_name, s.store_img, s.store_thumb, s.delevery_tip, r.review_content, r.score, r.review_img FROM bm_order_user o LEFT JOIN (SELECT ORDER_NUM, LISTAGG(FOOD_INFO, '/') food_info FROM BM_ORDER_DETAIL_USER GROUP BY ORDER_NUM) d ON o.order_num = d.order_num LEFT JOIN bm_store s ON o.store_id = s.id LEFT JOIN bm_review r ON o.order_num = r.order_num WHERE o.user_id = #{userId } ORDER BY o.order_date desc ) O ) </select>
listagg는 첫번 째 인자의 결과가 여러개가 있을 때 두번 째 인자의 구분자로 합쳐서 하나의 컬럼으로 보여줍니다
listagg 사용x

listagg 사용o

불러온 json형태의 메뉴 정보를 오브젝트로 변환하기 위해 util패키지에 추가합니다
public class FoodInfoFromJson { public static List<Cart> foodInfoFromJson(String foodInfoJSON) { Map<String, Object> map = new HashMap<>(); String[] arr = foodInfoJSON.split("/"); Gson gson = new Gson(); List<Cart> cartList = new ArrayList<>(); for(int i=0;i<arr.length;i++) { cartList.add(gson.fromJson(arr[i], Cart.class)); } return cartList; } }
이제 화면을 보여줄 jsp,css와 js를 추가합니다
리뷰 모달에서 이미지 첨부시 미리보기 기능을 위해 util.js에 코드를 추가합니다
function imgPreview(e,target){ const previewBox = target.siblings("div"); const preview = previewBox.find(".preview"); const fileReader = new FileReader(); fileReader.readAsDataURL(e.target.files[0]); fileReader.onload = function() { preview.attr("src", fileReader.result); previewBox.css("display", "block"); } } function imgClose() { $(".preview").attr("src", ""); $(".img").val(""); $(".img_box div").css("display", "none"); }
실행 결과

'스프링부트' 카테고리의 다른 글
스프링부트+jsp로 배달사이트 만들기-16 리뷰 사진 올리기 (0) | 2021.12.09 |
---|---|
스프링부트+jsp로 배달사이트 만들기-15 리뷰작성 (0) | 2021.12.08 |
스프링부트+jsp로 배달사이트 만들기-12 가게 정보 탭 (0) | 2021.12.07 |
스프링부트+jsp로 배달사이트 만들기-11 장바구니추가, 삭제 (2) | 2021.12.07 |
스프링부트+jsp로 배달사이트 만들기-10 음식 목록 가져오기 (0) | 2021.12.07 |