ww519441258
5 years ago
22 changed files with 644 additions and 428 deletions
-
12api/config/main.php
-
40api/controllers/WxPaymentController.php
-
246api/logic/WxPaymentLogic.php
-
10backend/config/main.php
-
14backend/config/params.php
-
358backend/modules/payment/logic/WxPaymentManager.php
-
8backend/modules/shop/controllers/DeliveryController.php
-
20backend/modules/shop/controllers/OrderController.php
-
69backend/modules/shop/logic/delivery/DeliveryManager.php
-
71backend/modules/shop/logic/payment/WxPaymentManager.php
-
41backend/modules/shop/migrations/m191218_122251_add_column_invoice_sn_in_delivery.php
-
11backend/modules/shop/models/ars/Delivery.php
-
2backend/modules/shop/models/ars/WxPayConfig.php
-
7backend/modules/shop/models/searchs/DeliverySearch.php
-
16backend/modules/shop/models/searchs/OrderSearch.php
-
4backend/modules/shop/views/delivery/_form.php
-
37backend/modules/shop/views/delivery/info.php
-
78backend/modules/shop/views/delivery/logistics.php
-
11backend/modules/shop/views/delivery/view.php
-
11backend/modules/shop/views/order/logistics.php
-
1backend/modules/shop/views/order/refund.php
-
5common/config/params.php
@ -1,4 +1,18 @@ |
|||
<?php |
|||
return [ |
|||
'adminEmail' => 'admin@example.com', |
|||
'logistics' => [ |
|||
'SELF' => '商家配送', |
|||
'shunfeng' => '顺丰速运', |
|||
'suteng' => '速腾快递', |
|||
'shentong' => '申通快递', |
|||
'zhongtong' => '中通快递', |
|||
'yuantong' => '圆通快递', |
|||
'huitong' => '百世快递(原汇通)', |
|||
'yunda' => '韵达快递', |
|||
'yousu' => 'UC优速快递', |
|||
'gnxb' => '邮政小包', |
|||
'youzhengguonei' => '邮政包裹/平邮/挂号信', |
|||
'jingdong' => '京东快递', |
|||
], |
|||
]; |
@ -0,0 +1,358 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace backend\modules\payment\logic; |
|||
|
|||
|
|||
use api\logic\Helper; |
|||
use backend\modules\shop\models\ars\PaymentLog; |
|||
use backend\modules\shop\models\ars\RefundLog; |
|||
use backend\modules\shop\models\ars\WxPayConfig; |
|||
use EasyWeChat\Factory; |
|||
use yii\db\Exception; |
|||
use yii\helpers\Json; |
|||
use yii\web\BadRequestHttpException; |
|||
use yii\web\NotFoundHttpException; |
|||
use Yii; |
|||
|
|||
class WxPaymentManager |
|||
{ |
|||
/*支付类型*/ |
|||
const PAY_TYPE_WEB = 1; |
|||
const PAY_TYPE_MINI_PROGRAM = 2; |
|||
/*支付状态*/ |
|||
const STATUS_PAYMENT_WAITING = 0; |
|||
const STATUS_PAYMENT_SUCCESS = 1; |
|||
/*退款状态*/ |
|||
const STATUS_REFUND_WAIT = 0; //退款待审核
|
|||
const STATUS_REFUND_CONFIRM = 1; //退款待确认
|
|||
const STATUS_REFUND_SUCCESS = 2; //退款成功
|
|||
const STATUS_REFUND_PORTION = 3; //部分退款
|
|||
/*发起支付方式*/ |
|||
const TRADE_TYPE_JS_API = 'JSAPI'; |
|||
|
|||
public $appId; |
|||
public $mchId; |
|||
public $key; |
|||
public $certPath; |
|||
public $keyPath; |
|||
public $notifyUrl; |
|||
public $tradeType; |
|||
public $payType; |
|||
public $app; |
|||
public $order; |
|||
|
|||
/** |
|||
* @param $orderId |
|||
* @param $orderAmount |
|||
* @param $paymentAmount |
|||
* @param $notifyUrl |
|||
* @param $payType |
|||
* @return mixed |
|||
* @throws BadRequestHttpException |
|||
* @throws Exception |
|||
* 微信统一下单 |
|||
*/ |
|||
public function wxPayment($orderId, $orderAmount, $paymentAmount, $notifyUrl, $payType) |
|||
{ |
|||
if (empty($orderId) || empty($orderAmount) ||empty($paymentAmount) || empty($notifyUrl) || empty($payType)) { |
|||
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); |
|||
} |
|||
$this->tradeType = self::TRADE_TYPE_JS_API; |
|||
$this->payType = $payType; |
|||
$this->notifyUrl = $notifyUrl; |
|||
|
|||
$unifyParams = $this->applyPaymentData($orderId, $orderAmount, $paymentAmount, $notifyUrl); |
|||
$result = $this->unify($unifyParams); |
|||
if ($result['return_code'] == 'FAIL') { |
|||
throw new BadRequestHttpException($result['return_msg']); |
|||
} |
|||
if ($result['return_code'] == 'SUCCESS' && $result['return_msg'] == 'OK' && $result['result_code'] == 'FAIL') { |
|||
throw new BadRequestHttpException($result['err_code_des']); |
|||
} |
|||
return Json::decode($this->getBridgeConfig($result['prepay_id']), true); |
|||
} |
|||
|
|||
/** |
|||
* @param $prepayId |
|||
* @return array|string |
|||
*/ |
|||
private function getBridgeConfig($prepayId) |
|||
{ |
|||
$this->initObject(); |
|||
return $this->app->jssdk->bridgeConfig($prepayId); |
|||
} |
|||
|
|||
/** |
|||
* @param string $orderId |
|||
* @param int $orderAmount |
|||
* @param int $paymentAmount |
|||
* @param string $notifyUrl |
|||
* @return array |
|||
* @throws BadRequestHttpException |
|||
* @throws Exception |
|||
* 生成支付参数 |
|||
*/ |
|||
private function applyPaymentData($orderId, $orderAmount, $paymentAmount, $notifyUrl) |
|||
{ |
|||
$this->savePaymentLog($orderId, $orderAmount, $paymentAmount, $notifyUrl); |
|||
|
|||
$params = [ |
|||
'body' => '订单支付', |
|||
'out_trade_no' => $orderId, |
|||
'total_fee' => $paymentAmount, |
|||
'openid' => Yii::$app->user->identity->wx_openid, |
|||
]; |
|||
return $params; |
|||
} |
|||
|
|||
/** |
|||
* @param string $orderId |
|||
* @param int $orderAmount |
|||
* @param int $paymentAmount |
|||
* @param string $notifyUrl |
|||
* @throws BadRequestHttpException |
|||
* @throws Exception |
|||
* 保存支付信息 |
|||
*/ |
|||
private function savePaymentLog($orderId, $orderAmount, $paymentAmount, $notifyUrl) |
|||
{ |
|||
$paymentLog = PaymentLog::findOne(['order_id' => $orderId]); |
|||
if (!$paymentLog) { |
|||
$paymentLog = new PaymentLog(); |
|||
} elseif (!empty($paymentLog->wx_payment_id)) { |
|||
throw new BadRequestHttpException('此订单号也有支付信息,不能重复'); |
|||
} |
|||
$paymentLog->order_id = $orderId; |
|||
$paymentLog->order_amount = $orderAmount; |
|||
$paymentLog->payment_amount = $paymentAmount; |
|||
$paymentLog->notify_url = $this->notifyUrl; |
|||
$paymentLog->type = $this->payType; |
|||
$paymentLog->status = self::STATUS_PAYMENT_WAITING; |
|||
if (!$paymentLog->save()) { |
|||
throw new Exception(Helper::errorMessageStr($paymentLog->errors)); |
|||
} |
|||
} |
|||
|
|||
protected function getApp() |
|||
{ |
|||
$this->initObject(); |
|||
$config = [ |
|||
'app_id' => $this->appId, |
|||
'mch_id' => $this->mchId, |
|||
'key' => $this->key, |
|||
'cert_path' => $this->certPath, |
|||
'key_path' => $this->keyPath, |
|||
'notify_url' => $this->notifyUrl, |
|||
'trade_type' => $this->tradeType, |
|||
'sandbox' => true, // 设置为 false 或注释则关闭沙箱模式
|
|||
]; |
|||
$this->app = Factory::payment($config); |
|||
//判断当前是否为沙箱模式:
|
|||
$this->app->inSandbox(); |
|||
} |
|||
|
|||
/** |
|||
* @var WxPayConfig $wxPayConfig |
|||
*/ |
|||
private function initObject() |
|||
{ |
|||
$path = Yii::getAlias('@backend'); |
|||
$wxPayConfig = WxPayConfig::find()->one(); |
|||
switch ($this->payType) { |
|||
case self::PAY_TYPE_WEB: |
|||
// $wxConfig = WxConfig::find()->one();
|
|||
// $this->appId = trim($wxConfig->appid);
|
|||
break; |
|||
case self::PAY_TYPE_MINI_PROGRAM: |
|||
// $miniProgramConfig = MiniProgramConfig::find()->one();
|
|||
// $this->appId = trim($miniProgramConfig->appid);
|
|||
break; |
|||
} |
|||
$this->mchId = trim($wxPayConfig->mch_id); |
|||
$this->key = trim($wxPayConfig->key); |
|||
$this->certPath = trim($path . $wxPayConfig->cert_path); |
|||
$this->keyPath = trim($path . $wxPayConfig->key_path); |
|||
$this->notifyUrl = Yii::$app->request->hostInfo . '/wx-payment/notify'; |
|||
|
|||
$this->mchId = '1395812402'; |
|||
$this->key = '51CF5EE3B2E35B9843E17E6099325A65'; |
|||
} |
|||
|
|||
/** |
|||
* @param $unifyParams |
|||
* @return mixed |
|||
* 统一下单 |
|||
*/ |
|||
private function unify($unifyParams) |
|||
{ |
|||
$unifyParams['trade_type'] = $this->tradeType; |
|||
$this->getApp(); |
|||
return $this->app->order->unify($unifyParams); |
|||
} |
|||
|
|||
/** |
|||
* @param $data |
|||
* @return bool |
|||
* 支付成功回调验证签名和支付金额 |
|||
*/ |
|||
public function checkSign($data) |
|||
{ |
|||
$this->initObject(); |
|||
$notifySign = $data['sign']; |
|||
unset($data['sign']); |
|||
$sign = $this->_sign($data); |
|||
if ($notifySign == $sign) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @param $arr |
|||
* @return string |
|||
* 微信签名方法 |
|||
*/ |
|||
private function _sign($arr) |
|||
{ |
|||
$arr = array_filter($arr); |
|||
ksort($arr); |
|||
$arr['key'] = $this->key; |
|||
$queryString = http_build_query($arr); |
|||
$queryString = urldecode($queryString); |
|||
return strtoupper(md5($queryString)); |
|||
} |
|||
|
|||
|
|||
/*************************************** Refund ************************************************/ |
|||
/** |
|||
* @param string $orderId |
|||
* @param int $refundAmount |
|||
* @param string $refundAccount |
|||
* @param int $reason |
|||
* @return RefundLog |
|||
* @throws BadRequestHttpException |
|||
* @throws Exception |
|||
* @throws NotFoundHttpException |
|||
* 申请退款 |
|||
*/ |
|||
public function applyRefund($orderId, $refundAmount, $refundAccount, $reason) |
|||
{ |
|||
if (empty($orderId) || empty($refundAmount) || empty($refundAccount) || empty($reason)) { |
|||
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); |
|||
} |
|||
$paymentLog = PaymentLog::findOne(['order_id' => $orderId]); |
|||
if (empty($paymentLog)) { |
|||
throw new NotFoundHttpException('订单支付信息未找到'); |
|||
} |
|||
if (RefundLog::findOne(['order_id' => $orderId, 'status' => self::STATUS_REFUND_WAIT])) { |
|||
throw new BadRequestHttpException('此订单存在等待审核的退款申请'); |
|||
} |
|||
$refundedAmount = RefundLog::find() |
|||
->where(['order_id' => $orderId, 'status' => self::STATUS_PAYMENT_SUCCESS]) |
|||
->sum('refund_amount') ?? 0; |
|||
|
|||
$refundLog = new RefundLog(); |
|||
$refundLog->order_id = $orderId; |
|||
$refundLog->wx_refund_id = Helper::timeRandomNum(3, 'R'); |
|||
$refundLog->reason = $reason; |
|||
$refundLog->order_amount = $paymentLog->payment_amount; |
|||
$refundLog->refund_amount = $refundAmount; |
|||
$refundLog->refunded_amount = $refundedAmount; |
|||
$refundLog->type = $paymentLog->type; |
|||
$refundLog->status = self::STATUS_REFUND_WAIT; |
|||
$refundLog->refund_account = $refundAccount; |
|||
$refundLog->applyed_at = time(); |
|||
if (!$refundLog->save()) { |
|||
throw new Exception(Helper::errorMessageStr($refundLog->errors)); |
|||
} |
|||
return $refundLog; |
|||
} |
|||
|
|||
/** |
|||
* @param string $orderId |
|||
* @param int $refundAmount |
|||
* @param int $operatorId |
|||
* @return array|mixed |
|||
* @throws BadRequestHttpException |
|||
* @throws NotFoundHttpException |
|||
*/ |
|||
public function refund($orderId, $refundAmount, $operatorId) |
|||
{ |
|||
$paymentLog = PaymentLog::findOne(['order_id' => $orderId]); |
|||
if (empty($paymentLog)) { |
|||
throw new NotFoundHttpException('订单支付信息未找到'); |
|||
} |
|||
$refundLog = RefundLog::findOne(['order_id' => $orderId, 'status' => self::STATUS_REFUND_WAIT]); |
|||
if (empty($refundLog)) { |
|||
throw new NotFoundHttpException('订单退款信息未找到'); |
|||
} |
|||
|
|||
$this->executeRefund($paymentLog, $refundLog, $refundAmount); |
|||
return $this->updateRefundInfo($paymentLog, $refundLog, $operatorId); |
|||
} |
|||
|
|||
/** |
|||
* @param PaymentLog $paymentLog |
|||
* @param RefundLog $refundLog |
|||
* @param $refundAmount |
|||
* @throws BadRequestHttpException |
|||
*/ |
|||
private function executeRefund($paymentLog, $refundLog, $refundAmount) |
|||
{ |
|||
/*参数分别为:微信订单号、商户退款单号、订单金额、退款金额、其他参数*/ |
|||
$this->getApp(); |
|||
$config = [ |
|||
'refund_desc' => '退款' |
|||
]; |
|||
$result = $this->app->refund->byTransactionId( |
|||
$paymentLog->wx_payment_id, |
|||
$refundLog->wx_refund_id, |
|||
$paymentLog->payment_amount, |
|||
$refundAmount, |
|||
$config |
|||
); |
|||
Yii::info($result, 'refund_log'); |
|||
|
|||
if ($result['return_code'] == 'FAIL' || $result['return_msg'] != 'OK' || $result['result_code'] == 'FAIL') { |
|||
throw new BadRequestHttpException($result['return_msg']); |
|||
} |
|||
if ($result['err_code_des']) { |
|||
throw new BadRequestHttpException($result['err_code_des']); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @param PaymentLog $paymentLog |
|||
* @param RefundLog $refundLog |
|||
* @param int $operatorId |
|||
* @return array |
|||
*/ |
|||
private function updateRefundInfo($paymentLog, $refundLog, $operatorId) |
|||
{ |
|||
$tra = Yii::$app->db->beginTransaction(); |
|||
try { |
|||
$paymentLog->wx_refund_id = $refundLog->wx_refund_id; |
|||
$paymentLog->refund_account = $refundLog->refund_account; |
|||
$paymentLog->status = $refundLog->refund_amount < $paymentLog->payment_amount ? self::STATUS_REFUND_SUCCESS : self::STATUS_REFUND_PORTION; |
|||
if (!$paymentLog->save()) { |
|||
throw new Exception(Helper::errorMessageStr($paymentLog->errors)); |
|||
} |
|||
|
|||
$refundLog->operator_id = $operatorId; |
|||
$refundLog->status = $refundLog->refund_amount < $paymentLog->payment_amount ? self::STATUS_REFUND_SUCCESS : self::STATUS_REFUND_PORTION; |
|||
$refundLog->finished_at = time(); |
|||
if (!$refundLog->save()) { |
|||
throw new Exception(Helper::errorMessageStr($refundLog->errors)); |
|||
} |
|||
|
|||
$tra->commit(); |
|||
return ['status' => true]; |
|||
} catch (Exception $e) { |
|||
$tra->rollBack(); |
|||
return ['status' => false, 'info' => $e->getMessage()]; |
|||
} |
|||
} |
|||
|
|||
} |
@ -1,71 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace backend\modules\shop\logic\payment; |
|||
|
|||
use api\logic\Helper; |
|||
use api\logic\WxPaymentLogic; |
|||
use backend\modules\shop\models\ars\PaymentLog; |
|||
use backend\modules\shop\models\ars\RefundLog; |
|||
use yii\db\Exception; |
|||
use yii\web\BadRequestHttpException; |
|||
use yii\web\NotFoundHttpException; |
|||
use Yii; |
|||
|
|||
class WxPaymentManager extends WxPaymentLogic |
|||
{ |
|||
/** |
|||
* @param RefundLog $refundLog |
|||
* @param int $operatorId |
|||
* @return array|mixed |
|||
* @throws BadRequestHttpException |
|||
* @throws NotFoundHttpException |
|||
*/ |
|||
public function refund($refundLog, $operatorId) |
|||
{ |
|||
$paymentLog = PaymentLog::findOne(['order_id' => $refundLog->order_id]); |
|||
if (empty($paymentLog)) { |
|||
throw new NotFoundHttpException('订单支付信息未找到'); |
|||
} |
|||
$refundLog = RefundLog::findOne(['order_id' => $orderId, 'status' => self::STATUS_REFUND_WAIT]); |
|||
if (!$refundLog) { |
|||
throw new NotFoundHttpException('订单退款信息未找到'); |
|||
} |
|||
|
|||
/*参数分别为:微信订单号、商户退款单号、订单金额、退款金额、其他参数*/ |
|||
$this->getApp(); |
|||
$config = ['refund_desc' => '退款']; |
|||
$result = $this->app->refund->byTransactionId( |
|||
$paymentLog->wx_refund_id, |
|||
$refundLog->wx_refund_id, |
|||
round($paymentLog->payment_amount * 100), |
|||
round($refundLog->refund_amount * 100), |
|||
$config |
|||
); |
|||
Yii::info($result, 'refund_log'); |
|||
|
|||
if ($result['return_code'] == 'FAIL' || $result['return_msg'] != 'OK' || $result['result_code'] == 'FAIL') { |
|||
throw new BadRequestHttpException($result['return_msg']); |
|||
} |
|||
if ($result['err_code_des']) { |
|||
throw new BadRequestHttpException($result['err_code_des']); |
|||
} |
|||
$tra = Yii::$app->db->beginTransaction(); |
|||
try { |
|||
$paymentLog->status = $refundLog->refund_amount < $paymentLog->payment_amount ? self::STATUS_REFUND_SUCCESS : self::STATUS_REFUND_PORTION; |
|||
if (!$paymentLog->save()) { |
|||
throw new Exception(Helper::errorMessageStr($paymentLog->errors)); |
|||
} |
|||
$refundLog->operator_id = $operatorId; |
|||
$refundLog->status = $refundLog->refund_amount < $paymentLog->payment_amount ? self::STATUS_REFUND_SUCCESS : self::STATUS_REFUND_PORTION; |
|||
$refundLog->finished_at = time(); |
|||
if (!$refundLog->save()) { |
|||
throw new Exception(Helper::errorMessageStr($refundLog->errors)); |
|||
} |
|||
$tra->commit(); |
|||
return ['status' => 'true']; |
|||
} catch (Exception $e) { |
|||
$tra->rollBack(); |
|||
return ['status' => false, 'info' => $e->getMessage()]; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,41 @@ |
|||
<?php |
|||
|
|||
use yii\db\Migration; |
|||
|
|||
/** |
|||
* Class m191218_122251_add_column_invoice_sn_in_delivery |
|||
*/ |
|||
class m191218_122251_add_column_invoice_sn_in_delivery extends Migration |
|||
{ |
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function safeUp() |
|||
{ |
|||
$this->addColumn('ats_delivery', 'invoice_sn', $this->string()->after('shipping_id')->comment('运单号')); |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function safeDown() |
|||
{ |
|||
$this->dropColumn('ats_delivery', 'invoice_sn'); |
|||
return true; |
|||
} |
|||
|
|||
/* |
|||
// Use up()/down() to run migration code without a transaction.
|
|||
public function up() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public function down() |
|||
{ |
|||
echo "m191218_122251_add_column_invoice_sn_in_delivery cannot be reverted.\n"; |
|||
|
|||
return false; |
|||
} |
|||
*/ |
|||
} |
@ -0,0 +1,37 @@ |
|||
<?php |
|||
|
|||
use yii\widgets\DetailView; |
|||
use backend\modules\shop\models\ars\Delivery; |
|||
?>
|
|||
|
|||
<?= |
|||
DetailView::widget([ |
|||
'model' => $model, |
|||
'attributes' => [ |
|||
'id', |
|||
'order_id', |
|||
'shipping_name', |
|||
'shipping_id', |
|||
[ |
|||
'attribute' => 'type', |
|||
'value' => function ($model) { |
|||
return Delivery::dropDown('type', $model->type); |
|||
} |
|||
], |
|||
'status', |
|||
'decription:ntext', |
|||
[ |
|||
'attribute' => 'created_at', |
|||
'value' => function ($model) { |
|||
return date('Y-m-d H:i:s', $model->created_at); |
|||
} |
|||
], |
|||
[ |
|||
'attribute' => 'updated_at', |
|||
'value' => function ($model) { |
|||
return date('Y-m-d H:i:s', $model->updated_at); |
|||
} |
|||
], |
|||
], |
|||
]); |
|||
?>
|
@ -1,37 +1,51 @@ |
|||
<?php |
|||
|
|||
use yii\helpers\Html; |
|||
use yii\widgets\DetailView; |
|||
use backend\modules\shop\models\ars\Delivery; |
|||
?>
|
|||
|
|||
<?= |
|||
DetailView::widget([ |
|||
'model' => $model, |
|||
'attributes' => [ |
|||
'id', |
|||
'order_id', |
|||
'shipping_name', |
|||
'shipping_id', |
|||
[ |
|||
'attribute' => 'type', |
|||
'value' => function ($model) { |
|||
return Delivery::dropDown('type', $model->type); |
|||
} |
|||
], |
|||
'status', |
|||
'decription:ntext', |
|||
[ |
|||
'attribute' => 'created_at', |
|||
'value' => function ($model) { |
|||
return date('Y-m-d H:i:s', $model->created_at); |
|||
} |
|||
], |
|||
[ |
|||
'attribute' => 'updated_at', |
|||
'value' => function ($model) { |
|||
return date('Y-m-d H:i:s', $model->updated_at); |
|||
} |
|||
], |
|||
], |
|||
]); |
|||
/* @var $this yii\web\View */ |
|||
/* @var $model common\models\ars\Delivery */ |
|||
/* @var $logistics*/ |
|||
|
|||
?>
|
|||
|
|||
<p> |
|||
<?= Html::a('返回发货列表', ['index'], ['class' => 'btn btn-success']) ?>
|
|||
</p> |
|||
|
|||
<div class="delivery-view"> |
|||
|
|||
<div> |
|||
<label for="">物流单位:</label> |
|||
<?= isset($logistics->expTextName) ? $logistics->expTextName : ''?>
|
|||
</div> |
|||
|
|||
<div> |
|||
<label for="">运单号:</label> |
|||
<?= isset($logistics->mailNo) ? $logistics->mailNo : ''?>
|
|||
</div> |
|||
|
|||
<div> |
|||
<label for="">物流电话:</label> |
|||
<?= isset($logistics->tel) ? $logistics->tel : ''?>
|
|||
</div> |
|||
|
|||
<div> |
|||
<label for="">更新时间:</label> |
|||
<?= isset($logistics->updateStr) ? $logistics->updateStr : '' ?>
|
|||
</div> |
|||
|
|||
<div style="margin-top:20px"> |
|||
<?php |
|||
if (isset($logistics->data)) { |
|||
foreach ($logistics->data as $value) { |
|||
echo '<div style="margin:20px 0">' . |
|||
"<div> $value->time </div>" . |
|||
"<div> $value->context </div>" . |
|||
'</div>'; |
|||
} |
|||
} |
|||
?>
|
|||
</div> |
|||
|
|||
</div> |
@ -1,9 +1,14 @@ |
|||
<?php |
|||
/** |
|||
* @var \backend\modules\shop\models\ars\Delivery $delivery |
|||
*/ |
|||
?>
|
|||
|
|||
<div class="logistics"> |
|||
<?= $form->field($delivery, 'shipping_name')->textInput(['maxlength' => true]) ?>
|
|||
|
|||
<?= $form->field($delivery, 'shipping_id')->textInput(['maxlength' => true]) ?>
|
|||
<?= $form->field($delivery, 'shipping_id')->dropDownList(Yii::$app->params['logistics']) ?>
|
|||
|
|||
<?= $form->field($delivery, 'status')->textInput() ?>
|
|||
<?= $form->field($delivery, 'invoice_sn')->textInput(['maxlength' => true]) ?>
|
|||
|
|||
<?= $form->field($delivery, 'decription')->textarea(['rows' => 6]) ?>
|
|||
</div> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue