게시판의 사용과 커스터마이징

게시판의 종류와 사용방법

게시판의 종류

1. 표준 게시판

게시판 관리

- 게시판 구분(공지/소개/문의)

image.png

모든 게시판에 대한 정보를 불러옵니다.

구분코드, PostCode, 상태, 종류설명, 카테고리 등이 포함되어 있습니다.

모든 게시판들은 psot_type_id를 통해 구분됩니다.

- 공지형 게시판

image.png

공지형 게시판의 자식 메뉴들이 노출됩니다.

각 메뉴에서는 해당되는 게시글들을 수정 /삭제 /복사 등 게시글 관리가 가능합니다.

공지형 게시판의 para_name은 다음과 같습니다.

분류 para_name(조회) para_name(등록)
공지사항 notice-input notice
이벤트 event-input event
배너/팝업
banner-input
banner
자주묻는 질문(FAQ) faq-input faq
이용약관 policy-input policy
개인정보 보호정책 privacy-input privacy
전자금육 이용약관 e-finance-input e-finance
교환환불 정책 refund-input refund
- 소개형 게시판

image.png

소개형 게시판의 자식 메뉴들이 노출됩니다.

기능적인 부분은 위와 같습니다.

분류 para_name (조회) para_name (등록)
회사소개 intro-input intro
제품소개 production-input production
특허/인증서
certificatate-input
certificatate
포트폴리오 portfolio-input portfolio
뉴스 news-input news


- 문의형 게시판

image.png

para_name

분류 para_name (조회) para_name (등록)
상품문의
item-inquiry-input
item-inquiry
상담 신청
contactus-input
contactus
1대1 문의
1to1-input
1to1
공개 질문
standard-input
standard

각 페이지에서 등록된 게시판들이 pro 페이지의 게시글로 노출됩니다.

게시판을 Pro Page에 적용하는 방법

1대1문의 (문의형 게시판)을 pro page에 적용하기

[문의형 게시판 - 1대1 문의 적용하기 예제]

1. Controller 구성

pro 테마에 Controller를 구성합니다. dabory/themes/pro/app/Http/Controller/etc 디렉토리에 OneToOneController.php를 생성하고 메서드를 작성합니다.

- 외부 API 호출 설정

백엔드 API를 호출하고 결과를 처리하기 위해 App\Services\CallApiService를 사용합니다.

class OneToOneController extends Controller
{
    private $callApiService;


    public function __construct(CallApiService $callApiService)
    {
        $this->callApiService = $callApiService;
    }


    public function list()
    {
        $limit = (int)request('limit', 12);
        $page = (int)request('page', 1);

        $oneToOnePage = $this->callApiService->callApi([
            'url' => 'list-type1-page',    // api에 요청할 url 주소
            'data' => [                    // list-type1-page로 요청할 data
                'QueryVars' => [           // api 서버에서 Query를 식별할 수 있도록 구성한 요소들
                    'QueryName' => 'pro:my-page/post-list',   // pro/.../my-page/post-list/ 디렉토리 안의 쿼리 파일을 찾는다.
                    'SimpleFilter' => "post_code='1to1'",     // where 절에 추가
                    'SubSimpleFilter' => "image_type = 'thumb'", 
                    'IsntPagination' => false     // pagination 여부
                ],
                'ListType1Vars' => [
                    'OrderBy' => request('sort', 'mx.created_on desc')
                ],
                'PageVars' => [
                    'Limit' => $limit,
                    'Offset' => ($page - 1) * $limit
                ]
            ]
        ]);


    //    dump($oneToOnePage);


        $oneToOnePage['Page'] = new LengthAwarePaginator($oneToOnePage['Page'], $oneToOnePage['PageVars']['QueryCnt'],
            $limit, $page, ['path' => request()->url()]);
        // dump($oneToOnePage);
        return view('views.etc.1to1-list', compact('oneToOnePage'));
    }


    public function store()
    {
        $validator = Validator::make(request()->all(), [
            'post_title' => 'required',
            'post_contents' => 'required',
            'pc1' => 'required',
            'pc2' => 'required|email'
        ]);


        if ($validator->fails()) {
            notify()->error(_e('Action failed'), 'Error', 'bottomRight');
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }


        $response =  $this->callApiService->callApi([
            'url' => 'post-act',
            'data' => [
                'Page' => [
                    [
                        'Id' => 0,
                        'PostTitle' => request('post_title'),
                        'PostContents' => request('post_contents'),
                        'PostTypeId' => 6,
                        'Pc1' => request('pc1'),
                        'Pc2' => request('pc2'),
                        'Status' => '2',
                        'MemberId' => session('member')['MemberId'],
                    ]
                ]
            ],
        ]);


        if ($this->callApiService->verifyApiError($response)) {
            notify()->error($response['body'], 'Error', 'bottomRight');
            return redirect()->back();
        }


//        notify()->success(_e('Action completed'), 'Success', 'bottomRight');
        return redirect()->route('1to1.list');
    }


    public function show($id)
    {
        $listType1Book = $this->callApiService->callApi([
            'url' => 'list-type1-book',
            'data' => [
                'Book' => [
                    [
                        'QueryVars' => [
                            'QueryName' => 'pro:my-page/post-details',
                            'SimpleFilter' => "post_code='1to1' and mx.id = $id",
                            'IsntPagination' => true,
                        ],
                        'PageVars' => [
                            'Limit' => 1
                        ]
                    ],
                    [
                        'QueryVars' => [
                            'QueryName' => 'pro:my-page/post-details-prenext',
                            'SimpleFilter' => "mx.id = (select max(id) from pro_post where id < ${id} and post_type_id = 6)",
                            'SubSimpleFilter' => "",
                            'IsntPagination' => true,
                        ],
                        'PageVars' => [
                            'Limit' => 1
                        ]
                    ],
                    [
                        'QueryVars' => [
                            'QueryName' => 'pro:my-page/post-details-prenext',
                            'SimpleFilter' => "mx.id = (select min(id) from pro_post where id > ${id} and post_type_id = 6)",
                            'SubSimpleFilter' => "",
                            'IsntPagination' => true,
                        ],
                        'PageVars' => [
                            'Limit' => 1
                        ]
                    ],
                ]
            ]
        ]);


    //    dd($listType1Book);
        if ($this->callApiService->verifyApiError($listType1Book)) {
            notify()->error($listType1Book['body'], 'Error', 'bottomRight');
            return redirect()->back();
        }


//        dump($listType1Book);
        return view('views.etc.1to1-details', compact('listType1Book'));
    }
}
1대1문의 구현을 위한 Controller 예시

이 구성으로 list-type1-page URL로 data가 요청되면, api 서버는 weberp-queries에서 해당 URL의 QueryVars에 작성해준 조건에 해당하는 SQL 파일을 찾고, 데이터로 쿼리 조건절을 구성하여 호출하고 반환합니다.

응답 처리 및 View 반환

API로부터 응답을 받아 변수에 담고, View 페이지에서 필요한 데이터를 가공하거나 변환하여 반환합니다. View 페이지에서는 반환받은 배열 데이터를 통해 페이지 작업을 수행할 수 있습니다.

TEST

Controller와 view 페이지 작업이 완료되었다면 erp/pro 각각의 페이지에서 테스트를 진행합니다.

예제에서 진행했던 1대1문의 게시판을 확인해보겠습니다. 

pro 페이지에 만들어준 문의하기 게시판에서 문의글을 작성한 뒤

image.png

erp 페이지로 이동하여 1대1문의 게시판을 확인합니다.

image.png

위와같이 문의내용이 잘 들어왔습니다.

참고사항

erp에 게시판 설치하기

erp 게시판 커스터마이징

문의형 게시판 커스터마이징하기

공지형 게시판 커스터마이징하기

소개형 게시판 커스터마이징하기

게시판 커스터마이징 방법

image.png

게시판을 커스터마징 하기 위해서는 

erp 게시판 구분 메뉴에서 게시판 구분 등록을 통해 새로운 커스터마징 게시판을 등록해야합니다.

image.png

게시판 구분 등록 예시

image.png

게시판이 생성된 것을 확인합니다.

image.png

생성해준 게시판을 사용자 메뉴에 따로 만들어주기 위해서 

메뉴 확장과 API 관리 - 사용자 메뉴로 이동합니다.

image.png

추가 버튼을 눌러 사용자 메뉴를 추가해줍니다.

image.png

전체 캐시삭제를 해줘야 사용자 메뉴에 반영이 됩니다.

image.png

새로운 사용자 메뉴가 추가됐습니다.

이제 상담내역 게시판의 crud를 구현해주기 위해서 

erp의 파라메터를 만들어줍니다. 파라메터는 사용자 메뉴를 추가할때 입력했던 위치에 만들어줘야 합니다.

해당 위치로 이동하여 디렉토리를 생성하고 contatctus-custom-input.json 이라는 파라메터 파일을 생성해줍니다.

내용은 아래와 같습니다.

{
    "//list-type-1": "simple and plain list by query of table join",


    "General": {
        "Title": "상담내역 관리",
        "PageApi": "list-type1-page",
        "ActApi": "post-act"
    },


    "QueryVars": {
        "QueryName": "kbgolf::post/contactus-custom-input",
        "FilterName": "",
        "FilterValue": "",
        "FilterDate": "mx.official_date",
        "SimpleFilter": "pt.post_code = 'contactus-custom'"
    },


    "HeadSelectOptions": [
        {
            "Value": "xls-report",
            "Caption": "(기존)엑셀 다운로드"
        },
        {
            "Value": "custom-xls-report",
            "Caption": "엑셀 다운로드",
            "Component": "dummy",
            "Parameter": "/list/list-type1/download/contactus-custom",
            "ThemeDir": "/kbgolf/erp"
        },
        {
            "Value": "new",
            "Caption": "상담신청 등록"
        },
        {
            "Value": "multi-delete",
            "Caption": "상담신청 일괄 삭제"
        }
    ],


    "//FormVars": "FormVars[0]-caption, FormVars[1]-searchPopup",
    "FormVars": [
        {
            "ListButton": "조회",
            "DateRange": "",
            "DateNavi": "이전 | (오늘지정) | 이후",
            "Date": "자료 등록일",
            "From": "부터",
            "To": "까지",
            "FirstRange": "",
            "SecondRange": "",
            "ThirdRange": "",
            "FourthRange": "",
            "AddTotalLine": "",
            "SelectPopup": "팝업 선택(라디오 버튼)",
            "MultiPopup": "",
            "ChartPopup": "",
            "DownloadList": "",
            "ShowOnlyClosed": "",
            "Balance": "",
            "OrderBy": "표시 순서",
            "FilterOption": "검색 조건",
            "SimpleOption": "상태별 검색"
        }
    ],


    "FilterSelectOptions": [
        {
            "Value": "",
            "Caption": "=검색 조건="
        },
        {
            "Value": "mx.pc1",
            "Caption": "신청자"
        },
        {
            "Value": "mx.pc5",
            "Caption": "회원권명"
        },
        {
            "Value": "mx.pc3",
            "Caption": "거래 구분"
        },
        {
            "Value": "mx.pc4",
            "Caption": "회원권 구분"
        }
    ],


    "SimpleSelectOptions": [
        {
            "Value": "",
            "Caption": "전체"
        },
        {
            "Value": "mx.pc7='상담접수'",
            "Caption": "상담접수"
        },
        {
            "Value": "mx.pc7='상담완료'",
            "Caption": "상담완료"
        }
    ],
    "//ListType1RangeVars": "[0]-filter, [1]-component, [2]-parameter",
    "ListType1RangeVars": [
        {
            "FirstRange": "",
            "SecondRange": "",
            "ThirdRange": "",
            "FourthRange": ""
        },
        {
            "FirstRange": "",
            "SecondRange": "",
            "ThirdRange": "",
            "FourthRange": ""
        },
        {
            "FirstRange": "",
            "SecondRange": "",
            "ThirdRange": "",
            "FourthRange": ""
        }
    ],


    "DateNaviOptions": [
        {
            "Value": "day",
            "Caption": "일"
        },
        {
            "Value": "week",
            "Caption": "주"
        },
        {
            "Value": "month",
            "Caption": "월"
        },
        {
            "Value": "quarterly",
            "Caption": "분기"
        },
        {
            "Value": "semiannual",
            "Caption": "반기"
        },
        {
            "Value": "year",
            "Caption": "년"
        },
        {
            "Value": "all",
            "Caption": "전체"
        }
    ],


    "SelectPopupOptions": [
        {
            "Caption": "상담신청 관리",
            "Component": "kbgolf::popup.popup-form1.form-a.post.contactus-custom-form",
            "Parameter": "kbgolf::/popup/popup-form1/form-a/post/contactus-custom"
        }
    ],


    "// OrderByOptions": "OrderBy Options//첫번째 Value가 Default",
    "OrderByOptions": [
        {
            "Value": "mx.created_on desc",
            "Caption": "문의일자 역순"
        },
        {
            "Value": "mx.created_on asc",
            "Caption": "문의일자 순서"
        }
    ],


    "//BalanceOptions": "Show OnlyBalaceRemained or All",
    "BalanceOptions": [
        {
            "Value": "",
            "Caption": "전체 보기"
        },
        {
            "Value": "c10 > 0",
            "Caption": "잔량있는 것만"
        }
    ],


    "DisplayVars": {
        "IsListFirst": true,
        "IsExcelColumn": true,
        "IsSelectPopupHidden": true,
        "IsC1Popup": "1",
        "InitLines": 10,
        "HeadHeight": "140",
        "BodyHeight": "570"
    },


    "ThumbContainerVars": {
        "ListWidth": 60,
        "ListHeight": 50
    },


    "// ListVars": "ListVars[0]-caption, ListVars[1]-size(px), ListVars[2]-align->right(number) left(left)",
    "ListVars": [
        {
            "$Radio": "$Radio",
            "$Check": "$Check",
            "No": "번호",
            "C1": "신청자",
            "C2": "연락처",
            "C3": "거래구분",
            "C4": "회원권 구분",
            "C5": "회원권명",
            "C6": "희망가격",
            "C7": "요청사항",
            "C8": "상태"
        },
        {
            "$Radio": "2",
            "$Check": "2",
            "No": "2",
            "C1": "5",
            "C2": "4",
            "C3": "4",
            "C4": "5",
            "C5": "5",
            "C6": "5",
            "C7": "7",
            "C8": "4"
        },
        {
            "$Radio": "center",
            "$Check": "center",
            "No": "center",
            "C1": "center",
            "C2": "center",
            "C3": "center",
            "C4": "center",
            "C5": "center",
            "C6": "center",
            "C7": "center",
            "C8": "center"
        }
    ]
}


이제 pro 페이지와 연동하여 상담내역을 관리할 수 있는 게시판이 구성됐습니다.
pro 페이지 적용은 아래 링크를 통해 체크할 수 있습니다.
참고사항

pro 페이지 적용방법