?<?php
namespace?app\api\service;
use?app\api\model\OrderProduct;
use?app\api\model\Product;
use?app\api\model\UserAddress;
use?app\lib\exception\OrderException;
use?app\lib\exception\UserException;
use?think\Exception;
class?Order
{
????//?訂單的商品列表,客戶(hù)端傳遞來(lái)的下單商品參數(shù)--二維數(shù)組
????protected?$oProducts;
????//?根據(jù)product_id從數(shù)據(jù)庫(kù)中查詢(xún)出的真實(shí)商品信息--庫(kù)存量
????protected?$products;
????protected?$uid;
????//?下單方法,參數(shù)$uid--用戶(hù),$oProducts
????public?function?place($uid,?$oProducts)
????{
????????//?將傳進(jìn)來(lái)的$uid和$oProducts賦值給成員變量$uid和$oProducts
????????$this->uid?=?$uid;
????????$this->oProducts?=?$oProducts;
????????//?從數(shù)據(jù)庫(kù)中獲取$products的信息,調(diào)用方法getProductsByOrder
????????$this->products?=?$this->getProductsByOrder($oProducts);
????????//?獲取getOrderStatus方法的返回結(jié)果
????????$status?=?$this->getOrderStatus();
????????//?查看庫(kù)存量是否通過(guò),未通過(guò)則:
????????if?(!$status['pass'])?{
????????????//在$status數(shù)組中增加訂單編號(hào)為-1,表示訂單創(chuàng)建失敗值,作為標(biāo)記
????????????$status['order_id']?=?-1;
????????????//返回結(jié)果到客戶(hù)端,
????????????return?$status;
????????}
????????//?庫(kù)存量通過(guò),則創(chuàng)建訂單.第一步,創(chuàng)建訂單快照
????????$orderSnap?=?$this->snapOrder($status);
????????$order?=?$this->createOrder($orderSnap);
????????$order['pass']?=?true;
????????return?$order;
????}
????//?10-12
????//?第二步,創(chuàng)建訂單
????private?function?createOrder($snap)
????{
????????try?{
????????????//?訂單號(hào)
????????????$orderNo?=?$this->makeOrderNo();
????????????//?實(shí)例化order模型
????????????$order?=?new?\app\api\model\Order();
????????????//?數(shù)據(jù)庫(kù)的order表中插入數(shù)據(jù)
????????????$order->user_id?=?$this->uid;
????????????$order->order_no?=?$orderNo;
????????????$order->total_price?=?$snap['orderPrice'];
????????????$order->total_count?=?$snap['totalCount'];
????????????$order->snap_img?=?$snap['snapImg'];
????????????$order->snap_name?=?$snap['snapNme'];
????????????$order->snap_address?=?$snap['snapAddress'];
????????????$order->snap_items?=?json_encode($snap['pStatus']);
????????????$order->save();
????????????//?order表的id?插入?到order_product的order_id賦值
????????????//?獲取order表的id和create_time
????????????$orderID?=?$order->id;
????????????$create_time?=?$order->create_time;
????????????//?為訂單中的每一個(gè)商品添加$orderID
????????????//?&引用符號(hào),才能夠在數(shù)組中增加字段
????????????foreach?($this->oProducts?as?&$p)?{
????????????????$p['order_id']?=?$orderID;
????????????}
????????????//調(diào)用模型orderproduct,將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)order_product表
????????????$orderProduct?=?new?OrderProduct();
????????????//?保存數(shù)組需要調(diào)用saveAll方法
????????????$orderProduct->saveAll($this->oProducts);
????????????return?[
????????????????'order_no'?=>?$orderNo,
????????????????'order_id'?=>?$orderID,
????????????????'create_time'?=>?$create_time
????????????];
????????}?catch?(Exception?$ex)?{
????????????throw?$ex;
????????}
????}
????//?生成訂單號(hào)
????public?static?function?makeOrderNo()
????{
????????$yCode?=?array('A',?'B',?'C',?'D',?'E',?'F',?'G',?'H',?'I',?'J');
????????$orderSn?=
????????????$yCode[intval(date('Y'))?-?2019]?.?strtoupper(dechex(date('m')))?.?date(
????????????????'d')?.?substr(time(),?-5)?.?substr(microtime(),?2,?5)?.?sprintf(
????????????????'%02d',?rand(0,?99));
????????return?$orderSn;
????}
????//?10-11
????//?生成訂單快照
????private?function?snapOrder($status)
????{
????????//快照信息的關(guān)聯(lián)數(shù)組
????????$snap?=?[
????????????//商品總價(jià)
????????????'orderPrice'?=>?0,
????????????//所有商品的數(shù)量和
????????????'totalCount'?=>?0,
????????????//單類(lèi)商品的詳細(xì)信息
????????????'pStatus'?=>?[],
????????????//快照地址,快照商品名,快照商品圖
????????????'snapAddress'?=>?null,
????????????//訂單中第一個(gè)商品的名字和圖片作為快照
????????????'snapName'?=>?'',
????????????'snapImg'?=>?''
????????];
????????$snap['orderPrice']?=?$status['orderPrice'];
????????$snap['totalCount']?=?$status['totalCount'];
????????$snap['pStatus']?=?$status['pStatusArray'];
????????//將$userAddress數(shù)組序列化為json字符串,方便存入數(shù)據(jù)庫(kù)中,但不太好.
????????$snap['snapAddress']?=?json_encode($this->getUserAddress());
????????$snap['snapName']?=?$this->products[0]['name'];
????????$snap['snapImg']?=?$this->products[0]['main_img_url'];
????????if?(count($this->products)?>?1)?{
????????????$snap['snapName']?.=?'等';
????????}
//????????print_r($snap);
????}
????//?獲取快照地址
????private?function?getUserAddress()
????{
????????//獲取$userAddress對(duì)象
????????$userAddress?=?UserAddress::where('user_id',?'=',?$this->uid)->find();
????????if?(!$userAddress)?{
????????????throw?new?UserException([
????????????????'msg'?=>?'用戶(hù)收貨地址不存在,下單失敗',
????????????????'errorCode'?=>?60001
????????????]);
????????}
????????//返回$userAddress數(shù)組
????????return?$userAddress->toArray();
????}
????//?10-9?下單接口業(yè)務(wù)模型二
????//?定義方法:獲取訂單狀態(tài).對(duì)比$oProducts和$products,檢驗(yàn)庫(kù)存量
????//?此處不需要傳遞參數(shù)$oProducts和$products,是因?yàn)楸绢?lèi)中已經(jīng)定了賦值好了.
????//?定義訂單狀態(tài)相關(guān)屬性,用于返回結(jié)果
????//??????pass--庫(kù)存量檢測(cè)是否通過(guò),默認(rèn)值設(shè)為true
????//??????orderPrice--所有商品價(jià)格總和,默認(rèn)值設(shè)為0
????//??????pStatusArray--數(shù)組,通過(guò)order的product_id獲取并保存訂單中所有商品的詳細(xì)信息
????//??????????????????用于歷史訂單,默認(rèn)值設(shè)為空數(shù)組
????//獲取訂單狀態(tài),返回值為數(shù)組,包含庫(kù)存量是否充足,所有商品總價(jià),和所有訂單商品的詳細(xì)信息.
????private?function?getOrderStatus()
????{
????????$status?=?[
????????????'pass'?=>?true,
????????????'orderPrice'?=>?0,
????????????'totalCount'?=>?0,
????????????'pStatusArray'?=>?[]
????????];
????????//?使用循環(huán)對(duì)比進(jìn)行庫(kù)存量檢測(cè)
????????foreach?($this->oProducts?as?$oProduct)?{
????????????$pStatus?=?$this->getProductStatus(
????????????????$oProduct['product_id'],?$oProduct['count'],?$this->products
????????????);
????????????if?(!$pStatus['haveStock'])?{
????????????????$status['pass']?=?false;
????????????}
????????????$status['orderPrice']?+=?$pStatus['totalPrice'];
????????????$status['totalCount']?+=?$pStatus['count'];
????????????array_push($status['pStatusArray'],?$pStatus);
????????}
????????return?$status;
????}
????//?定義方法getProductStatus
????//?根據(jù)$oPIDs中的product_id獲取$products數(shù)組中對(duì)應(yīng)的商品庫(kù)存量
????//?$oPIDs數(shù)組中只有product_id
????//?定義$pStatus的數(shù)據(jù)結(jié)構(gòu)
????//??????$pStatus的作用,將本次訂單信息保存至歷史訂單
????//?$pIndex指定product_id在$products中id對(duì)應(yīng)數(shù)組的下標(biāo)序號(hào)
????//?totalPrice--訂單中某個(gè)商品的總價(jià)格
????private?function?getProductStatus($oPIDs,?$oCount,?$products)
????{
????????$pIndex?=?-1;
????????$pStatus?=?[
????????????'id'?=>?null,
????????????'haveStock'?=>?false,
????????????//訂單中某個(gè)商品的數(shù)量
????????????'count'?=>?0,
????????????'name'?=>?'',
????????????'totalPrice'?=>?0
????????];
????????//使用循環(huán)找出$pIndex
????????for?($i?=?0;?$i?<?count($products);?$i++)?{
????????????if?($oPIDs?==?$products[$i]['id'])?{
????????????????$pIndex?=?$i;
????????????}
????????}
????????if?($pIndex?==?-1)?{
????????????//以防用戶(hù)下單的商品客戶(hù)端傳遞的productid有可能根本不存在,在服務(wù)器中已經(jīng)下架了或丟失了,即$pIndex?=?-1,需要拋出異常
????????????throw?new?OrderException([
????????????????'msg'?=>?'id為'?.?$oPIDs?.?'的商品不存在,訂單創(chuàng)建失敗'
????????????]);
????????}?else?{
????????????$products?=?$products[$pIndex];
????????????$pStatus['id']?=?$products['id'];
????????????$pStatus['count']?=?$oCount;
????????????$pStatus['name']?=?$products['name'];
????????????$pStatus['totalPrice']?=?$products['price']?*?$oCount;
????????????if?($products['stock']?-?$oCount?>=?0)?{
????????????????$pStatus['haveStock']?=?true;
????????????}
????????}
????????return?$pStatus;
????}
????//?根據(jù)訂單信息$oProducts查找真實(shí)的商品信息$products
????private?function?getProductsByOrder($oProducts)
????{
????????//?通過(guò)循環(huán)將product_id讀取出來(lái)并存放在$oPIDs數(shù)組中,$oPIDs是一個(gè)只有product_id的以為數(shù)組.
????????$oPIDs?=?[];
????????foreach?($oProducts?as?$item)?{
????????????array_push($oPIDs,?$item['product_id']);
????????}
????????//?通過(guò)新構(gòu)造的數(shù)組$oPIDs,調(diào)用Product模型的all方法到數(shù)據(jù)庫(kù)中進(jìn)行硬查詢(xún)
????????//??????并使用->visible方法獲取指定部分?jǐn)?shù)據(jù)
????????//???之前在全局配置中數(shù)組返回形式是collection數(shù)據(jù)集,
????????//???此處使用數(shù)據(jù)集的toArray方法將數(shù)據(jù)集轉(zhuǎn)化為數(shù)組形式(方便與$oProducts數(shù)組作對(duì)比)
????????//?查詢(xún)結(jié)構(gòu)$products是一個(gè)二維數(shù)組
????????$products?=?Product::all($oPIDs)
????????????->visible(['id',?'price',?'stock',?'name',?'main_img_url'])
????????????->toArray();
????????return?$products;
????}
}
添加回答
舉報(bào)
0/150
提交
取消