shoppingmallv2 init...

This commit is contained in:
최준흠 2023-08-02 17:10:27 +09:00
parent ec51486a53
commit 072e584a82
12 changed files with 230 additions and 113 deletions

View File

@ -150,9 +150,12 @@ $routes->group('front', ['namespace' => 'App\Controllers\Front'], function ($rou
});
$routes->group('order', static function ($routes) {
$routes->get('', 'OrderController::index');
$routes->post('insert', 'OrderController::insert');
$routes->get('view/(:uuid)', 'OrderController::view/$1');
});;
$routes->group('cart', static function ($routes) {
$routes->post('addCart', 'CartController::addCart');
$routes->post('cancelCart', 'CartController::cancelCart');
});;
});
/*
* --------------------------------------------------------------------

View File

@ -125,16 +125,37 @@ $routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'au
});
});
$routes->group('front', ['namespace' => 'App\Controllers\Front'], function ($routes) {
$routes->group('user', ['namespace' => 'App\Controllers\Front', 'filter' => 'authFilter:master,director,cloudflare,manager,gold,silver,brone,vip,user'], static function ($routes) {
$routes->get('update', 'UserController::update_form');
$routes->post('update', 'UserController::update');
$routes->get('view', 'UserController::view');
});
$routes->group('board', static function ($routes) {
$routes->get('', 'BoardController::index');
$routes->get('excel', 'BoardController::excel/$1');
$routes->get('insert', 'BoardController::insert_form');
$routes->post('insert', 'BoardController::insert');
$routes->get('update/(:num)', 'BoardController::update_form/$1');
$routes->post('update/(:num)', 'BoardController::update/$1');
$routes->get('view/(:num)', 'BoardController::view/$1');
$routes->get('reply/(:num)', 'BoardController::reply_form/$1');
$routes->post('reply/(:num)', 'BoardController::reply/$1');
$routes->get('delete/(:num)', 'BoardController::delete/$1', ['filter' => 'authFilter:master']);
$routes->get('download/(:any)/(:num)', 'BoardController::download/$1/$2');
});
$routes->group('product', static function ($routes) {
$routes->get('', 'ProductController::index');
$routes->get('excel', 'ProductController::excel/$1');
$routes->get('view/(:uuid)', 'ProductController::view/$1');
});
$routes->group('order', ['filter' => 'authFilter:master,director,cloudflare,manager,gold,silver,brone,vip,user'], static function ($routes) {
$routes->group('order', static function ($routes) {
$routes->get('', 'OrderController::index');
$routes->post('insert', 'OrderController::insert');
$routes->get('view/(:uuid)', 'OrderController::view/$1');
});;
$routes->group('cart', static function ($routes) {
$routes->post('addCart', 'CartController::addCart');
$routes->post('cancelCart', 'CartController::cancelCart');
});;
});
/*
* --------------------------------------------------------------------

View File

@ -9,7 +9,6 @@ use Psr\Log\LoggerInterface;
class OrderController extends AdminController
{
private $_product_options = null;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->_model = new OrderModel($this->getFields());

View File

@ -2,13 +2,13 @@
namespace App\Controllers;
use App\Libraries\Adapter\Auth\Adapter;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use App\Libraries\Adapter\Auth\Adapter;
class AuthController extends Controller

View File

@ -0,0 +1,181 @@
<?php
namespace App\Controllers;
use App\Models\OrderModel;
use App\Models\ProductModel;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class CartController extends Controller
{
/**
* Instance of the main Request object.
*
* @var CLIRequest|IncomingRequest
*/
protected $request;
/**
* An array of helpers to be loaded automatically upon
* class instantiation. These helpers will be available
* to all other controllers that extend BaseController.
*
* @var array
*/
protected $helpers = ['Common'];
/**
* Be sure to declare properties for any property fetch you initialized.
* The creation of dynamic property is deprecated in PHP 8.2.
*/
// protected $session;
/**
* Constructor.
*/
private $_session = null;
private $_viewDatas = array();
private $_orderModel = null;
private $_productModel = null;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
$this->_session = \Config\Services::session();
$this->_viewDatas['title'] = '장바구니';
$this->_viewDatas['session'] = $this->_session;
}
private function getOrderModel()
{
return $this->_orderModel = $this->_orderModel ?: new OrderModel();
}
private function getProductModel()
{
return $this->_productModel = $this->_productModel ?: new ProductModel();
}
final public function init()
{
$this->_viewDatas['fields'] = ["product_uid", "quantity", "price", "status"];
$this->_viewDatas['fieldRules'] = $this->getOrderModel()->getFieldRules($this->_viewDatas['fields']);
return $this->_viewDatas;
}
//주문
protected function addCart_validate()
{
//fieldData Rule 검사
if (!$this->validate($this->_viewDatas['fieldRules'])) {
throw new \Exception("{$this->_viewDatas['title']}의 검증 오류발생\n" . implode("\n", $this->validator->getErrors()));
}
//fieldData 적용
$this->_viewDatas['fieldDatas'] = array();
foreach ($this->_viewDatas['fields'] as $field) {
$this->_viewDatas['fieldDatas'] = $this->request->getVar($field);
}
}
public function addCart()
{
$msg = "";
try {
$this->_viewDatas = $this->init(__FUNCTION__);
//Transaction 시작
$this->getOrderModel()->transStart();
//장바구니정보 검증
$this->addCart_validate();
//상품정보 가져오기
$product = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $this->_viewDatas['fieldDatas']['product_uid']]);
//재고수 비교
if ($product->getStock() < $this->_viewDatas['fieldDatas']['quantity']) {
throw new \Exception("구매수량이 너무 많습니다.\n구매수량:{$this->_viewDatas['fieldDatas']['quantity']}개, 남은 재고수량:{$product->getStock()}");
}
//구매 금액 비교
$price = ($product->getPrice() - $product->getSale()) * $this->_viewDatas['fieldDatas']['quantity'];
if ($price != $this->_viewDatas['fieldDatas']['price']) {
throw new \Exception("실 상품금액{$price} 와 구매금액{$this->_viewDatas['fieldDatas']['price']}이 서로 다릅니다.");
}
//상품명을 복사해서 구매한 상품명에 넣기
$this->_viewDatas['fieldDatas'][$this->getOrderModel()->getTitleField()] = $product->getTitle();
//주문추가
$entity = $this->getOrderModel()->addCart($this->_viewDatas['fieldDatas']);
//상품재고감소
$this->getProductModel()->addCart($product, $this->_viewDatas['fieldDatas']['quantity']);
//주문정보 세션에 넣기
$order_uids = $this->_session->get(SESSION_NAMES['CART']) ?: array();
$this->_session->set(SESSION_NAMES['CART'], [...$order_uids, $entity->getPrimaryKey()]);
//Transaction Commit
$this->getOrderModel()->transComplete();
$msg = sprintf(
"%s에서 %s %s개를 장바구니에 담았습니다.",
$this->_viewDatas['title'],
$entity->getTitle(),
$entity->getQuantity(),
);
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} catch (\Exception $e) {
//Transaction Rollback
$this->getOrderModel()->transRollback();
log_message("error", $e->getMessage());
$msg = sprintf(
"%s에서 다음 오류로 인해 장바구니에 담기를 실패하였습니다.\n%s",
$this->_viewDatas['title'],
$e->getMessage()
);
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} finally {
$this->_session->setFlashdata("return_message", $msg);
}
}
//주문취소
public function canelCart($uid)
{
$msg = "";
try {
//주문정보 가져오기
$entity = $this->getOrderModel()->getEntity([$this->getOrderModel()->getPrimaryKey() => $uid]);
//Transaction 시작
$this->getOrderModel()->transStart();
//주문취소
if (!$this->getOrderModel()->canelCart($entity)) {
log_message("error", __FUNCTION__ . "에서 호출:" . $this->getOrderModel()->getLastQuery());
log_message("error", implode("\n", $this->getOrderModel()->errors()));
throw new \Exception(__FUNCTION__ . " 오류 발생.\n" . var_export($this->getOrderModel()->errors(), true));
}
//상품정보 가져오기
$product = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $this->_viewDatas['fieldDatas']['product_uid']]);
//상품반환
$this->getProductModel()->canelCart($product, $entity->getQuantity());
//주문정보 세션에서 빼기
$order_uids = $this->_session->get(SESSION_NAMES['CART']) ?: array();
$temps = array();
foreach ($order_uids as $order_uid) {
if ($order_uid != $entity->uid) {
array_push($temps, $order_uid);
}
}
$this->_session->set(SESSION_NAMES['CART'], $temps);
//Transaction Commit
$this->getOrderModel()->transComplete();
$msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()} {$entity->quantity}개의 주문을 취소하였습니다.";
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} catch (\Exception $e) {
//Transaction Rollback
$this->getOrderModel()->transRollback();
$msg = sprintf(
"%s에서 다음 오류로 인해 주문취소를 실패하였습니다.\n%s",
$this->_viewDatas['title'],
$e->getMessage()
);
log_message("error", $e->getMessage());
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} finally {
$this->_session->setFlashdata("return_message", $msg);
}
}
}

View File

@ -2,16 +2,13 @@
namespace App\Controllers\Front;
use App\Entities\OrderEntity;
use App\Models\OrderModel;
use App\Models\ProductModel;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class OrderController extends FrontController
{
private $_productModel = null;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->_model = new OrderModel($this->getFields());
@ -44,92 +41,6 @@ class OrderController extends FrontController
return ["status"];
}
//Insert관련 (주문)
//세션에 장바구니에 담긴 Order UID를 추가해준다.
private function setCart(OrderEntity $entity)
{
$order_uids = $this->_session->get(SESSION_NAMES['CART']) ?: array();
$this->_session->set(SESSION_NAMES['CART'], [...$order_uids, $entity->getPrimaryKey()]);
}
protected function insert_process()
{
$this->_productModel = $this->_productModel ?: new ProductModel();
//상품정보 가져오기
$product = $this->_productModel->getEntity([$this->_model->getPrimaryKey() => $this->_viewDatas['fieldDatas']['product_uid']]);
//구매 금액 비교
$price = ($product->getPrice() - $product->getSale()) * $this->_viewDatas['fieldDatas']['quantity'];
if ($price != $this->_viewDatas['fieldDatas']['price']) {
throw new \Exception("실 상품금액{$price} 와 구매금액{$this->_viewDatas['fieldDatas']['price']}이 서로 다릅니다.");
}
//상품재고 줄이기,Order(장바구니)에넣기,Order(장바구니)번호 세션넣기
$this->_productModel->decreaseStock($product, $this->_viewDatas['fieldDatas']['quantity']);
//상품명을 복사해서 구매한 상품명에 넣기
$this->_viewDatas['fieldDatas'][$this->_model->getTitleField()] = $product->getTitle();
//장바구니에 넣기
$entity = parent::insert_process();
//장바구니 세션정의
$this->setCart($entity);
return $entity;
}
public function insert()
{
$msg = "";
try {
$this->_viewDatas = $this->init(__FUNCTION__);
//Transaction 시작
$this->_model->transStart();
$this->insert_validate();
$this->insert_process();
//Transaction Commit
$this->_model->transComplete();
$msg = sprintf(
"%s에서 해당 상품 %s개를 장바구니에 담았습니다.",
$this->_viewDatas['title'],
$this->_viewDatas['fieldDatas']['quantity']
);
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} catch (\Exception $e) {
//Transaction Rollback
$this->_model->transRollback();
log_message("error", $e->getMessage());
$msg = sprintf(
"%s에서 다음 오류로 인해 장바구니에 담기를 실패하였습니다.\n%s",
$this->_viewDatas['title'],
$e->getMessage()
);
return redirect()->back()->withInput();
} finally {
$this->_session->setFlashdata("return_message", $msg);
}
}
//Delete 관련 (주문취소)
protected function delete_process($entity)
{
if (!$this->_model->delete($entity->getPrimaryKey())) {
log_message("error", __FUNCTION__ . "에서 호출:" . $this->_model->getLastQuery());
log_message("error", implode("\n", $this->_model->errors()));
throw new \Exception(__FUNCTION__ . " 오류 발생.\n" . var_export($this->_model->errors(), true));
}
return $entity;
}
public function delete($uid)
{
$msg = "";
try {
$entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->delete_process($entity);
$msg = "{$this->_viewDatas['title']}에서 해당 상품 {$entity->quantity}개를 완료하였습니다.";
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} catch (\Exception $e) {
$msg = "{$this->_viewDatas['title']}에서 " . __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage();
log_message("error", $e->getMessage());
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} finally {
$this->_session->setFlashdata("return_message", $msg);
}
}
//Index관련
protected function index_setCondition()
{

View File

@ -164,15 +164,6 @@ abstract class BaseModel extends Model
);
}
//View관련 (게시판등의 조회수 증가함수)
final public function increaseViewCount($uid, string $field = "view_cnt", int $cnt = 1)
{
//escape -> false옵션 반드시 있어야함
$this->set($field, "{$field}+{$cnt}", false);
$this->where($this->primaryKey, $uid);
$this->update();
}
//create , modify 직전 작업용 작업
protected function changeFormData(string $action, string $field, array $formDatas, $entity)
{

View File

@ -64,10 +64,9 @@ class OrderModel extends BaseModel
{
return $this->where($conditions)->first() ?: throw new \Exception("해당 데이터가 없습니다.\n" . var_export($conditions, true));
}
//장바구니에 넣기
public function create(array $formDatas): OrderEntity
{
return $this->create_process(new OrderEntity(), $formDatas);
return $this->create_process(new OrderEntity(), $formDatas);
}
public function modify(OrderEntity $entity, array $formDatas): OrderEntity
{
@ -79,4 +78,15 @@ class OrderModel extends BaseModel
parent::setIndexWordFilter($word);
$this->orLike($this->getTitleField(), $word, "both");
}
//장바구니에 넣기
public function addCart(array $formDatas): OrderEntity
{
return $this->create_process(new OrderEntity(), $formDatas);
}
//장바구니에 빼기
public function canelCart(OrderEntity $entity)
{
return $this->delete(new $entity->getPrimaryKey());
}
}

View File

@ -97,17 +97,18 @@ class ProductModel extends BaseModel
$this->orLike("content", $word, "both"); //befor , after , both
}
//Ecommerce Action
//장바구니에 넣기
final public function decreaseStock(ProductEntity $entity, int $quantity): ProductEntity
final public function addCart(ProductEntity $entity, int $quantity): ProductEntity
{
if ($entity->getStock() < $quantity) {
throw new \Exception("구매수량이 너무 많습니다.\n구매수량:{$quantity}개, 남은 재고수량:{$entity->getStock()}");
}
if ($entity->getStock() == $quantity) {
$entity->status = "outofstock";
}
$entity->stock -= $quantity;
return $this->save_process($entity);
}
//장바구니에 빼기
public function canelCart(ProductEntity $entity)
{
return $this->delete(new $entity->getPrimaryKey());
}
}

View File

@ -26,7 +26,7 @@
<?php endforeach; ?>
<td>
<?php if ($entity->getStatus() == DEFAULTS['STATUS']) : ?>
<?= anchor(current_url() . '/delete/' . $entity->getPrimaryKey(), ICONS['DELETE'], ["class" => "btn btn-sm btn-danger btn-circle", "target" => "_self"]) ?>
<?= anchor('/front/cart/cancelCart/' . $entity->getPrimaryKey(), ICONS['DELETE'], ["class" => "btn btn-sm btn-danger btn-circle", "target" => "_self"]) ?>
<?php endif; ?>
</td>
</tr>

View File

@ -1,4 +1,4 @@
<?= form_open("front/order/insert", ['method' => 'post']) ?>
<?= form_open("front/cart/addCart", ['method' => 'post']) ?>
<?= form_hidden("product_uid", $entity->getPrimaryKey()) ?>
<input type="hidden" id="price" name="price" value="<?= ($entity->getPrice() - $entity->getSale()) * 1 ?>">
<?php

View File

@ -14,7 +14,7 @@
</table>
<div style="text-align:center">
<?php if ($entity->getStatus() == DEFAULTS['STATUS']) : ?>
<?= $this->include('front/product/orderform'); ?>
<?= $this->include('front/product/addCart'); ?>
<?php else : ?>
이제품은 현재[<?= lang('Product.STATUS.' . $entity->getStatus()) ?>]입니다.
<?php endif ?>