travis
5 years ago
11 changed files with 649 additions and 2 deletions
-
34backend/modules/shop/controllers/OrderController.php
-
242backend/modules/shop/logic/delivery/DeliveryManager.php
-
37backend/modules/shop/migrations/m191206_024047_create_table_delivery_goods.php
-
79backend/modules/shop/models/ars/DeliveryGoods.php
-
2backend/modules/shop/models/searchs/DeliverySearch.php
-
5backend/modules/shop/models/searchs/OrderSearch.php
-
56backend/modules/shop/views/order/delivery.php
-
130backend/modules/shop/views/order/delivery_goods.php
-
11backend/modules/shop/views/order/logistics.php
-
5backend/modules/shop/views/order/shipping_info.php
-
50console/controllers/TestController.php
@ -0,0 +1,242 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace backend\modules\shop\logic\delivery; |
|||
|
|||
use backend\modules\shop\models\ars\Delivery; |
|||
use backend\modules\shop\models\ars\DeliveryGoods; |
|||
use backend\modules\shop\models\ars\ExpressTemplate; |
|||
use backend\modules\shop\models\ars\Order; |
|||
use backend\modules\shop\models\ars\OrderGoods; |
|||
use Yii; |
|||
use yii\db\Exception; |
|||
|
|||
class DeliveryManager |
|||
{ |
|||
/** |
|||
* @param $order |
|||
* @param $delivery |
|||
* @return array |
|||
* 订单发货 |
|||
*/ |
|||
public static function orderDelivery($order, $delivery) |
|||
{ |
|||
$transaction = Yii::$app->db->beginTransaction(); |
|||
try { |
|||
$data = Yii::$app->request->post(); |
|||
if (empty($data['deliveryGoods'])) { |
|||
throw new Exception('缺少发货商品信息'); |
|||
} |
|||
$deliveryGoods = json_decode($data['deliveryGoods']); |
|||
$delivery->load($data); |
|||
$delivery->order_id = $order->id; |
|||
if (!$delivery->save()) { |
|||
throw new Exception('保存物流信息失败'); |
|||
} |
|||
|
|||
/*发货商品数据*/ |
|||
self::deliveryGoods($delivery->id, $order, $deliveryGoods); |
|||
|
|||
$transaction->commit(); |
|||
return ['status' => true]; |
|||
} catch (Exception $e) { |
|||
$transaction->rollBack(); |
|||
return ['status' => false, 'info' => $e->getMessage()]; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @param $delivery_id |
|||
* @param $order |
|||
* @param $deliveryGoods |
|||
* @throws Exception |
|||
* 发货商品数据 |
|||
*/ |
|||
public static function deliveryGoods($delivery_id, $order, $deliveryGoods) |
|||
{ |
|||
foreach ($deliveryGoods as $k => $value) { |
|||
$model = new DeliveryGoods(); |
|||
$model->delivery_id = $delivery_id; |
|||
$model->order_goods_id = $value->id; |
|||
$model->goods_id = $value->goods_id; |
|||
$model->goods_name = $value->goods_name; |
|||
$model->goods_number = $value->goods_number; |
|||
if ($model->goods_number < $value->lack_number) { |
|||
$order->status = Order::STATUS_SHIPMENT_PORTION; |
|||
} else { |
|||
$order->status = Order::STATUS_SHIPMENT_ALL; |
|||
} |
|||
if (!$order->save()) { |
|||
throw new Exception('order shipping_status update false'); |
|||
} |
|||
if (!$model->save()) { |
|||
throw new Exception('delivery_goods save false'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* @param $order |
|||
* @param $goodsStatus |
|||
* @throws Exception |
|||
* @name '修改发货状态' |
|||
*/ |
|||
public function updateShippedStatus($order, $goodsStatus){ |
|||
|
|||
|
|||
} |
|||
|
|||
/** |
|||
* @param $order_id |
|||
* @return array |
|||
* @throws Exception |
|||
* 获取发货全部商品信息 |
|||
*/ |
|||
public static function deliveryGoodsInfo($order_id) |
|||
{ |
|||
$delivery = Delivery::find()->select('id')->where(['order_id' => $order_id])->all(); |
|||
/*如果该订单是首次发货*/ |
|||
if (!$delivery) { |
|||
$unShippend = self::firstDelivery($order_id); |
|||
return ['unShipped' => $unShippend]; |
|||
} |
|||
|
|||
$deliveryIds = []; |
|||
foreach ($delivery as $value) { |
|||
$deliveryIds[] = $value->id; |
|||
} |
|||
|
|||
$filter = []; |
|||
$deliveryGoods = DeliveryGoods::find()->where(['delivery_id' => $deliveryIds])->all(); |
|||
for ($i = 0; $i < count($deliveryGoods); $i++) { |
|||
$orderGoodsId = $deliveryGoods[$i]['order_goods_id']; |
|||
//以orderGoods的id为键名,以orderGoods的数量为键值,先保存到filter数组中
|
|||
$filter[$orderGoodsId] = $deliveryGoods[$i]['goods_number']; |
|||
for ($j = 0; $j < count($deliveryGoods); $j++) { |
|||
//如果发货商品中有其他相同orderGoods的商品
|
|||
if ($orderGoodsId == $deliveryGoods[$j]['order_goods_id'] && $i !== $j) { |
|||
//商品数量叠加起来并保存
|
|||
$filter[$orderGoodsId] += $deliveryGoods[$j]['goods_number']; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*获取订单已发的商品和未发的商品*/ |
|||
return self::getDeliveryGoodsInfo($filter, $order_id); |
|||
} |
|||
|
|||
/** |
|||
* @param $order_id |
|||
* @return array |
|||
* 首次发货直接获取orderGoods的内容 |
|||
*/ |
|||
public static function firstDelivery($order_id) |
|||
{ |
|||
$unShippedGoods = []; |
|||
$orderGoods = OrderGoods::find()->where(['order_id' => $order_id])->all(); |
|||
foreach ($orderGoods as $k => $v) { |
|||
$unShippedGoods[] = [ |
|||
'id' => $v->id, |
|||
'goods_id' => $v->goods_id, |
|||
'goods_img' => $v->goods_img, |
|||
'goods_name' => $v->goods_name, |
|||
'price' => $v->price, |
|||
'market_price' => $v->market_price, |
|||
'goods_number' => $v->goods_count, |
|||
'lack_number' => $v->goods_count, |
|||
'sku_value' => $v->sku_value, |
|||
]; |
|||
} |
|||
return $unShippedGoods; |
|||
} |
|||
|
|||
/** |
|||
* @param $filter |
|||
* @param $order_id |
|||
* @return array |
|||
* @throws Exception |
|||
* 获取订单已发的商品和未发的商品 |
|||
*/ |
|||
public static function getDeliveryGoodsInfo($filter,$order_id) |
|||
{ |
|||
$unShipped = []; //未发货商品
|
|||
foreach ($filter as $k => $value) { //键名为ordergoods_id,键值为对应的已发货数量
|
|||
$goodsData = self::getOrderGoodsInfo($k); |
|||
if ($value < $goodsData['goods_number']) { //如果已发货数量未达到order_goods里的数量
|
|||
$lack_number = $goodsData['goods_number'] - $value; |
|||
$goodsData['lack_number'] = $lack_number; |
|||
$goodsData['goods_number'] = $lack_number; |
|||
$unShipped[] = $goodsData; |
|||
} |
|||
} |
|||
$shipped = self::getDeliveryInfo($order_id); //已发货商品信息
|
|||
return ['shipped' => $shipped, 'unShipped' => $unShipped]; |
|||
} |
|||
|
|||
/** |
|||
* @param $order_id |
|||
* @return array |
|||
* @throws Exception |
|||
* 通过订单号获取发货信息 |
|||
*/ |
|||
public static function getDeliveryInfo($order_id) |
|||
{ |
|||
$deliveryInfo = []; |
|||
$delivery = Delivery::findAll(['order_id' => $order_id]); |
|||
foreach ($delivery as $k => $value) { |
|||
$expressTemplate = ExpressTemplate::find()->select('name')->where(['id' => $value->shipping_id])->one(); |
|||
$deliveryInfo[$k]['logisticInfo'] = [ |
|||
'exp_name'=> $expressTemplate ? $expressTemplate->name : '', |
|||
'invoice_no'=> $value->invoice_no |
|||
]; //物流公司和运单号
|
|||
$deliveryInfo[$k]['goodsInfo'] = self::getDeliverGoodsInfo($value->id); //获取商品信息
|
|||
} |
|||
return $deliveryInfo; |
|||
} |
|||
|
|||
/** |
|||
* @param $delivery_id |
|||
* @return array |
|||
* @throws Exception |
|||
* 通过获取订单已发货的商品信息 |
|||
*/ |
|||
public static function getDeliverGoodsInfo($delivery_id) |
|||
{ |
|||
$goodsInfo = []; |
|||
$deliveryGoods = DeliveryGoods::find()->where(['delivery_id'=>$delivery_id])->andWhere(['>','goods_number',0])->all(); |
|||
foreach ($deliveryGoods as $value) { |
|||
$goodsData = self::getOrderGoodsInfo($value->order_goods_id); |
|||
$goodsData['delivery_number'] = $value->goods_number; |
|||
$goodsInfo[] = $goodsData; |
|||
} |
|||
return $goodsInfo; |
|||
} |
|||
|
|||
/** |
|||
* @param $orderGoodsId |
|||
* @return array |
|||
* @throws Exception |
|||
* 获取订单商品信息 |
|||
*/ |
|||
private static function getOrderGoodsInfo($orderGoodsId) |
|||
{ |
|||
$orderGoods = OrderGoods::findOne($orderGoodsId); //通过orderGoods_id找到订单商品
|
|||
if ($orderGoods) { |
|||
$goodsData = [ |
|||
'id' => $orderGoods->id, |
|||
'goods_id' => $orderGoods->goods_id, |
|||
'goods_name' => $orderGoods->goods_name, |
|||
'shop_price' => $orderGoods->shop_price, |
|||
'goods_number' => $orderGoods->goods_number, |
|||
'goods_img' => $orderGoods->goods_img, |
|||
'sku_type' => $orderGoods->sku_type, |
|||
]; |
|||
return $goodsData; |
|||
} else { |
|||
throw new Exception('order_goods not found'); |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,37 @@ |
|||
<?php |
|||
|
|||
use yii\db\Migration; |
|||
|
|||
/** |
|||
* Class m191206_024047_create_table_delivery_goods |
|||
*/ |
|||
class m191206_024047_create_table_delivery_goods extends Migration |
|||
{ |
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function safeUp() |
|||
{ |
|||
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB COMMENT="物流商品表"'; |
|||
$this->createTable('ats_delivery_goods', [ |
|||
'id' => $this->primaryKey(), |
|||
'delivery_id' => $this->integer()->notNull()->defaultValue(0)->comment('物流id'), |
|||
'order_goods_id' => $this->integer()->notNull()->defaultValue(0)->comment('订单商品id'), |
|||
'goods_id' => $this->integer()->notNull()->defaultValue(0)->comment('商品id'), |
|||
'goods_name' => $this->string()->notNull()->defaultValue('')->comment('商品名称'), |
|||
'goods_number' => $this->integer()->notNull()->defaultValue(0)->comment('商品数量'), |
|||
'created_at' => $this->integer()->notNull()->defaultValue(0)->comment('创建时间'), |
|||
'updated_at' => $this->integer()->notNull()->defaultValue(0)->comment('更新时间'), |
|||
], $tableOptions); |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function safeDown() |
|||
{ |
|||
$this->dropTable('ats_delivery_goods'); |
|||
return true; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,79 @@ |
|||
<?php |
|||
|
|||
namespace backend\modules\shop\models\ars; |
|||
|
|||
use Yii; |
|||
use yii\behaviors\TimestampBehavior; |
|||
|
|||
/** |
|||
* This is the model class for table "ats_delivery_goods". |
|||
* |
|||
* @property int $id |
|||
* @property int $delivery_id 物流id |
|||
* @property int $order_goods_id 订单商品id |
|||
* @property int $goods_id 商品id |
|||
* @property int $goods_name 商品名称 |
|||
* @property int $goods_number 商品数量 |
|||
* @property int $created_at 创建时间 |
|||
* @property int $updated_at 更新时间 |
|||
*/ |
|||
class DeliveryGoods extends \yii\db\ActiveRecord |
|||
{ |
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public static function tableName() |
|||
{ |
|||
return 'ats_delivery_goods'; |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function rules() |
|||
{ |
|||
return [ |
|||
[['delivery_id', 'order_goods_id', 'goods_id', 'goods_number'], 'integer'], |
|||
[['goods_name'], 'string'], |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function attributeLabels() |
|||
{ |
|||
return [ |
|||
'id' => 'id', |
|||
'delivery_id' => '物流id', |
|||
'order_goods_id' => '订单商品id', |
|||
'goods_id' => '商品id', |
|||
'goods_name' => '商品名称', |
|||
'goods_number' => '商品数量', |
|||
'created_at' => '创建时间', |
|||
'updated_at' => '更新时间', |
|||
]; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* @author linyao |
|||
* @email 602604991@qq.com |
|||
* @created Nov 8, 2019 |
|||
* |
|||
* 行为存储创建时间和更新时间 |
|||
*/ |
|||
public function behaviors() |
|||
{ |
|||
return [ |
|||
[ |
|||
'class' => TimestampBehavior::className(), |
|||
'createdAtAttribute' => 'created_at', |
|||
'updatedAtAttribute' => 'updated_at', |
|||
'value' => function() { |
|||
return time(); |
|||
}, |
|||
], |
|||
]; |
|||
} |
|||
} |
@ -0,0 +1,56 @@ |
|||
<?php |
|||
|
|||
use yii\helpers\Html; |
|||
use yii\bootstrap4\ActiveForm; |
|||
use kartik\tabs\TabsX; |
|||
|
|||
/* @var $this yii\web\View */ |
|||
/* @var $order backend\modules\shop\models\ars\Order */ |
|||
/* @var $delivery backend\modules\shop\models\ars\Delivery */ |
|||
/* @var $form yii\widgets\ActiveForm */ |
|||
/* @var $deliveryGoods */ |
|||
|
|||
$this->title = '订单发货:'. $order->order_sn; |
|||
$this->params['breadcrumbs'][] = ['label' => '订单列表', 'url' => ['index']]; |
|||
$this->params['breadcrumbs'][] = $this->title; |
|||
Yii::$app->params['bsVersion'] = '4.x'; |
|||
?>
|
|||
|
|||
<div class="delivery-form"> |
|||
|
|||
<?php |
|||
$form = ActiveForm::begin(['options' => ['class' => 'container-fluid']]); |
|||
|
|||
echo TabsX::widget([ |
|||
'bordered' => true, |
|||
'items' => [ |
|||
[ |
|||
'label' => '<i class="fas fa-user"></i> 物流信息', |
|||
'content' => $this->render('logistics', [ |
|||
'order' => $order, |
|||
'delivery' => $delivery, |
|||
'form' => $form, |
|||
]), |
|||
], |
|||
[ |
|||
'label' => '<i class="fas fa-ad"></i> 订单商品信息', |
|||
'content' => $this->render('delivery_goods', [ |
|||
'form' => $form, |
|||
'deliveryGoods' => $deliveryGoods, |
|||
]), |
|||
], |
|||
], |
|||
'position' => TabsX::POS_ABOVE, |
|||
'encodeLabels' => false |
|||
]); |
|||
?>
|
|||
|
|||
|
|||
<div class="form-group"> |
|||
<?= Html::submitButton('保存', ['class' => 'btn btn-success']) ?>
|
|||
<?= Html::a('返回', ['index'], ['class' => 'btn btn-info']) ?>
|
|||
</div> |
|||
|
|||
<?php ActiveForm::end(); ?>
|
|||
|
|||
</div> |
@ -0,0 +1,130 @@ |
|||
<?php |
|||
/** |
|||
* Created by PhpStorm. |
|||
* User: Administrator |
|||
* Date: 2018/9/4 |
|||
* Time: 19:59 |
|||
*/ |
|||
?>
|
|||
|
|||
<style> |
|||
.box { |
|||
margin-top: 20px; |
|||
} |
|||
.unShipped-table,.shipped-table { |
|||
margin:15px; |
|||
width:90%; |
|||
padding:5px; |
|||
border-radius: 10px; |
|||
box-shadow:0 4px 30px 2px rgba(223, 225, 230, 0.5) !important; |
|||
} |
|||
</style> |
|||
|
|||
<div> |
|||
<div class="box unShipped-box"> |
|||
<h5>未发货商品</h5> |
|||
<table class="table unShipped-table"> |
|||
<tr> |
|||
<th>商品名称</th> |
|||
<th>商品sku</th> |
|||
<th>还需发货数量</th> |
|||
<th>发货数量</th> |
|||
</tr> |
|||
</table> |
|||
</div> |
|||
<div class="box shipped-box"> |
|||
<h5>已发货商品</h5> |
|||
</div> |
|||
<input type="hidden" id="deliveryGoods" name="deliveryGoods"><!-- 用于保存商品json --> |
|||
</div> |
|||
|
|||
<script src="/js/jquery.js"></script> |
|||
<script> |
|||
//初始化订单商品数据
|
|||
var data = <?= $deliveryGoods ?>;
|
|||
console.log(data); |
|||
function init() { |
|||
var unShipped = data.unShipped; |
|||
showUnShipped(unShipped); |
|||
if(data.shipped){ |
|||
var shipped = data.shipped; |
|||
showShipped(shipped) |
|||
} |
|||
unShipped = JSON.stringify(unShipped); |
|||
$('#deliveryGoods').val(unShipped) |
|||
} |
|||
|
|||
init(); |
|||
|
|||
//显示未发货商品
|
|||
function showUnShipped(unShipped) { |
|||
unShipped.forEach(function (item,index) { |
|||
var tr = "<tr data-index='" + index +"'>" + |
|||
"<td class='goods_name'>" + item.goods_name + "</td>" + |
|||
"<td class='goods_sku'>" + item.sku_value + "</td>" + |
|||
"<td class='lack_number'>" + item.lack_number + "</td>" + |
|||
"<td><input type='text' class='goods_number' value='"+item.lack_number+"' disabled/></td>" + |
|||
"<td>" + |
|||
"<input type='button' class='btn btn-primary' value='编辑' onclick='updateGoods(this)'/>" + |
|||
"<input type='button' class='btn btn-primary' value='保存' onclick='saveGoods(this)' style='display: none' />" + |
|||
"</td>" + |
|||
"</tr>"; |
|||
$('.unShipped-table').append(tr) |
|||
}); |
|||
} |
|||
|
|||
//显示已发货商品
|
|||
function showShipped(shipped) { |
|||
shipped.forEach(function(item,index){ |
|||
var table = ' <table class="table shipped-table">' + |
|||
'<tr>' + |
|||
'<th>商品名称</th>' + |
|||
'<th>商品sku</th>' + |
|||
'<th>发货数量</th>' + |
|||
'</tr>\n' + |
|||
'</table>'; |
|||
var div = document.createElement('div'); |
|||
div.innerText = '运单号:' + item.logisticInfo.invoice_no + '快递公司:'+ item.logisticInfo.exp_name; |
|||
$('.shipped-box').append(div); |
|||
$('.shipped-box').append(table); |
|||
table = $('.shipped-table').eq(index); |
|||
item.goodsInfo.forEach(function (item,index) { |
|||
var tr = "<tr data-index='" + index +"'>" + |
|||
"<td class='goods_name'>" + item.goods_name + "</td>" + |
|||
"<td class='goods_sku'>" + item.sku_type + "</td>" + |
|||
"<td class='goods_number'>" + item.delivery_number + "</td>" + |
|||
"</tr>"; |
|||
$(table).append(tr); |
|||
}); |
|||
}) |
|||
} |
|||
|
|||
//编辑发货数量
|
|||
function updateGoods(ref){ |
|||
$(ref).hide(); |
|||
$(ref).next().show(); |
|||
$(ref).parent().parent().find('.goods_number').removeAttr('disabled') |
|||
} |
|||
|
|||
//保存编辑
|
|||
function saveGoods(ref) { |
|||
if(typeof unShipped =='string'){ |
|||
unShipped = JSON.parse(unShipped) |
|||
} |
|||
var tr = $(ref).parent().parent(); |
|||
tr.find('.goods_number').attr('disabled','disabled'); |
|||
var index = tr.attr('data-index'); |
|||
var number = tr.find('.goods_number').val(); |
|||
if (number < 0) { |
|||
alert('发货数量不能低于0'); |
|||
tr.find('.goods_number').val(0); |
|||
return false; |
|||
} |
|||
unShipped[index].goods_number = number; |
|||
unShipped = JSON.stringify(unShipped); |
|||
$('#deliveryGoods').val(unShipped); |
|||
$(ref).hide(); |
|||
$(ref).prev().show(); |
|||
} |
|||
</script> |
|||
|
@ -0,0 +1,11 @@ |
|||
<div class="logistics"> |
|||
<?= $form->field($delivery, 'shipping_name')->textInput(['maxlength' => true]) ?>
|
|||
|
|||
<?= $form->field($delivery, 'shipping_id')->textInput(['maxlength' => true]) ?>
|
|||
|
|||
<?= $form->field($delivery, 'type')->textInput() ?>
|
|||
|
|||
<?= $form->field($delivery, 'status')->textInput() ?>
|
|||
|
|||
<?= $form->field($delivery, 'decription')->textarea(['rows' => 6]) ?>
|
|||
</div> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue