반응형
옵션분류가 한개일때는 해 봤고 두개 이상일때 가격이 같다면 한개일때와 큰 차이는 없기때문에 2개이상이면서 가격이 다를때 어떻게 하는지 해보자. 우선 제품 등록부터 수정해보자.
/admin/product/product_up.php
<?php
include $_SERVER["DOCUMENT_ROOT"]."/inc/header.php";
if(!$_SESSION['AUID']){
echo "<script>alert('권한이 없습니다.');history.back();</script>";
exit;
}
$query="select * from category where step=1";
$result = $mysqli->query($query) or die("query error => ".$mysqli->error);
while($rs = $result->fetch_object()){
$cate1[]=$rs;
}
?>
<style>
.thst{
text-align: center;
vertical-align: middle;
}
</style>
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css" rel="stylesheet">
<div style="text-align:center;padding:20px;"><H3>제품등록하기</H3></div>
<form method="post" action="pupok.php" onsubmit="return save()" enctype="multipart/form-data">
<table class="table table-sm table-bordered">
<tbody>
<input type="hidden" name="file_table_id" id="file_table_id" value="">
<input type="hidden" name="contents" id="contents" value="">
<tr>
<th scope="row" class="thst">카테고리선택</th>
<td>
<div class="row g-3">
<div class="col-md-4">
<select class="form-select" name="cate1" id="cate1" aria-label="Default select example">
<option value="">대분류</option>
<?php
foreach($cate1 as $c){
?>
<option value="<?php echo $c->code;?>"><?php echo $c->name;?></option>
<?php }?>
</select>
</div>
<div class="col-md-4">
<select class="form-select" name="cate2" id="cate2" aria-label="Default select example">
<option value="">중분류</option>
</select>
</div>
<div class="col-md-4">
<select class="form-select" name="cate3" id="cate3" aria-label="Default select example">
<option value="">소분류</option>
</select>
</div>
</div>
</td>
</tr>
<tr>
<th scope="row" class="thst">제품명</th>
<td><input type="text" class="form-control" name="name" id="name"></td>
</tr>
<tr>
<th scope="row" class="thst">택배비</th>
<td><input type="number" style="width:200px;text-align:right;" class="form-control" name="delivery_fee" id="delivery_fee"></td>
</tr>
<tr>
<th scope="row" class="thst">제품가격</th>
<td><input type="number" style="width:200px;text-align:right;" class="form-control" name="price" id="price"></td>
</tr>
<tr>
<th scope="row" class="thst">세일가격</th>
<td><input type="number" style="width:200px;text-align:right;" class="form-control" name="sale_price" id="sale_price"></td>
</tr>
<tr>
<th scope="row" class="thst">세일비율</th>
<td><input type="number" style="width:200px;text-align:right;" class="form-control" name="sale_ratio" id="sale_ratio"></td>
</tr>
<tr>
<th scope="row" class="thst">재고</th>
<td><input type="number" style="width:200px;text-align:right;" class="form-control" name="cnt" id="cns"></td>
</tr>
<tr>
<th scope="row" class="thst">전시옵션</th>
<td>
<input class="form-check-input" type="checkbox" name="ismain" id="ismain" value="1">메인
<input class="form-check-input" type="checkbox" name="isnew" id="isnew" value="1">신제품
<input class="form-check-input" type="checkbox" name="isbest" id="isbest" value="1">베스트
<input class="form-check-input" type="checkbox" name="isrecom" id="isrecom" value="1">추천
</td>
</tr>
<tr>
<th scope="row" class="thst">위치지정</th>
<td>
<select class="form-select" name="locate" id="locate" aria-label="Default select example">
<option value="0">지정안함</option>
<option value="1">1번위치</option>
<option value="2">2번위치</option>
</select>
</td>
</tr>
<tr>
<th scope="row" class="thst">판매종료일</th>
<td>
<input type="text" class="form-control" style="width: 272px;" name="sale_end_date" id="sale_end_date" value="<?php echo date("Y-m-d",strtotime("+6 month"))?>">
</td>
</tr>
<tr>
<th scope="row" class="thst">제품상세설명</th>
<td>
<div id="summernote"></div>
</td>
</tr>
<tr>
<th scope="row" class="thst">썸네일</th>
<td><input type="file" class="form-control" name="thumbnail" id="thumbnail"></td>
</tr>
<tr style="max-height:100px;">
<th scope="row" class="thst">추가이미지</th>
<td style="height:100px;">
<input type="file" multiple name="upfile[]" id="upfile" style="display:none;">
<div id="target_file_wrap">
<a href="#" onclick="jQuery('#upfile').click()" class="btn btn-primary">이미지선택</a>
</div>
<div class="row row-cols-1 row-cols-md-6 g-4" id="imageArea">
</div>
</td>
</tr>
<tr>
<th scope="row" class="thst">
<select class="form-select" name="optionCate1" id="optionCate1">
<option value="컬러" selected>컬러</option>
</select>
</th>
<td>
<table class="table">
<thead>
<tr>
<th scope="col">옵션명</th>
<th scope="col">재고</th>
<th scope="col">가격</th>
<th scope="col">이미지</th>
</tr>
</thead>
<tbody id="option1">
<tr id="optionTr1">
<th scope="row">
<input class="form-control" type="text" style="max-width:200px;" value="" name="optionName1[]">
</th>
<td>
<div class="input-group">
<input type="text" class="form-control" style="max-width:100px;" value="0" name="optionCnt1[]">
<span class="input-group-text">개</span>
</div>
</td>
<td>
<div class="input-group">
<input type="text" class="form-control" style="max-width:100px;" value="0" name="optionPrice1[]">
<span class="input-group-text">원</span>
</div>
</td>
<td>
<input type="file" class="form-control" name="optionImage1[]" id="optionImage1">
</td>
</tr>
</tbody>
</table>
<button class="btn btn-secondary" type="button" onclick="opt1cp()">옵션추가</button>
</td>
</tr>
<tr>
<th scope="row" class="thst">
<select class="form-select" name="optionCate2" id="optionCate2">
<option value="사이즈" selected>사이즈</option>
</select>
</th>
<td>
<table class="table">
<thead>
<tr>
<th scope="col">옵션명</th>
<th scope="col">재고</th>
<th scope="col">가격</th>
</tr>
</thead>
<tbody id="option2">
<tr id="optionTr2">
<th scope="row">
<input class="form-control" type="text" style="max-width:200px;" value="" name="optionName2[]">
</th>
<td>
<div class="input-group">
<input type="text" class="form-control" style="max-width:100px;" value="0" name="optionCnt2[]">
<span class="input-group-text">개</span>
</div>
</td>
<td>
<div class="input-group">
<input type="text" class="form-control" style="max-width:100px;" value="0" name="optionPrice2[]">
<span class="input-group-text">원</span>
</div>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-secondary" type="button" onclick="opt2cp()">옵션추가</button>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" type="submit">등록완료</button>
</form>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script>
function opt1cp(){
var addHtml=$("#optionTr1").html();
var addHtml="<tr>"+addHtml+"</tr>";
$("#option1").append(addHtml);
}
function opt2cp(){
var addHtml=$("#optionTr2").html();
var addHtml="<tr>"+addHtml+"</tr>";
$("#option2").append(addHtml);
}
function save(){
var markup = $('#summernote').summernote('code');
var contents=encodeURIComponent(markup);
$("#contents").val(contents);
}
$(function(){
$('#summernote').summernote({
height: 300
});
$("#sale_end_date").datepicker({ dateFormat: 'yy-mm-dd' });
});
$("#cate1").change(function(){
var cate1 = $("#cate1 option:selected").val();
var data = {
cate1 : cate1
};
$.ajax({
async : false ,
type : 'post' ,
url : 'category2.php' ,
data : data ,
dataType : 'html' ,
error : function() {} ,
success : function(return_data) {
$("#cate2").html(return_data);
}
});
});
$("#cate2").change(function(){
var cate2 = $("#cate2 option:selected").val();
var data = {
cate2 : cate2
};
$.ajax({
async : false ,
type : 'post' ,
url : 'category3.php' ,
data : data ,
dataType : 'html' ,
error : function() {} ,
success : function(return_data) {
$("#cate3").html(return_data);
}
});
});
$("#upfile").change(function(){
var files = $('#upfile').prop('files');
for(var i=0; i < files.length; i++) {
attachFile(files[i]);
}
$('#upfile').val('');
});
function attachFile(file) {
var formData = new FormData();
formData.append("savefile", file);
$.ajax({
url: 'product_save_image.php',
data: formData,
cache: false,
contentType: false,
processData: false,
dataType : 'json' ,
type: 'POST',
success: function (return_data) {
if(return_data.result=="member"){
alert('로그인 하십시오.');
return;
}else if(return_data.result=="size"){
alert('10메가 이하만 첨부할 수 있습니다.');
return;
}else if(return_data.result=="image"){
alert('이미지 파일만 첨부할 수 있습니다.');
return;
}else if(return_data.result=="error"){
alert('첨부하지 못했습니다. 관리자에게 문의하십시오.');
return;
}else{
imgid = $("#file_table_id").val() + return_data.imgid + ",";
$("#file_table_id").val(imgid);
var html = "<div class='col' id='f_"+return_data.imgid+"'><div class='card h-100'><img src='/pdata/"+return_data.savename+"' class='card-img-top'><div class='card-body'><button type='button' class='btn btn-warning' onclick='file_del("+return_data.imgid+")'>삭제</button></div></div></div>";
$("#imageArea").append(html);
}
}
});
}
function file_del(imgid){
if(!confirm('삭제하시겠습니까?')){
return false;
}
var data = {
imgid : imgid
};
$.ajax({
async : false ,
type : 'post' ,
url : 'image_delete.php' ,
data : data ,
dataType : 'json' ,
error : function() {} ,
success : function(return_data) {
if(return_data.result=="member"){
alert('로그인 하십시오.');
return;
}else if(return_data.result=="my"){
alert('본인이 작성한 제품의 이미지만 삭제할 수 있습니다.');
return;
}else if(return_data.result=="no"){
alert('삭제하지 못했습니다. 관리자에게 문의하십시오.');
return;
}else{
$("#f_"+imgid).hide();
}
}
});
}
</script>
<?php
include $_SERVER["DOCUMENT_ROOT"]."/inc/footer.php";
?>
두번째 옵션분류는 사이즈라고 하겠다. 보통 컬러와 사이즈가 옵션분류가 되는 경우가 가장 많다. 그리고 옵션분류가 2개인 경우가 가장 많다.
방법은 옵션이 하나일때와 비슷하다. 다만 사이즈에는 사진이 없다. 이제 이값들을 처리해줄 파일을 수정해보자.
/admin/product/pupok.php
<?php session_start();
include $_SERVER["DOCUMENT_ROOT"]."/inc/dbcon.php";
ini_set( 'display_errors', '0' );
if(!$_SESSION['AUID']){
echo "<script>alert('권한이 없습니다.');history.back();</script>";
exit;
}
$cate=$_POST["cate1"].$_POST["cate2"].$_POST["cate3"];//대중소분류를 모두 저장한다.
$name=$_POST["name"];//제품명
$delivery_fee=$_POST["delivery_fee"];//택배비
$price=$_POST["price"];//가격
$sale_price=$_POST["sale_price"];//세일가
$sale_ratio=$_POST["sale_ratio"];//세일비율
$cnt=$_POST["cnt"];//재고
$contents=rawurldecode($_POST['contents']);//제품 설명
$ismain=$_POST["ismain"];//메인
$isnew=$_POST["isnew"];//신상품
$isbest=$_POST["isbest"];//베스트
$isrecom=$_POST["isrecom"];//추천
$locate=$_POST["locate"];//위치
$sale_end_date=$_POST["sale_end_date"];//판매종료일
$file_table_id=$_POST["file_table_id"];//이미지
$file_table_id=rtrim($file_table_id,",");//오른쪽 끝에 , 삭제
$optionCate1=$_POST["optionCate1"];//옵션분류
$optionCate2=$_POST["optionCate2"];//옵션분류
if($_FILES["thumbnail"]["name"]){//첨부한 파일이 있으면
if($_FILES['thumbnail']['size']>10240000){//10메가
echo "<script>alert('10메가 이하만 첨부할 수 있습니다.');history.back();</script>";
exit;
}
if($_FILES['thumbnail']['type']!='image/jpeg' and $_FILES['thumbnail']['type']!='image/gif' and $_FILES['thumbnail']['type']!='image/png'){//이미지가 아니면, 다른 type은 and로 추가
echo "<script>alert('이미지만 첨부할 수 있습니다.');history.back();</script>";
exit;
}
$save_dir = $_SERVER['DOCUMENT_ROOT']."/pdata/";//파일을 업로드할 디렉토리
$filename = $_FILES["thumbnail"]["name"];
$ext = pathinfo($filename,PATHINFO_EXTENSION);//확장자 구하기
$newfilename = date("YmdHis").substr(rand(),0,6);
$thumbnail = $newfilename.".".$ext;//새로운 파일이름과 확장자를 합친다
if(move_uploaded_file($_FILES["thumbnail"]["tmp_name"], $save_dir.$thumbnail)){
$thumbnail = "/pdata/".$thumbnail;
}else{
echo "<script>alert('이미지를 등록할 수 없습니다. 관리자에게 문의해주십시오.');history.back();</script>";
exit;
}
}
$sale_cnt = 0;//판매량
$query="INSERT INTO products
(name, cate, content, thumbnail, price, sale_price, sale_ratio, cnt, sale_cnt, isnew, isbest, isrecom, ismain, locate, userid, sale_end_date, reg_date, delivery_fee)
VALUES('$name'
, '".$cate."'
, '".$contents."'
, '".$thumbnail."'
, '".$price."'
, '".$sale_price."'
, '".$sale_ratio."'
, ".$cnt."
, ".$sale_cnt."
, '".$isnew."'
, '".$isbest."'
, '".$isrecom."'
, '".$ismain."'
, '".$locate."'
, '".$_SESSION['AUID']."'
, '".$sale_end_date."'
, now()
, '".$delivery_fee."'
)";
$rs=$mysqli->query($query) or die($mysqli->error);
$pid = $mysqli -> insert_id;
if($rs){
//옵션부분
$optionName1=$_REQUEST["optionName1"];//옵션명
$optionCnt1=$_REQUEST["optionCnt1"];//재고
$optionPrice1=$_REQUEST["optionPrice1"];//가격
$optionName2=$_REQUEST["optionName2"];//옵션명
$optionCnt2=$_REQUEST["optionCnt2"];//재고
$optionPrice2=$_REQUEST["optionPrice2"];//가격
if($_FILES["optionImage1"]["name"][0]){//첨부한 파일이 있으면
for($k=0;$k<count($_FILES["optionImage1"]["name"]);$k++){
if($_FILES['optionImage1']['size'][$k]>10240000){//10메가
echo "<script>alert('10메가 이하만 첨부할 수 있습니다.');history.back();</script>";
exit;
}
if($_FILES['optionImage1']['type'][$k]!='image/jpeg' and $_FILES['optionImage1']['type'][$k]!='image/gif' and $_FILES['optionImage1']['type'][$k]!='image/png'){//이미지가 아니면, 다른 type은 and로 추가
echo "<script>alert('이미지만 첨부할 수 있습니다.');history.back();</script>";
exit;
}
$save_dir = $_SERVER['DOCUMENT_ROOT']."/pdata/optiondata/";//파일을 업로드할 디렉토리
$filename = $_FILES["optionImage1"]["name"][$k];
$ext = pathinfo($filename,PATHINFO_EXTENSION);//확장자 구하기
$newfilename = date("YmdHis").substr(rand(),0,6);
$optionImage1 = $newfilename.".".$ext;//새로운 파일이름과 확장자를 합친다
if(move_uploaded_file($_FILES["optionImage1"]["tmp_name"][$k], $save_dir.$optionImage1)){
$upload_option_image[]="/pdata/optiondata/".$optionImage1;
}
}
}
$k=0;
foreach($optionName1 as $on){
if($on){
$optQuery="INSERT INTO testdb.product_options
(pid, cate, option_name, option_cnt, option_price, image_url)
VALUES (".$pid.", '".$optionCate1."', '".$on."', ".$optionCnt1[$k].", ".$optionPrice1[$k].", '".$upload_option_image[$k]."')";
$ofs=$mysqli->query($optQuery) or die($mysqli->error);
$k++;
}
}
$k=0;
foreach($optionName2 as $on){
if($on){
$optQuery="INSERT INTO testdb.product_options
(pid, cate, option_name, option_cnt, option_price)
VALUES (".$pid.", '".$optionCate2."', '".$on."', ".$optionCnt2[$k].", ".$optionPrice2[$k].")";
$ofs=$mysqli->query($optQuery) or die($mysqli->error);
$k++;
}
}
if($file_table_id){//첨부한 이미지 테이블 업데이트
$upquery="update product_image_table set pid=".$pid." where imgid in (".$file_table_id.")";
$fs=$mysqli->query($upquery) or die($mysqli->error);
}
echo "<script>alert('등록했습니다.');location.href='/admin/product/product_list.php';</script>";
exit;
}else{
echo "<script>alert('등록하지 못했습니다. 관리자에게 문의해주십시오.');history.back();</script>";
exit;
}
?>
비슷하다. 다만 이미지부분이 없을뿐.
제품을 등록할때 컬러에 2개, 사이즈에 2개를 올려라, 둘다 가격에 값을 넣고 재고에는 넣지 마라. 일단 가격이 변하는걸 보도록 하자.
/admin/product/product_view.php
<?php
include $_SERVER["DOCUMENT_ROOT"]."/inc/header.php";
if(!$_SESSION['AUID']){
echo "<script>alert('권한이 없습니다.');history.back();</script>";
exit;
}
//ini_set( 'display_errors', '1' );
$pid = $_GET['pid'];
$query="select * from products where pid=".$pid;
$result = $mysqli->query($query) or die("query error => ".$mysqli->error);
$rs = $result->fetch_object();
$query2="select * from product_options where cate='컬러' and pid=".$pid;
$result2 = $mysqli->query($query2) or die("query error => ".$mysqli->error);
while($rs2 = $result2->fetch_object()){
$options1[]=$rs2;
}
$query2="select * from product_options where cate='사이즈' and pid=".$pid;
$result2 = $mysqli->query($query2) or die("query error => ".$mysqli->error);
while($rs2 = $result2->fetch_object()){
$options2[]=$rs2;
}
?>
<style>
.col{
border: 1px solid #f1f1f1;
}
[type=radio] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
[type=radio] + span {
cursor: pointer;
}
[type=radio]:checked + span {
outline: 5px solid indigo;
}
</style>
<div class="container">
<div class="row">
<div class="col" style="text-align:center;">
<img id="pimg" src="<?php echo $rs->thumbnail;?>" style="max-width:200px;">
</div>
<div class="col">
<h3><?php echo $rs->name;?></h3>
<div>
가격 : <span id="price"><?php echo number_format($rs->price);?></span>원
</div>
<?php if($options1){?>
<!-- <div>
옵션 :
<select name="poption" id="poption">
<option value="">선택하세요</option>
<?php foreach($options as $op){?>
<option value="<?php echo $op->poid;?>"><?php echo $op->option_name;?></option>
<?php }?>
</select>
</div> -->
<br>
<div>
<?php foreach($options1 as $op1){?>
<input type="radio" name="poption1" id="poption1_<?php echo $op1->poid;?>" value="<?php echo $op1->poid;?>">
<span onclick="jQuery('#poption1_<?php echo $op1->poid;?>').click();" style="content:url(<?php echo $op1->image_url;?>);height:100px;width:100px;"></span>
</input>
<?php }?>
</div>
<br>
<div>
<?php foreach($options2 as $op2){
$option_name=$op2->option_name;
if($op2->option_price)$option_name.="(+".number_format($op2->option_price).")";
?>
<input type="radio" name="poption2" id="poption2_<?php echo $op2->poid;?>" value="<?php echo $op2->poid;?>">
<span onclick="jQuery('#poption2_<?php echo $op2->poid;?>').click();"><?php echo $option_name;?></span>
</input>
<?php }?>
</div>
<?php }?>
</div>
</div>
</div>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script>
$("input[name='poption1']:radio,input[name='poption2']:radio").change(function () {
var poid1 = $('input:radio[name="poption1"]:checked').val();
var poid2 = $('input:radio[name="poption2"]:checked').val();
var data = {
poid1 : poid1,
poid2 : poid2
};
$.ajax({
async : false ,
type : 'post' ,
url : 'option_change.php' ,
data : data ,
dataType : 'json' ,
error : function() {} ,
success : function(data) {
//console.log(JSON.stringify(data));
var price=parseInt(data.option_price1)+parseInt(data.option_price2)+<?php echo $rs->price;?>;
$("#pimg").attr("src", data.image_url);
$("#price").text(number_format(price));
}
});
});
function number_format(num){
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g,',');
}
$("#poption").change(function(){
var poid = $("#poption option:selected").val();
var data = {
poid : poid
};
$.ajax({
async : false ,
type : 'post' ,
url : 'option_change.php' ,
data : data ,
dataType : 'json' ,
error : function() {} ,
success : function(data) {
var price=parseInt(data.option_price)+<?php echo $rs->price;?>;
$("#pimg").attr("src", data.image_url);
$("#price").text(number_format(price));
}
});
});
</script>
<?php
include $_SERVER["DOCUMENT_ROOT"]."/inc/footer.php";
?>
앞에서 할땐 있었던 select박스 옵션을 선택하는 부분은 뺐다. 이미지로 선택하는 것만 놔뒀다.
첫번째 옵션을 선택하거나 두번째 옵션을 선택하면 가격이 변한다. 테스트를 위해 컬러에도 가격을 넣었는데 대부분 컬러 바꾼다고 가격이 변하는 경우는 없다.
방법은 옵션을 선택할때마다 ajax를 통해 선택한 옵션을 확인해서 가격을 가져오고 원래 가격에 가격을 더해 보여준다.
다음엔 재고가 다를 경우를 해보자. 이건 좀더 어렵다.
반응형
'PHP강좌 > 쇼핑몰만들기강좌' 카테고리의 다른 글
php+mysql 쇼핑몰 만들기 강좌 - #13 이미지 서버에 등록 feat. CDN (0) | 2022.03.29 |
---|---|
php+mysql 쇼핑몰 만들기 강좌 - #12 WMS 시스템 연동하기(재고관리) (0) | 2022.03.26 |
php+mysql 쇼핑몰 만들기 강좌 - #10 제품 상세 페이지 옵션에 이미지 보여주기 (0) | 2022.03.22 |
php+mysql 쇼핑몰 만들기 강좌 - #9 제품 상세 페이지 간략 (0) | 2022.03.22 |
php+mysql 쇼핑몰 만들기 강좌 - #8 제품 옵션분류가 한개일때 (0) | 2022.03.21 |