shoppingmallv2 init...

This commit is contained in:
최준흠 2023-08-01 15:16:22 +09:00
parent 6b41a6c3d9
commit e219d26731
20 changed files with 129 additions and 82 deletions

View File

@ -122,7 +122,7 @@ $routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'au
});
$routes->group('order', static function ($routes) {
$routes->get('', 'OrderController::index');
$routes->post('insert/(:uuid)', 'OrderController::insert/$1');
$routes->post('insert', 'OrderController::insert');
$routes->get('view/(:uuid)', 'OrderController::view/$1');
$routes->post('batchjob', 'OrderController::batchjob`');
$routes->get('delete/(:uuid)', 'OrderController::delete/$1', ['filter' => 'authFilter:master']);

View File

@ -2,22 +2,56 @@
namespace App\Controllers\Admin;
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 AdminController
{
private $_cart_name = "order_uids";
private $_cart_delimeter = "||";
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->_model = new OrderModel();
parent::initController($request, $response, $logger);
$this->_viewPath .= strtolower($this->_model->getClassName());
helper("cookie");
}
//쿠키에 장바구니에 담긴 Order UID를 추가해준다.
private function setOrderCookie(OrderEntity $entity)
{
$order_uids = array();
if (has_cookie($this->_cart_name)) {
$order_uids = explode($this->_cart_delimeter, get_cookie($this->_cart_name));
}
delete_cookie($this->_cart_name);
//24시간 저장
set_cookie([
'name' => $this->_cart_name,
'value' => implode($this->_cart_delimeter, [...$order_uids, $entity->getPrimaryKey()]),
'expire' => '36400',
]);
}
//장바구니에 담기
protected function insert_process()
{
//fieldData Rule 검사및 fieldData 적용
parent::insert_process();
//상품재고 줄이기
$productModel = new ProductModel();
$product = $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']}이 서로 다릅니다.");
}
$productModel->decreaseStock($product, $this->_viewDatas['fieldDatas']['quantity']);
}
public function insert()
{
$msg = "";
@ -25,11 +59,12 @@ class OrderController extends AdminController
$this->_viewDatas['fields'] = $this->_model->getFields(__FUNCTION__);
$this->_viewDatas['fieldRules'] = $this->_model->getFieldRules($this->_viewDatas['fields'], __FUNCTION__);
//Transaction 시작
$this->_model->transStart();
$this->insert_process();
$this->_model->addCart($this->_viewDatas['fieldDatas']);
$this->_model->transStart();
$entity = $this->_model->create($this->_viewDatas['fieldDatas']);
$this->setOrderCookie($entity);
//Transaction Commit
$this->_model->transCommit();
$this->_model->transComplete();
$msg = sprintf(
"%s에서 해당 상품 %s개를 장바구니에 담았습니다.",
$this->_viewDatas['title'],
@ -40,7 +75,6 @@ class OrderController extends AdminController
//Transaction Rollback
$this->_model->transRollback();
log_message("error", $e->getMessage());
log_message("error", var_export($this->_viewDatas['fieldDatas'], true));
$msg = sprintf(
"%s에서 다음 오류로 인해 장바구니에 담기를 실패하였습니다.\n%s",
$this->_viewDatas['title'],

View File

@ -12,9 +12,8 @@ class AuthController extends BaseController
private $_adapters = array();
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->_backend = service('user');
parent::initController($request, $response, $logger);
$this->_viewPath .= strtolower($this->_backend->getClassName());
$this->_viewPath .= 'auth';
$this->initAdapters();
}
@ -36,13 +35,14 @@ class AuthController extends BaseController
public function login()
{
$viewDatas = array();
foreach ($this->_adapters as $key => $adapter) {
$this->_viewDatas['login_buttons'][$key] = $adapter->getAuthButton();
$viewDatas['login_buttons'][$key] = $adapter->getAuthButton();
}
$this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []];
$viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []];
helper(['form']);
$this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return view('auth/login', $this->_viewDatas);
return view('auth/login', $viewDatas);
}
public function signup(string $site)

View File

@ -161,7 +161,7 @@ abstract class BaseController extends Controller
try {
$this->_viewDatas = $this->init(__FUNCTION__);
$this->insert_process();
$entity = $this->_model->insert($this->_viewDatas['fieldDatas']);
$entity = $this->_model->create($this->_viewDatas['fieldDatas']);
$msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}" . __FUNCTION__ . " 완료하였습니다.";
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} catch (\Exception $e) {
@ -181,7 +181,7 @@ abstract class BaseController extends Controller
$this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []];
helper(['form']);
$this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
$this->_viewDatas['entity'] = $this->_model->getEntity($uid);
$this->_viewDatas['entity'] = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
return view($this->_viewPath . '/update', $this->_viewDatas);
} catch (\Exception $e) {
log_message("error", $e->getMessage());
@ -209,9 +209,9 @@ abstract class BaseController extends Controller
$msg = "";
try {
$this->_viewDatas = $this->init(__FUNCTION__);
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity($uid);
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->update_process();
$entity = $this->_model->update($entity, $this->_viewDatas['fieldDatas']);
$entity = $this->_model->modify($entity, $this->_viewDatas['fieldDatas']);
$msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}" . __FUNCTION__ . " 완료하였습니다.";
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} catch (\Exception $e) {
@ -231,7 +231,7 @@ abstract class BaseController extends Controller
$this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []];
helper(['form']);
$this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
$entity = $this->_model->getEntity($uid);
$entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$titleField = $this->_model->getTitleField();
$entity->$titleField = "RE: " . $entity->$titleField;
$contentField = $this->_model->getContentField();
@ -252,7 +252,7 @@ abstract class BaseController extends Controller
$msg = "";
try {
$this->_viewDatas = $this->init(__FUNCTION__);
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity($uid);
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->reply_process();
$entity = $this->_model->reply($entity, $this->_viewDatas['fieldDatas']);
$msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}" . __FUNCTION__ . " 완료하였습니다.";
@ -276,9 +276,9 @@ abstract class BaseController extends Controller
$msg = "";
try {
$this->_viewDatas = $this->init(__FUNCTION__, [$field]);
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity($uid);
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->toggle_process();
$entity = $this->_model->update($entity, $this->_viewDatas['fieldDatas']);
$entity = $this->_model->modify($entity, $this->_viewDatas['fieldDatas']);
$msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}" . __FUNCTION__ . " 완료하였습니다.";
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} catch (\Exception $e) {
@ -318,9 +318,9 @@ abstract class BaseController extends Controller
$this->_model->transStart();
foreach ($uids as $uid) {
try {
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity($uid);
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->batchjob_process();
array_push($entitys, $this->_model->update($entity, $this->_viewDatas['fieldDatas']));
array_push($entitys, $this->_model->modify($entity, $this->_viewDatas['fieldDatas']));
array_push($batchjobs, "{$cnt}. {$uid}->{$entity->getTitle()}는 완료.");
} catch (\Exception $e) {
array_push($batchjobs, "{$cnt}. {$uid}는 실패.");
@ -328,7 +328,7 @@ abstract class BaseController extends Controller
$cnt++;
}
//Transaction Commit
$this->_model->transCommit();
$this->_model->transComplete();
$msg = sprintf(
"%s에서 총:%s개의 %s 완료하였습니다.",
$this->_viewDatas['title'],
@ -359,7 +359,7 @@ abstract class BaseController extends Controller
{
$msg = "";
try {
$entity = $this->_model->delete($this->_model->getEntity($uid));
$entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
if (!$this->_model->delete($entity->getPrimaryKey())) {
log_message("error", __FUNCTION__ . "에서 호출:" . $this->_model->getLastQuery());
log_message("error", implode("\n", $this->_model->errors()));
@ -387,8 +387,7 @@ abstract class BaseController extends Controller
$this->_viewDatas = $this->init(__FUNCTION__);
helper(['form']);
$this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []];
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity($uid);
$this->_viewDatas['entity'] = $this->_model->view($entity);
$entity = $this->_viewDatas['entity'] = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return view($this->_viewPath . '/view', $this->_viewDatas);
} catch (\Exception $e) {
@ -525,7 +524,7 @@ abstract class BaseController extends Controller
final public function download(string $field, $uid)
{
try {
$entity = $this->_model->getEntity($uid);
$entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
if (!$entity->$field) {
throw new \Exception("첨부파일이 확인되지 않습니다.");
}

View File

@ -45,7 +45,6 @@ DROP TABLE IF EXISTS shoppingmall.tw_order;
CREATE TABLE shoppingmall.tw_order (
uid varchar(36) NOT NULL,
product_uid varchar(36) NULL COMMENT '상품 정보',
sess_id varchar(50) NOT NULL COMMENT '세션 정보',
user_uid varchar(36) NULL COMMENT '사용자 정보',
quantity varchar(255) NOT NULL COMMENT '수량',
price int(10) UNSIGNED NOT NULL COMMENT '구매가',
@ -56,7 +55,7 @@ CREATE TABLE shoppingmall.tw_order (
PRIMARY KEY (uid),
CONSTRAINT FOREIGN KEY (product_uid) REFERENCES tw_product (uid),
CONSTRAINT FOREIGN KEY (user_uid) REFERENCES tw_user (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT ='Cart 정보';
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT ='Order 정보';
DROP TABLE IF EXISTS shoppingmall.tw_order_history;

View File

@ -7,6 +7,6 @@ use CodeIgniter\Entity\Entity;
abstract class BaseEntity extends Entity
{
abstract public function getPrimaryKey();
abstract public function getTitle();
abstract public function getStatus();
abstract public function getTitle(): string;
abstract public function getStatus(): string;
}

View File

@ -13,11 +13,11 @@ class BoardConfigEntity extends BaseEntity
{
return $this->attributes['uid'];
}
public function getTitle()
public function getTitle(): string
{
return $this->attributes['name'];
}
public function getStatus()
public function getStatus(): string
{
return $this->attributes['status'];
}

View File

@ -13,11 +13,11 @@ class BoardEntity extends BaseHierarchyEntity
{
return $this->attributes['uid'];
}
public function getTitle()
public function getTitle(): string
{
return $this->attributes['title'];
}
public function getStatus()
public function getStatus(): string
{
return $this->attributes['status'];
}

View File

@ -13,11 +13,11 @@ class CategoryEntity extends BaseHierarchyEntity
{
return $this->attributes['uid'];
}
public function getTitle()
public function getTitle(): string
{
return $this->attributes['name'];
}
public function getStatus()
public function getStatus(): string
{
return $this->attributes['status'];
}

View File

@ -14,11 +14,11 @@ class OrderEntity extends BaseEntity
{
return $this->attributes['uid'];
}
final public function getTitle()
final public function getTitle(): string
{
return $this->attributes['product_uid'];
}
final public function getStatus()
final public function getStatus(): string
{
return $this->attributes['status'];
}

View File

@ -13,11 +13,11 @@ class ProductEntity extends BaseEntity
{
return $this->attributes['uid'];
}
public function getTitle()
public function getTitle(): string
{
return $this->attributes['name'];
}
public function getStatus()
public function getStatus(): string
{
return $this->attributes['status'];
}

View File

@ -13,11 +13,11 @@ class UserEntity extends BaseEntity
{
return $this->attributes['uid'];
}
public function getTitle()
public function getTitle(): string
{
return $this->attributes['name'];
}
public function getStatus()
public function getStatus(): string
{
return $this->attributes['status'];
}

View File

@ -13,11 +13,11 @@ class UserSNSEntity extends BaseEntity
{
return $this->attributes['uid'];
}
public function getTitle()
public function getTitle(): string
{
return $this->attributes['name'];
}
public function getStatus()
public function getStatus(): string
{
return $this->attributes['status'];
}

View File

@ -63,12 +63,12 @@ abstract class BaseModel extends Model
return $this->primaryKey;
}
abstract public function getTitleField(): string;
abstract public function getEntity($uid): BaseEntity;
abstract public function getEntity($conditions): BaseEntity;
abstract public function getFieldFilters(): array;
abstract public function getFields(string $action): array;
final public function getEntitys($conditions = false): array
final public function getEntitys(array $conditions = array()): array
{
return $conditions ? $this->where($conditions)->findAll() : $this->findAll();
return $this->where($conditions)->findAll();
}
protected function getFieldRule(string $field, array $rules, string $action = ""): array
{
@ -119,9 +119,9 @@ abstract class BaseModel extends Model
}
//Field별 Form Option용
public function getFormOptions($conditions, $options = array()): array
public function getFormOptions(array $conditions = array(), $options = array()): array
{
foreach ($this->getEntitys(['status' => 'use']) as $entity) {
foreach ($this->getEntitys($conditions) as $entity) {
$options[$entity->getPrimaryKey()] = $entity->getTitle();
}
return $options;
@ -175,9 +175,9 @@ abstract class BaseModel extends Model
final public function increaseViewCount($uid, string $field = "view_cnt", int $cnt = 1)
{
//escape -> false옵션 반드시 있어야함
$this->builder()->set($field, "{$field}+{$cnt}", false);
$this->builder()->where($this->primaryKey, $uid);
$this->builder()->update();
$this->set($field, "{$field}+{$cnt}", false);
$this->where($this->primaryKey, $uid);
$this->update();
}
//create , modify 직전 작업용 작업

View File

@ -76,7 +76,7 @@ class BoardModel extends BaseHierarchyModel
case 'board_config_uid':
if (is_null($this->_boardconfig_options)) {
$boardConfigModel = new BoardConfigModel();
$this->_boardconfig_options = $boardConfigModel->getFormOptions(['status' => 'use']);
$this->_boardconfig_options = $boardConfigModel->getFormOptions();
}
$options = $this->_boardconfig_options;
break;

View File

@ -69,7 +69,7 @@ class CategoryModel extends BaseHierarchyModel
return $this->where($conditions)->first() ?: throw new \Exception("해당 데이터가 없습니다.\n" . var_export($conditions, true));
}
public function getFormOptions($conditions, $options = array()): array
public function getFormOptions(array $conditions = array(), $options = array()): array
{
$old_title = "";
foreach ($this->where($conditions)->orderby("grpno DESC, grporder ASC")->findAll() as $entity) {

View File

@ -7,14 +7,15 @@ use App\Entities\ProductEntity;
class OrderModel extends BaseModel
{
private $_product_options = null;
protected $table = "tw_order";
protected $useAutoIncrement = false;
protected $returnType = OrderEntity::class;
protected $useSoftDeletes = false;
protected $useSoftDeletes = true;
public function __construct()
{
parent::__construct('Order');
$this->allowedFields = ["uid", "user_uid", "sess_id", ...$this->allowedFields, ...$this->getFields(),];
$this->allowedFields = ["uid", "user_uid", ...$this->allowedFields, ...$this->getFields(),];
$this->validationRules = [...$this->validationRules, ...$this->getFieldRules($this->allowedFields),];
}
final public function getTitleField(): string
@ -28,7 +29,7 @@ class OrderModel extends BaseModel
case "index":
case "excel":
case "view":
return [$this->getTitleField(), "user_uid", "sess_id", "quantity", "price", "status", "updated_at", "created_at"];
return [$this->getTitleField(), "user_uid", "quantity", "price", "status", "updated_at", "created_at"];
break;
default:
return $fields;
@ -50,9 +51,6 @@ class OrderModel extends BaseModel
case "user_uid":
$rules[$field] = "required|regex_match[/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/]";
break;
case "sess_id":
$rules[$field] = "required|string";
break;
case 'quantity':
case 'price':
$rules[$field] = "required|numeric";
@ -64,28 +62,35 @@ class OrderModel extends BaseModel
return $rules;
}
protected function changeFormData(string $action, string $field, array $formDatas, $entity)
//Field별 Form Option용
public function getFieldFormOption(string $field): array
{
switch ($field) {
case "sess_id": //장바구니에 입력의 경우에만 자동으로 추가
if ($action == 'create') {
$entity->$field = $this->_session->session_id;
case 'product_uid':
if (is_null($this->_product_options)) {
$productModel = new productModel();
$this->_product_options = $productModel->getFormOptions();
}
$options = $this->_product_options;
break;
default:
$entity = parent::changeFormData($action, $field, $formDatas, $entity);
return parent::getFieldFormOption($field);
break;
}
return $entity;
if (!is_array($options)) {
throw new \Exception(__FUNCTION__ . "에서 {$this->getClassName()}의 Field:{$field}의 FormOptionData가 array가 아닙니다.\n" . var_export($options, true));
}
return $options;
}
public function getEntity($conditions): OrderEntity
{
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
{
@ -97,11 +102,4 @@ class OrderModel extends BaseModel
parent::setIndexWordFilter($word);
$this->orLike($this->getTitleField(), $word, "both");
}
//Ecommerce Action
//장바구니에 넣기
final public function addCart(ProductEntity $product, int $quantity, int $price): OrderEntity
{
return $this->create(['product_uid' => $product->getPrimaryKey(), 'quantity' => $quantity, 'price' => $price]);
}
}

View File

@ -10,7 +10,7 @@ class ProductModel extends BaseModel
protected $table = "tw_product";
protected $useAutoIncrement = false;
protected $returnType = ProductEntity::class;
protected $useSoftDeletes = false;
protected $useSoftDeletes = true;
public function __construct()
{
parent::__construct('Product');
@ -85,7 +85,7 @@ class ProductModel extends BaseModel
case 'category_uid':
if (is_null($this->_category_options)) {
$categoryModel = new CategoryModel();
$this->_category_options = $categoryModel->getFormOptions(['status' => 'use']);
$this->_category_options = $categoryModel->getFormOptions();
}
$options = $this->_category_options;
break;
@ -122,8 +122,11 @@ class ProductModel extends BaseModel
//Ecommerce Action
//장바구니에 넣기
final public function addCart(ProductEntity $entity, int $quantity): ProductEntity
final public function decreaseStock(ProductEntity $entity, int $quantity): ProductEntity
{
if ($entity->getStock() < $quantity) {
throw new \Exception("구매수량이 너무 많습니다.\n구매수량:{$quantity}개, 남은 재고수량:{$entity->getStock()}");
}
if ($entity->getStock() == $quantity) {
$entity->status = "outofstock";
}

View File

@ -9,7 +9,7 @@ class UserModel extends BaseModel
protected $table = "tw_user";
protected $useAutoIncrement = false;
protected $returnType = UserEntity::class;
protected $useSoftDeletes = false;
protected $useSoftDeletes = true;
public function __construct()
{
parent::__construct('User');

View File

@ -1,7 +1,21 @@
<?= form_open("admin/order/insert", ['method' => 'post']) ?>
<?= form_hidden("product_uid", $entity->getPrimaryKey()) ?>
<?= form_hidden("price", $entity->getPrice() - $entity->getSale()) ?>
구매 수량 : <?= getFieldForm_ProductHelper('quantity', 1, $fieldFormOptions) ?>
구매 금액 : <?= number_format(($entity->getPrice() - $entity->getSale()) * 1) ?>
<input type="hidden" id="price" name="price" value="<?= ($entity->getPrice() - $entity->getSale()) * 1 ?>">
<?php
$quantityOptions = [DEFAULTS['EMPTY'] => "구매수량 선택"];
for ($i = 1; $i <= $entity->getStock(); $i++) {
$quantityOptions[$i] = $i . "";
}
?>
구매 수량 : <?= form_dropdown('quantity', $quantityOptions, 1, ['onChange' => "cal_price(this.options[this.selectedIndex].value)"]); ?>
구매 금액 : <span id="order_price"><?= number_format(($entity->getPrice() - $entity->getSale()) * 1) ?></span>원
<?= form_submit('', '최소:1 ~ 최대:' . $entity->getStock(), array("class" => "btn btn-outline btn-primary")); ?>
<?= form_close(); ?>
<?= form_close(); ?>
<script>
function cal_price(quantity) {
var price = 0;
price = (<?= $entity->getPrice() ?> - <?= $entity->getSale() ?>) * quantity;;
document.getElementById('price').value = price;
document.getElementById('order_price').textContent = new Intl.NumberFormat().format(price);
}
</script>