|
|
@@ -8,10 +8,18 @@
|
|
|
|
|
|
namespace frontendApi\modules\v1\controllers;
|
|
|
|
|
|
+use common\helpers\Cache;
|
|
|
use common\helpers\Date;
|
|
|
+use common\helpers\DingTalk;
|
|
|
use common\helpers\Form;
|
|
|
+use common\helpers\LoggerTool;
|
|
|
+use common\helpers\Logistics;
|
|
|
+use common\helpers\Tool;
|
|
|
use common\helpers\user\Info;
|
|
|
+use common\models\ApproachOrder;
|
|
|
+use common\models\ApproachOrderGoods;
|
|
|
use common\models\DecOrder;
|
|
|
+use common\models\forms\ApproachOrderForm;
|
|
|
use common\models\forms\DeclarationForm;
|
|
|
use common\models\forms\OrderForm;
|
|
|
use common\models\Order;
|
|
|
@@ -22,10 +30,17 @@ use common\models\ShopGoods;
|
|
|
use common\models\User;
|
|
|
use common\models\UserBonus;
|
|
|
use common\models\UserWallet;
|
|
|
+use Yii;
|
|
|
+use yii\data\Pagination;
|
|
|
+use yii\db\Query;
|
|
|
+use yii\web\HttpException;
|
|
|
|
|
|
class ShopController extends BaseController {
|
|
|
+
|
|
|
public $modelClass = DecOrder::class;
|
|
|
|
|
|
+ const TRANSACTION_TYPE_PAYMENT = 'payment';
|
|
|
+
|
|
|
/**
|
|
|
* 商品列表
|
|
|
* @return mixed
|
|
|
@@ -45,6 +60,7 @@ class ShopController extends BaseController {
|
|
|
]);
|
|
|
foreach ($data['list'] as $key => $value) {
|
|
|
$data['list'][$key]['DISCOUNT'] = $value['SELL_DISCOUNT']*100;
|
|
|
+ $data['list'][$key]['CATE'] = ShopGoods::GOODS_TYPE[$value['CATE_ID']]['name'] ?? '';
|
|
|
}
|
|
|
return static::notice($data);
|
|
|
}
|
|
|
@@ -146,6 +162,40 @@ class ShopController extends BaseController {
|
|
|
return static::notice($data);
|
|
|
}
|
|
|
|
|
|
+// /**
|
|
|
+// * 我的订单
|
|
|
+// * @return mixed
|
|
|
+// * @throws \yii\web\HttpException
|
|
|
+// */
|
|
|
+// public function actionOrderList() {
|
|
|
+// $uname = Info::getUserNameByUserId(\Yii::$app->user->id);
|
|
|
+// $condition = " AND IS_DELETE=0 AND ORDER_TYPE='FX' AND (USER_ID=:USER_ID OR CREATE_USER='$uname')";
|
|
|
+// $params[':USER_ID'] = \Yii::$app->user->id;
|
|
|
+// $data = Order::lists($condition, $params, [
|
|
|
+// 'select' => 'O.*,U.REAL_NAME,OG.*',
|
|
|
+// 'orderBy' => 'O.CREATED_AT DESC',
|
|
|
+// 'from' => Order::tableName() . ' AS O',
|
|
|
+// 'join' => [
|
|
|
+// ['LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID'],
|
|
|
+// ['LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN'],
|
|
|
+// ],
|
|
|
+// ]);
|
|
|
+// foreach ($data['list'] as $key => $value) {
|
|
|
+// if($value['ORDER_TYPE']=='ZC'){
|
|
|
+// $data['list'][$key]['ORDER_TYPE'] = '首单';
|
|
|
+// }else{
|
|
|
+//// $data['list'][$key]['ORDER_TYPE'] = in_array($value['PAY_TYPE'], ['cash', 'paystack']) ? '复消': '积分';
|
|
|
+// $data['list'][$key]['ORDER_TYPE'] = '复消';
|
|
|
+// }
|
|
|
+// //$data['list'][$key]['PROVINCE_NAME'] = $value['PROVINCE'] ? Region::getCnName($value['PROVINCE']) : '';
|
|
|
+// //$data['list'][$key]['CITY_NAME'] = $value['CITY'] ? Region::getCnName($value['CITY']) : '';
|
|
|
+// //$data['list'][$key]['COUNTY_NAME'] = $value['COUNTY'] ? Region::getCnName($value['COUNTY']) : '';
|
|
|
+// $data['list'][$key]['PAY_AT'] = Date::convert($value['PAY_AT'],'Y-m-d H:i:s');
|
|
|
+// $data['list'][$key]['PAY_TYPE'] = $value['PAY_TYPE'] == 'cash' ? '消费点数' : ($value['PAY_TYPE'] == 'exchange' ? '兑换点数' : '复消点数');
|
|
|
+// }
|
|
|
+// return static::notice($data);
|
|
|
+// }
|
|
|
+
|
|
|
/**
|
|
|
* 我的订单
|
|
|
* @return mixed
|
|
|
@@ -153,31 +203,51 @@ class ShopController extends BaseController {
|
|
|
*/
|
|
|
public function actionOrderList() {
|
|
|
$uname = Info::getUserNameByUserId(\Yii::$app->user->id);
|
|
|
- $condition = " AND IS_DELETE=0 AND ORDER_TYPE='FX' AND (USER_ID=:USER_ID OR CREATE_USER='$uname')";
|
|
|
+ $condition = " O.IS_DELETE = 0 AND O.ORDER_TYPE='FX' AND (O.USER_ID=:USER_ID OR O.CREATE_USER='$uname')";
|
|
|
$params[':USER_ID'] = \Yii::$app->user->id;
|
|
|
- $data = Order::lists($condition, $params, [
|
|
|
- 'select' => 'O.*,U.REAL_NAME,OG.*',
|
|
|
- 'orderBy' => 'O.CREATED_AT DESC',
|
|
|
- 'from' => Order::tableName() . ' AS O',
|
|
|
- 'join' => [
|
|
|
- ['LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID'],
|
|
|
- ['LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN'],
|
|
|
- ],
|
|
|
- ]);
|
|
|
+ $orderQuery = Order::find()
|
|
|
+ ->alias('O')
|
|
|
+ ->where($condition, $params)
|
|
|
+ ->select('O.*,U.REAL_NAME,OG.REAL_PRICE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV,OG.ORDER_SN,OG.GOODS_ID')
|
|
|
+ ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
|
|
|
+ ->join('LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
|
|
|
+ ->orderBy('O.CREATED_AT DESC');
|
|
|
+
|
|
|
+ // 订单中间表只查询待支付和支付失败的订单
|
|
|
+ $params[':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value']; // 待支付
|
|
|
+ $params[':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value']; // 支付失败
|
|
|
+ $orderStandardQuery = ApproachOrder::find()
|
|
|
+ ->alias('O')
|
|
|
+ ->where($condition . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $params)
|
|
|
+ ->select('O.*,U.REAL_NAME,OG.REAL_PRICE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV,OG.ORDER_SN,OG.GOODS_ID')
|
|
|
+ ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
|
|
|
+ ->join('LEFT JOIN', ApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
|
|
|
+ ->orderBy('O.CREATED_AT DESC');
|
|
|
+
|
|
|
+ $queryAll = $orderQuery->union($orderStandardQuery, true);
|
|
|
+ $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]);
|
|
|
+
|
|
|
+ $totalCount = $query->count();
|
|
|
+ $pagination = new Pagination(['totalCount' => $totalCount, 'pageSize' => \Yii::$app->request->get('pageSize')]);
|
|
|
+ $lists = $query->offset($pagination->offset)->limit($pagination->limit)->all();
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'list' => $lists,
|
|
|
+ 'currentPage'=>$pagination->page,
|
|
|
+ 'totalPages'=>$pagination->pageCount,
|
|
|
+ 'startNum' => $pagination->page * $pagination->pageSize + 1,
|
|
|
+ 'totalCount' => $pagination->totalCount,
|
|
|
+ 'pageSize' => $pagination->pageSize,
|
|
|
+ ];
|
|
|
+
|
|
|
foreach ($data['list'] as $key => $value) {
|
|
|
- if($value['ORDER_TYPE']=='ZC'){
|
|
|
- $data['list'][$key]['ORDER_TYPE'] = '首单';
|
|
|
- }else{
|
|
|
-// $data['list'][$key]['ORDER_TYPE'] = in_array($value['PAY_TYPE'], ['cash', 'paystack']) ? '复消': '积分';
|
|
|
- $data['list'][$key]['ORDER_TYPE'] = '复消';
|
|
|
- }
|
|
|
- //$data['list'][$key]['PROVINCE_NAME'] = $value['PROVINCE'] ? Region::getCnName($value['PROVINCE']) : '';
|
|
|
- //$data['list'][$key]['CITY_NAME'] = $value['CITY'] ? Region::getCnName($value['CITY']) : '';
|
|
|
- //$data['list'][$key]['COUNTY_NAME'] = $value['COUNTY'] ? Region::getCnName($value['COUNTY']) : '';
|
|
|
- $data['list'][$key]['PAY_AT'] = Date::convert($value['PAY_AT'],'Y-m-d H:i:s');
|
|
|
- $data['list'][$key]['PAY_TYPE'] = $value['PAY_TYPE'] == 'cash' ? '消费点数' : ($value['PAY_TYPE'] == 'exchange' ? '兑换点数' : '复消点数');
|
|
|
+ $data['list'][$key]['ORDER_TYPE'] = $value['ORDER_TYPE'] == 'ZC' ? '首单' : '复消';
|
|
|
+ $data['list'][$key]['PAY_AT'] = $value['PAY_AT'] ? Date::convert($value['PAY_AT'],'Y-m-d H:i:s') : '';
|
|
|
+ $data['list'][$key]['PAY_TYPE'] = ShopGoods::payTypes()[$value['PAY_TYPE']]['name'] ?? '';
|
|
|
+ $data['list'][$key]['STATUS'] = \Yii::$app->params['orderStatus'][$value['STATUS']]['label'] ?? '';
|
|
|
}
|
|
|
- return static::notice($data);
|
|
|
+
|
|
|
+ return $data;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -237,6 +307,237 @@ class ShopController extends BaseController {
|
|
|
return static::notice(Form::formatErrorsForApi($formModel->getErrors()),400);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ return static::notice('无效请求');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 确认订单
|
|
|
+ */
|
|
|
+ public function actionSureApproachOrder(){
|
|
|
+ if (\Yii::$app->request->isPost) {
|
|
|
+ $formModel = new ApproachOrderForm();
|
|
|
+ $formModel->scenario = 'userOrder';
|
|
|
+ $formModel->remark = '复销备注';
|
|
|
+ $post = \Yii::$app->request->post();
|
|
|
+ $post['type'] = DeclarationForm::TYPE_FX;
|
|
|
+ if ($formModel->load($post, '') && $order = $formModel->add()) {
|
|
|
+ return static::notice($order);
|
|
|
+ } else {
|
|
|
+ return static::notice(Form::formatErrorsForApi($formModel->getErrors()),400);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return static::notice('无效请求');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * iPay88支付成功的webhook.
|
|
|
+ * @throws HttpException
|
|
|
+ * @throws \Exception
|
|
|
+ */
|
|
|
+ public function actionVerifyApproachOrder() {
|
|
|
+ // iPay88支付成功的webhook.
|
|
|
+ $rawPostData = file_get_contents('php://input');
|
|
|
+ LoggerTool::notice(['actionVerifyApproachOrder', $rawPostData]);
|
|
|
+ $data = [];
|
|
|
+ if (strlen($rawPostData) > 0) {
|
|
|
+ $rawPostArray = explode('&', $rawPostData);
|
|
|
+ foreach ($rawPostArray as $raw) {
|
|
|
+ $raw = explode('=', $raw);
|
|
|
+ if (count($raw) == 2)
|
|
|
+ $data[$raw[0]] = urldecode($raw[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 支付webhook回调日志
|
|
|
+ Tool::approachOrderCall($data);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 订单状态
|
|
|
+ $orderStatus = ($data['Status'] == '1') ? \Yii::$app->params['orderStatus']['paid']['value'] : \Yii::$app->params['orderStatus']['failPaid']['value'];
|
|
|
+
|
|
|
+ $oderSn = $data['RefNo'] ?? '';
|
|
|
+
|
|
|
+ $formModel = new ApproachOrderForm();
|
|
|
+ $formModel->scenario = 'verifyPay';
|
|
|
+ $load = [
|
|
|
+ 'sn' => $oderSn,
|
|
|
+ 'scenario' => 'verifyPay',
|
|
|
+ 'status' => $orderStatus,
|
|
|
+ 'note' => [
|
|
|
+ 'MerchantCode' => $data['MerchantCode'],
|
|
|
+ 'PaymentId' => $data['PaymentId'],
|
|
|
+ 'status' => $data['Status'],
|
|
|
+ 'Signature' => $data['Signature'],
|
|
|
+ 'Currency' => $data['Currency'],
|
|
|
+ 'Amount' => $data['Amount'],
|
|
|
+ 'TransId' => $data['TransId'],
|
|
|
+ 'TranDate' => $data['TranDate'],
|
|
|
+ 'BankMID' => $data['BankMID'],
|
|
|
+ 'CCNo' => $data['CCNo'],
|
|
|
+
|
|
|
+ ],
|
|
|
+ ];
|
|
|
+
|
|
|
+ if ($formModel->load($load, '') && $result = $formModel->verifyPayOnline()) {
|
|
|
+ LoggerTool::info($result);
|
|
|
+
|
|
|
+ return http_response_code(200);
|
|
|
+ } else {
|
|
|
+ LoggerTool::error(Form::formatErrorsForApi($formModel->getErrors()));
|
|
|
+ return http_response_code(500);
|
|
|
+ }
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ LoggerTool::error(sprintf('actionVerifyApproachOrderError: File[%s], Line:[%s], Message[%s]', $e->getFile(), $e->getLine(), $e->getMessage()));
|
|
|
+ return http_response_code(500);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除准订单
|
|
|
+ */
|
|
|
+ public function actionDeleteApproachOrder()
|
|
|
+ {
|
|
|
+ $orderSn = \Yii::$app->request->post('orderSn');
|
|
|
+ // 删除订单中间表
|
|
|
+ ApproachOrder::deleteAll('SN = :SN', [':SN' => $orderSn]);
|
|
|
+ // 删除订单商品中间表
|
|
|
+ ApproachOrderGoods::deleteAll('ORDER_SN = :ORDER_SN', [':ORDER_SN' => $orderSn]);
|
|
|
+
|
|
|
+ return static::notice('');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * iPay88支付
|
|
|
+ * @return mixed
|
|
|
+ * @throws HttpException
|
|
|
+ */
|
|
|
+ public function actionIPay88()
|
|
|
+ {
|
|
|
+ // 订单ID
|
|
|
+ $paymentParams['RefNo'] = \Yii::$app->request->post('RefNo');
|
|
|
+ // 订单金额,元=>分
|
|
|
+ $money = \Yii::$app->request->post('Amount');
|
|
|
+ // 马来币汇率
|
|
|
+ $exchangeRateMYR = floatval(Cache::getSystemConfig()['exchangeRateMYR']['VALUE'] ?? 0);
|
|
|
+ // 计算马来币
|
|
|
+ $amount = number_format(round($money * $exchangeRateMYR), 2, '.', '');
|
|
|
+// $amount = number_format(1, 2, '.', ''); // TODO: 测试
|
|
|
+ $paymentParams['Amount'] = str_replace('.', '', $amount);
|
|
|
+ // (Optional) (int)
|
|
|
+ $paymentParams['PaymentId'] = '182'; // 2=信用卡 182=银联
|
|
|
+ // Product description. (length 100)
|
|
|
+ $paymentParams['ProdDesc'] = 'Pay for sales';
|
|
|
+ // Customer name. (length 100)
|
|
|
+ $paymentParams['UserName'] = 'MY32';
|
|
|
+ $paymentParams['SignatureType'] = 'SHA256';
|
|
|
+ // Customer email. (length 100)
|
|
|
+ $paymentParams['UserEmail'] = 'ek_dummy25@elken.com';
|
|
|
+ // Customer contact. (length 20)
|
|
|
+ $paymentParams['UserContact'] = '60172249692';
|
|
|
+
|
|
|
+ // (Optional) Merchant remarks. (length 100)
|
|
|
+ //$paymentParams['Remark'] = 'Here is the description';
|
|
|
+ //merchantkey + merchantcode+ reference Number + amount in cent + currency_code
|
|
|
+ $paymentFields = \Yii::$app->iPay88->getPaymentFields($paymentParams, self::TRANSACTION_TYPE_PAYMENT);
|
|
|
+
|
|
|
+ $transactionUrl = \Yii::$app->iPay88->getTransactionUrl(self::TRANSACTION_TYPE_PAYMENT);
|
|
|
+ $paymentFields['Amount'] = $amount;
|
|
|
+ $res = [
|
|
|
+ 'paymentFields' => $paymentFields,
|
|
|
+ 'transactionUrl' => $transactionUrl,
|
|
|
+ ];
|
|
|
+
|
|
|
+ return static::notice($res);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 推送订单到wst仓储系统
|
|
|
+ * @throws HttpException
|
|
|
+ * @throws \Exception
|
|
|
+ */
|
|
|
+ public function actionLogistics()
|
|
|
+ {
|
|
|
+ $orderSn = \Yii::$app->request->get('sn');
|
|
|
+ $order = Order::find()
|
|
|
+ ->where('SN=:ORDER_SN', [':ORDER_SN' => $orderSn])
|
|
|
+ ->asArray()
|
|
|
+ ->one();
|
|
|
+
|
|
|
+ if (!$order) {
|
|
|
+ return static::notice('订单【' . $orderSn . '】不存在');
|
|
|
+ }
|
|
|
+ if ($order['SEND_AT'] > 0) {
|
|
|
+ return static::notice('订单【' . $orderSn . '】不可重复推送');
|
|
|
+ }
|
|
|
+
|
|
|
+ $logistics = new Logistics();
|
|
|
+ $response = $logistics->createOrder($order);
|
|
|
+ LoggerTool::info(['actionLogistics', $response]);
|
|
|
+ if ($response['success'] == 1) {
|
|
|
+ // 更新db中订单推送成功状态
|
|
|
+ if (Order::updateAll(['SEND_AT' => time()], 'SN=:SN', [':SN' => $orderSn])) {
|
|
|
+ return static::notice($response);
|
|
|
+ } else {
|
|
|
+ return static::notice($orderSn . ' 推送wst系统成功, 更新状态失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return static::notice($orderSn . ' 推送wst系统失败');
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * @throws HttpException
|
|
|
+ * @throws \Exception
|
|
|
+ */
|
|
|
+ public function actionLogisticsAuto()
|
|
|
+ {
|
|
|
+ $createdAtStart = strtotime('yesterday');
|
|
|
+ $createdAtEnd = strtotime(date('Y-m-d')) - 1;
|
|
|
+ // 早5点推送,前一天0-24点的订单
|
|
|
+ $orderList = Order::find()
|
|
|
+ ->where(
|
|
|
+ '(CREATED_AT BETWEEN :CREATED_AT_START AND :CREATED_AT_END) AND STATUS=:STATUS AND SEND_AT=:SEND_AT AND PAY_TYPE=:PAY_TYPE',
|
|
|
+ [
|
|
|
+ ':CREATED_AT_START' => $createdAtStart,
|
|
|
+ ':CREATED_AT_END' => $createdAtEnd,
|
|
|
+ ':STATUS' => \Yii::$app->params['orderStatus']['paid']['value'],
|
|
|
+ ':SEND_AT' => 0,
|
|
|
+ 'PAY_TYPE' => 'online',
|
|
|
+ ]
|
|
|
+ )
|
|
|
+ ->asArray()
|
|
|
+ ->all();
|
|
|
+
|
|
|
+ $orderSnSuccess = [];
|
|
|
+ $orderSnFailed = [];
|
|
|
+ $logistics = new Logistics();
|
|
|
+ foreach ($orderList as $order) {
|
|
|
+ // 发送wst仓库系统
|
|
|
+ $response = $logistics->createOrder($order);
|
|
|
+ LoggerTool::warning($response);
|
|
|
+ if ($response['success'] == 1) {
|
|
|
+ // 写入mongo
|
|
|
+ Tool::wstOrderCall($response['data']);
|
|
|
+ $orderSnSuccess[] = $order['SN'];
|
|
|
+ } else {
|
|
|
+ $orderSnFailed[] = $order['SN'];
|
|
|
+ }
|
|
|
+
|
|
|
+ $orderSnSuccess[] = $response;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 更新db中订单推送成功状态
|
|
|
+ if (count($orderSnSuccess) > 0) {
|
|
|
+ Order::updateAll(['SEND_AT' => time()], 'SN IN (:SN)', [':SN' => implode("', '", $orderSnSuccess)]);
|
|
|
+ }
|
|
|
+ if (count($orderSnFailed) > 0) {
|
|
|
+ // 发送预警通知
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return static::notice(sprintf('wstLogisticsAutoSend success order count{%d}, orderSN[%s]; failed count{%d}, orderSN[%s]', count($orderSnSuccess), implode(', ', $orderSnSuccess), count($orderSnFailed), implode(', ', $orderSnFailed)));
|
|
|
+ }
|
|
|
}
|