3. 실제 구현

   : 이번시간에는 앞에서 설명한 대로 실제 중복체크기능을 어떻게 구현할지 소스를 보면서 설명하도록 하겠습니다.


  1) javascript(product.js)에서 로직 추가

var fnObj = {};

var ACTIONS = axboot.actionExtend(fnObj, {

    PAGE_SEARCH: function (caller, act, data) {   

        axboot.ajax({

            type: "GET",

            url: ["product"],

            data: caller.searchView.getData(),

            callback: function (res) {

            //중복기능추가용: 조회할때 기존 조회건인지를 확인하기 위해 __searched__ 속성을 더 붙여준다.

            for ( var i = 0; i < res.list.length; i++) {

            res.list[i].__searched__= true;

                }

                caller.gridView01.setData(res);

            }

        });

        return false;

    },

    PAGE_SAVE: function (caller, act, data) {

        var saveList = [].concat(caller.gridView01.getData("modified"));

        saveList = saveList.concat(caller.gridView01.getData("deleted"));  


        axboot.ajax({

            type: "PUT",

            url: ["product"],

            data: JSON.stringify(saveList),

            callback: function (res) {

                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);

                axToast.push(LANG("onsave"));

            },

            options: {

                    onError: function(err){

                    //{"message":"신규로 추가하신 [제품코드]코드는 이미 등록된 제품코드입니다."}

                       axDialog.alert({

                        title: "Error",

                            theme: "primary",

                            width:450,

                            msg: err.message

                        });    

                 }

        }

        });

    },

    ITEM_ADD: function (caller, act, data) {

        caller.gridView01.addRow();

    },

    ITEM_DEL: function (caller, act, data) {   

        caller.gridView01.delRow("selected");    

    }

});


var CODE = {};  //추가

// fnObj 기본 함수 스타트와 리사이즈

fnObj.pageStart = function () {

//

var _this = this;  


    axboot

        .call({

            type: "GET", url: "/api/v1/commonCodes", data: {groupCd: "ORIGIN"},

            callback: function (res) {

                var originList = [];

                res.list.forEach(function (n) {

                originList.push({

                CD: n.code, NM: n.name + "(" + n.code + ")"                        

                    });

                });

                this.originList = originList;

            }

        })        

        .done(function () {

            CODE = this; // this는 call을 통해 수집된 데이터들.

//위쪽 추가

            _this.pageButtonView.initView();  // this --> _this 로 변경

            _this.searchView.initView();  // this --> _this 로 변경

            _this.gridView01.initView();  // this --> _this 로 변경

    ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);

        });  //추가

};


fnObj.pageResize = function () {


};



fnObj.pageButtonView = axboot.viewExtend({

    initView: function () {

        axboot.buttonClick(this, "data-page-btn", {

            "search": function () {

                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);

            },

            "save": function () {

                ACTIONS.dispatch(ACTIONS.PAGE_SAVE);

            }

        });

    }

});


//== view 시작

/**

 * searchView

 */

fnObj.searchView = axboot.viewExtend(axboot.searchView, {

    initView: function () {

        this.target = $(document["searchView0"]);

        this.target.attr("onsubmit", "return ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);");

        this.filter = $("#filter");

    },

    getData: function () {

        return {

            pageNumber: this.pageNumber,

            pageSize: this.pageSize,

            filter: this.filter.val()

        }

    }

});



/**

 * gridView

 */

var list = [];

fnObj.gridView01 = axboot.viewExtend(axboot.gridView, {

    initView: function () {

        var _this = this;

        this.originList = CODE.originList; //추가

        

        this.target = axboot.gridBuilder({

            showRowSelector: true,

            frozenColumnIndex: 0,

            sortable: true,

            multipleSelect: true,

            target: $('[data-ax5grid="grid-view-01"]'), 

            columns: [

            {key: "prdtCd", label: "제품코드", width: 100, align: "center", editor: "text"},

                {key: "prdtNm", label: "제품명", width: 200, align: "center", editor: "text"},

                {

                    key: "origin", label: "원산지", width: 100,align: "center", editor: {

                    type: "select", config: {

                        columnKeys: {

                            optionValue: "CD", optionText: "NM"

                        },

                        options: this.originList //추가

                        /*

                        [

                        {"CD":"KR","NM":"한국(KR)"},

                        {"CD":"US","NM":"미국(US)"},

                        {"CD":"JP","NM":"일본(JP)"}

                        ]

                        */

                        

                    }

                  }

                },

                {key: "purchasePrice", label: "매입가격", width: 150, align: "right", editor: "number"},

                {key: "salesPrice", label: "판매가격", width: 150, align: "right", editor: "number"}          

            ],

            body: {

                onClick: function () {

                    this.self.select(this.dindex, {selectedClear: true});

                }

            }

        });


        axboot.buttonClick(this, "data-grid-view-01-btn", {

            "add": function () {

                ACTIONS.dispatch(ACTIONS.ITEM_ADD);

            },

            "delete": function () {

                ACTIONS.dispatch(ACTIONS.ITEM_DEL);

            }

        });

    },

    getData: function (_type) {   

        var _list = this.target.getList(_type);

        

        if (_type == "modified" || _type == "deleted") {

            list = ax5.util.filter(_list, function () {

                return this.prdtCd ;

            });

        } else {

            list = _list;

        }                

        

        return list;

    },

    addRow: function () {   

        this.target.addRow({__created__: true, origin: "KR"}, "last");

    },

    delRow: function delRow(_type) {    


    this.target.deleteRow(_type);  //여기서 무조건 deleteList에 추가해주고 있는것 같다.

   

    //그렇다보니 기존 조회된 데이터가 아닌 신규로 추가한 후 삭제해도 추가되기 때문에 

    //저장시 안넘어가도 되는 데이터(화면상에서만 행추가후 삭제시)까지 날라간다.

        

        //중복기능추가시: 조회된것이 아닌경우 deleteList에서 빼준다.        

        for(i=0;i<this.target.deletedList.length ;i++)

        {

        if(this.target.deletedList[i].__searched__==undefined)

        {

        this.target.deletedList[i]=null;

        }

        }

        

    }

});


2) Controller(ProductController) 에서 로직 추가

package com.dasdes.shopmng.controllers;


import com.chequer.axboot.core.api.response.Responses;

import com.chequer.axboot.core.controllers.BaseController;

import com.chequer.axboot.core.parameter.RequestParams;

import org.springframework.stereotype.Controller;


import com.chequer.axboot.core.api.ApiException;

import com.chequer.axboot.core.api.response.ApiResponse;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import com.dasdes.shopmng.domain.prdt.Product;

import com.dasdes.shopmng.domain.prdt.ProductService;

import com.wordnik.swagger.annotations.ApiImplicitParam;  

import com.wordnik.swagger.annotations.ApiImplicitParams; 


import javax.inject.Inject;

import java.util.List;


@Controller

@RequestMapping(value = "/api/v1/product")

public class ProductController extends BaseController {


    @Inject

    private ProductService productService;


    @RequestMapping(method = RequestMethod.GET, produces = APPLICATION_JSON)

    @ApiImplicitParams({

            @ApiImplicitParam(name = "prdtCd", value = "제품코드", dataType = "String", paramType = "query"),

            @ApiImplicitParam(name = "prdtNm", value = "제품명", dataType = "String", paramType = "query"),

            @ApiImplicitParam(name = "filter", value = "검색어", dataType = "String", paramType = "query")

    })    

    public Responses.ListResponse list(RequestParams<Product> requestParams) {

        List<Product> list = productService.gets(requestParams);

        return Responses.ListResponse.of(list);

    }


    @RequestMapping(method = {RequestMethod.PUT}, produces = APPLICATION_JSON)

    public ApiResponse save(@RequestBody List<Product> request) {

   

    //중복체크 후 중복발생 시 Exception핸들러로 받는다.

    try

    {

           productService.savePrdt(request);

    }

    catch(ApiException e)

    {

    return handleApiException(e);

    }

        return ok();

    }


 3) ProductService 에서 로직 추가

package com.dasdes.shopmng.domain.prdt;


import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional; //추가

import org.springframework.web.bind.annotation.ExceptionHandler;


import com.dasdes.shopmng.domain.BaseService;

import com.querydsl.core.BooleanBuilder;  //추가


import javax.inject.Inject;

import com.chequer.axboot.core.parameter.RequestParams;

import java.util.List;


import com.chequer.axboot.core.api.ApiException;



//import org.slf4j.Logger;

//import org.slf4j.LoggerFactory;


@Service

public class ProductService extends BaseService<Product, String>  {

//private final Logger logger = LoggerFactory.getLogger(ProductService.class);

    private ProductRepository productRepository;


    @Inject

    public ProductService(ProductRepository productRepository) {

        super(productRepository);

        this.productRepository = productRepository;

    }


    public List<Product> gets(RequestParams<Product> requestParams) {

    String prdtCd=requestParams.getString("prdtCd", "");

    String prdtNm=requestParams.getString("prdtNm", "");

    String filter = requestParams.getString("filter");

   

    BooleanBuilder builder = new BooleanBuilder();



        if (isNotEmpty(prdtCd)) {

            builder.and(qProduct.prdtCd.eq(prdtCd));

        }



        if (isNotEmpty(prdtNm)) {

            builder.and(qProduct.prdtNm.eq(prdtNm));

        }


        List<Product> prdtList = select().from(qProduct).where(builder).orderBy(qProduct.prdtCd.asc(), qProduct.prdtNm.asc()).fetch();


        if (isNotEmpty(filter)) {

        prdtList = filter(prdtList, filter);

        }

   

        return prdtList;

    }

    

    

    @Transactional

    public void savePrdt(List<Product> product) {

    Product prdt=null;

   

    for(int i=0;i<product.size();i++)

    {

        prdt=(Product)product.get(i);

   

        //신규추가된 데이터에 대해 기존에 있는데이터인지 체크

        if(prdt.isCreated() && exists(prdt.getId()))

        {

    throw new ApiException("신규로 추가하신 ["+prdt.getId()+"]코드는 이미 등록된 제품코드입니다.");

        }

    }

        save(product);

    }


4) 최종결과확인

  : 위와같이 소스를 수정하고 서버를 재기동 후 중복제품코드를 추가해서 입력해본다.





어때요? 도움이 많이 되셨나요? ~~~~~~~도움이 되셨다면 아래 꾹~~~

+ Recent posts