Axboot 멀티 테이블 수정/저장 예제 (1/2)

Axboot 멀티 테이블 수정/저장 예제 (1/2)

[제품 가격 History]

두개 이상의 테이블을 컨트롤하는 예제를 처리하기 위해 기존 예제에 적합한

제품 가격이 변경될 때마다 그 내역을 관리할 수 있는 화면을 만들어 보기로 한다.

1. 작성순서

   1) 먼저 제품 가격 History를 저장할 수 있는 테이블을 생성하고 조회할 수 있는 화면을 만든다.

      (이 부분은 화면생성부분을 참고하기 바랍니다. 여기서는 대략적으로 설명할 예정입니다.)

      -Axboot 신규화면 만들기 1~3 참고       

       Axboot 신규화면 만들기 1 - DB생성 및 서버단 소스생성

       Axboot 신규화면 만들기 2 - 화면 소스 만들기

       Axboot 신규화면 만들기 3 - 정상적인 CRUD를 위한 JAVA소스 수정

   

   2) 이전 단계에서 만든 제품정보의 판매가격 변경 시 제품 가격 History테이블에 저장하는 로직을 추가한다.

2. 구현

   1) 제품 History테이블 생성      

CREATE TABLE `prdt_price_hist` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`prdt_cd` VARCHAR(20) NOT NULL COMMENT '제품코드',
`ch_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '변경일시',
`sales_price` INT(10) NOT NULL DEFAULT '0' COMMENT '판매가격',
`CREATED_AT` DATETIME(6) NULL DEFAULT NULL,
`CREATED_BY` VARCHAR(255) NULL DEFAULT NULL,
`UPDATED_AT` DATETIME(6) NULL DEFAULT NULL,
`UPDATED_BY` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COMMENT='제품가격History'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=4

  2) JAVA 코드 생성

      : https://localhost:8080/modelExtractor/db 접속 후 위에서 만들어진 테이블 클릭 후 기본 JAVA코드를 생성하자.
        (위 Axboot 신규화면 만들기 1 참조 - 코드생성 시 Package Name : prdt , Class Name : PrdtPriceHist 로 입력)    

  3) 제품 가격 History 화면소스 만들기

      : 간단히 기존에 만들었던 제품 정보 화면 소스를 복사해서 PrdtPriceHist.jsp와 PrdtPriceHist.js 로 

        이름을 변경한 후 일부만 수정하면 된다.

        (추가적으로 위 링크의 화면소스만들기 2를 참고하여 webapp하위의 axboot.config.js 에 js에서 호출할 

         약식이름과 full명의 mapping설정한다. - "prdtPriceHist":"/api/v1/prdtPriceHist")

        

     - PrdtPriceHist.jsp 수정     

<%@ page contentType="text/html; charset=UTF-8" %>

<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="ax" tagdir="/WEB-INF/tags" %>

<ax:set key="system-common-code-version" value="1.0.0"/>

<ax:set key="title" value="${pageName}"/>

<ax:set key="page_desc" value="${pageRemark}"/>

<ax:set key="page_auto_height" value="true"/>

<ax:layout name="base">

    <jsp:attribute name="script">

        <ax:script-lang key="ax.script" var="LANG" />

        <ax:script-lang key="ax.admin" var="COL" />

        <script type="text/javascript" src="<c:url value='/assets/js/view/shopmng/prdtPriceHist.js' />"></script>

    </jsp:attribute>

    <jsp:body>

        <ax:page-buttons></ax:page-buttons>

        <div role="page-header">

            <ax:form name="searchView0">

                <ax:tbl clazz="ax-search-tbl" minWidth="500px">

                    <ax:tr>

                        <ax:td label='ax.admin.search' width="300px">

                            <ax:input type="text" name="filter" id="filter" clazz="form-control" placeholder="ax.admin.input.search"/>

                        </ax:td>

                    </ax:tr>

                </ax:tbl>

            </ax:form>

            <div class="H10"></div> 

        </div>

        <ax:split-layout name="ax1" orientation="horizontal">

            <ax:split-panel width="*" style="">

                <!-- 목록 -->

                <div class="ax-button-group" data-fit-height-aside="grid-view-01">

                    <div class="left">

                        <h2>

                            <i class="cqc-list"></i>

                            <!--<ax:lang id="ax.admin.commoncode.title"/>-->

                             제품 가격 변경 내역

                        </h2>

                    </div>

                    <div class="right">

                        <button type="button" class="btn btn-default" data-grid-view-01-btn="add"><i class="cqc-circle-with-plus"></i> <ax:lang id="ax.admin.add"/></button>

                        <button type="button" class="btn btn-default" data-grid-view-01-btn="delete"><i class="cqc-circle-with-minus"></i> <ax:lang id="ax.admin.delete"/></button>

                    </div>

                </div>

                <div data-ax5grid="grid-view-01" data-fit-height-content="grid-view-01" style="height: 300px;"></div>

            </ax:split-panel>

        </ax:split-layout>

    </jsp:body>

</ax:layout>

- PrdtPriceHist.js 수정

var fnObj = {};

var ACTIONS = axboot.actionExtend(fnObj, {

    PAGE_SEARCH: function (caller, act, data) {

        axboot.ajax({

            type: "GET",

            url: ["prdtPriceHist"],

            data: caller.searchView.getData(),

            callback: function (res) {

                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: ["prdtPriceHist"],

            data: JSON.stringify(saveList),

            callback: function (res) {

                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);

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

            }

        });

    },

    ITEM_ADD: function (caller, act, data) {

        caller.gridView01.addRow();

    },

    ITEM_DEL: function (caller, act, data) {

        caller.gridView01.delRow("selected");

    }

});

//기존 제품정보 복사 시 이 부분을 초기 셋팅으로만 변경해준다.

fnObj.pageStart = function () {

    this.pageButtonView.initView();

    this.searchView.initView();

    this.gridView01.initView();

    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

 */

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

    initView: function () {

        var _this = this;

        this.target = axboot.gridBuilder({

            showRowSelector: true,

            frozenColumnIndex: 0,

            sortable: true,

            multipleSelect: true,

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

            columns: [
                {
                    key: "id",
                    label: "id",
                    display: false
                },
                {
                    key: "prdtCd",
                    label: "제품코드",
                    width: 100,
                    align: "center",
                    editor: "text"
                },

                //내부적으로 update 일자를 관리하고 있지만, 그냥 넣어봤음.

                {
                    key: "chDate",
                    label: "변경일시",
                    width: 150,
                    align: "right",
                    editor: "date"
                },
                {
                    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 = [];

        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
        }, "last");

    }

});

그 다음은 서버를 실행하여 프로그램 및 매뉴관리 화면에서 제품가격History를 추가해준다.

나머지 조회 및 Update(제품정보의 판매가격 수정시 호출)을 위한 JAVA소스 수정은 다음에 게시하고,

오늘은 여기까지만 하도록 하겠습니다. 

    

      

#제품가격 #멀티테이블 #Axboot

Read more

2025년  ERP/CRM/SCM 시스템 종류

2025년 ERP/CRM/SCM 시스템 종류

2025년 글로벌 ERP/CRM/SCM 시스템 순위: 회사, 커뮤니티, 기능 비교 분석 기업들은 효율적인 운영과 경쟁력 강화를 위해 ERP, CRM, SCM 시스템 도입을 적극 검토하고 있습니다. 본 글에서는 시장 점유율, 기능, 고객 만족도, 기술 발전을 고려하여 주요 시스템들의 순위와 특징을 정리했습니다. 아래 순위는 주관적 평가이며, 실제 도입 시 기업의 규모와

해외여행 준비 체크리스트

해외여행 준비 체크리스트

해외여행 준비 체크리스트: 완벽한 여행을 위한 필수 준비 가이드 꿈꿔왔던 해외여행, 설렘과 함께 걱정도 따라옵니다. 꼼꼼한 준비가 완벽한 여행의 시작입니다. 2025년 최신 정보를 바탕으로, 놓치기 쉬운 부분까지 포함한 상세 체크리스트와 함께 걱정 없이 여행을 즐겨보세요! 본 가이드는 항공권 예매부터 현지 적응까지, 단계별로 필요한 정보를 제공합니다. 1. 여행 계획 수립 및

ChatGPT 무료와 유료 차이 비교

ChatGPT 무료와 유료 차이 비교

ChatGPT 무료와 유료(Plus,Pro) 차이 비교 ChatGPT는 오픈AI가 개발한 강력한 대규모 언어 모델로, 다양한 작업에 활용 가능한 놀라운 도구입니다. 무료 버전과 유료 버전인 ChatGPT Plus는 여러 측면에서 차이가 있으며, 어떤 버전을 선택해야 할지는 사용 목적과 예산에 따라 달라집니다. 이 글에서는 ChatGPT 무료와 유료 버전의 차이점을 상세하게 비교 분석하여, 여러분의

손흥민의 축구 인생

손흥민의 축구 인생

손흥민, 축구 역사의 한 페이지: 시대별 주요 활약상 손흥민, 대한민국을 대표하는 축구 스타이자 프리미어 리그를 빛낸 월드클래스 선수. 그의 놀라운 여정을 시대별로 나누어 살펴봅니다. 1. 어린 시절과 유소년 시절 (1992-2008) 손흥민은 1992년 강원도 춘천에서 태어나 어린 시절부터 축구에 몰두했습니다. 아버지 손웅정의 지도 아래 체계적인 훈련을 받으며 뛰어난 기술과 슈팅 능력을

Image 3
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
Image 4
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.