| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- <?php
- namespace addons\QiDingDong\common\service;
- use addons\QiDingDong\common\enums\QiDingDongEnums;
- use addons\QiDingDong\common\expand\sdk\qidingdong\src\model\CreateOrderModel;
- use addons\QiDingDong\common\expand\sdk\qidingdong\src\model\OrderGoodsItemModel;
- use addons\QiDingDong\common\expand\sdk\qidingdong\src\model\ShippingFeeModel;
- use addons\QiDingDong\common\expand\sdk\qidingdong\src\request\CreateOrderRequest;
- use addons\QiDingDong\common\expand\sdk\qidingdong\src\request\ShippingFeeRequest;
- use addons\QiDingDong\common\helper\RequestHelper;
- use addons\QiDingDong\common\models\QiDingDongEvent;
- use addons\QiDingDong\common\models\QiDingDongGoods;
- use addons\QiDingDong\common\models\QiDingDongGoodsAttr;
- use addons\QiDingDong\common\models\QiDingDongOrder;
- use addons\QiDingDong\common\models\QiDingDongRegion;
- use common\enums\AddonsEnum;
- use common\enums\ShippingTypeEnum;
- use common\enums\StatusEnum;
- use common\helpers\FormatHelper;
- use common\models\common\Express;
- use common\models\mall\Mall;
- use common\models\order\Order;
- use common\models\order\OrderExpress;
- use common\models\user\User;
- use yii\helpers\Json;
- class OrderService
- {
- public function page(int $mall_id, array $params)
- {
- $where = [
- ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]
- ];
- if (!empty($params['order_no'])) {
- $where[] = ['like', 'order_no', $params['order_no']];
- }
- if (!empty($params['third_order_no'])) {
- $where[] = ['like', 'third_order_no', $params['third_order_no']];
- }
- $is_master = SettingService::isMasterMall($mall_id);
- if (!$is_master) {
- $where[] = ['mall_id' => $mall_id];
- } elseif (!empty($params['keyword'])) {
- $mIds = Mall::find()->where(['or', ['like', 'id', $params['keyword']], ['like', 'name', $params['keyword']]])
- ->select('id')->column();
- if (empty($mIds)) return [];
- $where[] = ['mall_id' => $mIds];
- }
- if (!empty($params['member'])) {
- $query = User::find();
- if (!$is_master) $query->where(['mall_id' => $mall_id]);
- $uids = $query->andWhere(['or', ['like', 'id', $params['member']], ['like', 'mobile', $params['member']], ['like', 'nickname', $params['member']]])
- ->andWhere(['status' => StatusEnum::ENABLED])
- ->select('id')->column();
- if (empty($uids)) return [];
- $where[] = ['user_id' => $uids];
- }
- $ret = QiDingDongOrder::listPage([
- 'where' => $where,
- 'order' => 'id desc',
- 'limit' => $params['limit'] ?? '',
- 'with' => ['order' => function($query) {
- $query->with(['detail']);
- }, 'mall']
- ]);
- if (!empty(QiDingDongOrder::getStaticError())) return QiDingDongOrder::getStaticError();
- if (!empty($ret['list'])) {
- foreach ($ret['list'] as &$item) {
- $item['mall']['logo'] = MallService::getLogo($item['mall_id']);
- }
- }
- return $ret;
- }
- /**
- * @param array $order
- * @param int $a_order_id
- * @return bool
- */
- public function create(array $order, int $a_order_id = 0)
- {
- try {
- $goods_ids = array_column($order['detail'], 'goods_id');
- $list = QiDingDongGoods::lists([
- 'where' => [
- ['goods_id' => $goods_ids],
- ['mall_id' => $order['mall_id']]
- ],
- 'index' => 'goods_id',
- 'select'=> 'goods_id, third_goods_id'
- ]);
- $order_detail_ids = [];
- if (!empty($list)) {
- $goods = [];
- if (!empty($a_order_id)) {
- $orderModel = QiDingDongOrder::findOne(['id' => $a_order_id]);
- } else {
- $orderModel = QiDingDongOrder::findOne(['order_id' => $order['id']]);
- if (empty($orderModel)) $orderModel = new QiDingDongOrder();
- }
- $is_d = true;
- $region = QiDingDongRegion::findOne(['local_id' => $order['area']]);
- if (empty($region)) {
- $is_d = false;
- $region = QiDingDongRegion::findOne(['local_id' => $order['city']]);
- }
- $consumer_amount = 0;
- $consumer_ship_amount = 0;
- foreach ($order['detail'] as $item) {
- if (!empty($list[$item['goods_id']])) {
- $specItem = QiDingDongGoodsAttr::findOne(['goods_attr_id' => $item['goods_attr_id']]);
- // 取运费
- $shipContentModel = RequestHelper::contentModelInstance($order['mall_id']);
- $shipContentModel->content->data = new ShippingFeeModel();
- $shipContentModel->content->data->goods_id = $list[$item['goods_id']]['third_goods_id'];
- $shipContentModel->content->data->spec_id = $specItem->third_spec_id;
- $shipContentModel->content->data->province = $region->province_id;
- $shipContentModel->content->data->city = $region->city_id;
- $shipContentModel->content->data->area = $is_d ? $region->id : $region->district_id;
- $shipContentModel->content->data->num = $item['num'];
- $shipContentModel->content->data->yf_mode = StatusEnum::ENABLED;
- $shipContentModel->content->data->device = QiDingDongEnums::REQUEST_PARAMS_DEVICE;
- $req = new ShippingFeeRequest();
- $res = RequestHelper::send($req, RequestHelper::enCrypto($shipContentModel, $order['mall_id']), $order['mall_id']);
- if (is_array($res)) {
- $tGoods = new OrderGoodsItemModel();
- $tGoods->goods_id = $list[$item['goods_id']]['third_goods_id'];
- $tGoods->spec_id = $specItem->third_spec_id; // 商品规格ID
- $tGoods->num = $item['num'];
- $tGoods->yf_mode = StatusEnum::ENABLED; // 运输方式 2.4接口获取的code
- $tGoods->ship_price = $res['ship_price']; // 运费-- 运费计算接口获取 单位:分
- $tGoods->total_ship_price = $res['total_ship_price']; // 总运费-- 运费计算接口获取 单位:分
- $tGoods->basic_ship_price = $res['basic_ship_price']; // 基础运费-- 运费计算接口获取 单位:分
- $tGoods->goods_price = (int) bcmul($specItem->third_price, 100, 0); // 商品单价 (单位:分)
- $tGoods->ent_id = $res['ent_id'] ?? '';
- $order_detail_ids[] = $item['id'];
- $goods[] = $tGoods;
- $orderModel->req_success = 100;
- $consumer_amount += (int) bcmul($tGoods->goods_price, $item['num']);
- $consumer_ship_amount += $tGoods->ship_price;
- } else {
- $orderModel->req_success = StatusEnum::ENABLED;
- }
- $orderModel->last_resp = var_export($res, true);
- }
- }
- if (!empty($goods)) {
- // 如果失败了 这一行需要去掉
- $goods_price = round(bcmul(bcmul($consumer_amount, MallService::rate($order['mall_id']), 2), 0.01, 3), 2);
- $consumer_ship_amount = bcmul($consumer_ship_amount, 0.01, 2);
- $total_price = bcadd($goods_price, $consumer_ship_amount, 2);
- $balanceLogModel = (new FundService())->create([
- 'mall_id' => $order['mall_id'],
- 'amount' => $total_price,
- 'remark' => "来自订单号为[{$order['order_no']}]的购物消费,其中商品金额为[$goods_price],运费金额为[$consumer_ship_amount]",
- 'type' => QiDingDongEnums::BALANCE_LOG_TYPE_CONSUMER,
- 'direction' => QiDingDongEnums::BALANCE_DIRECTION_OUT,
- 'order_no' => $order['order_no'],
- 'addons' => AddonsEnum::ADDONS_NAME_QI_DING_DONG,
- ]);
- if (!is_string($balanceLogModel)) {
- $contentModel = RequestHelper::contentModelInstance($order['mall_id']);
- $contentModel->content->data = new CreateOrderModel();
- $contentModel->content->data->phone = $order['mobile'];
- $contentModel->content->data->consignee = "{$order['region_name']}{$order['address']}";
- $contentModel->content->data->province = $region->province_id; // ID要相通
- $contentModel->content->data->city = $region->city_id;
- $contentModel->content->data->area = $region->district_id;
- $contentModel->content->data->buyer_name = $order['receiver_name'];
- $contentModel->content->data->trade_no = $order['order_no'];
- $contentModel->content->data->goods = $goods;
- $contentModel->content->data->device = QiDingDongEnums::REQUEST_PARAMS_DEVICE;
- // 商品信息
- $req = new CreateOrderRequest();
- $res = RequestHelper::send($req, RequestHelper::enCrypto($contentModel, $order['mall_id']), $order['mall_id']);
- $orderModel->req_success = 100;
- if (!is_array($res)) {
- $orderModel->req_success = StatusEnum::ENABLED;
- // throw new \Exception($res);
- }
- } else {
- $res = $balanceLogModel;
- $orderModel->req_success = StatusEnum::ENABLED;
- }
- $orderModel->last_resp = var_export($res, true);
- }
- // 创建订单
- $orderModel->content = ['create' => !empty($res) ? $res : []];
- $orderModel->post = ['create' => !empty($contentModel) ? $contentModel->toArray() : (!empty($shipContentModel) ? $shipContentModel->toArray() : [])];
- if (empty($a_order_id)) {
- $orderModel->order_no = $order['order_no'];
- $orderModel->order_id = $order['id'];
- $orderModel->mall_id = $order['mall_id'];
- $orderModel->user_id = $order['user_id'];
- $orderModel->order_detail_ids = $order_detail_ids;
- }
- $orderModel->third_order_no = $res['order_sn'] ?? '';
- $orderModel->req_success = !empty($orderModel->req_success) ? $orderModel->req_success : 100;
- $orderModel->last_req = 'create';
- if (!$orderModel->save()) throw new \Exception($orderModel->getErrorMessage());
- if ($orderModel->req_success != 100 && !empty($balanceLogModel) && !is_string($balanceLogModel)) {
- FundService::asyncRefund($balanceLogModel->id);
- }
- }
- } catch (\Exception $e) {
- \Yii::error(FormatHelper::exception($e, __METHOD__));
- var_dump($e->getMessage(), $e->getFile(), $e->getLine());
- return false;
- }
- return true;
- }
- /**
- * 订单更新
- * @param QiDingDongEvent $event
- * @return void
- * @throws \Exception
- */
- public function eventUpdate(QiDingDongEvent &$event)
- {
- // foreach (Mall::getAllMallIds() as $mallId) {
- // $config = (new SettingService())->get($mallId);
- // if ($config['app_key'] == $event->post['app_key'] && $config['token'] == $event->post['base']['token']) {
- // break;
- // }
- // $config = null;
- // }
- // if (empty($config)) throw new \Exception("未找到插件信息");
- $aOrder = QiDingDongOrder::findOne(['third_order_no' => $event->content['content']['data']['order_sn']]);
- if (empty($aOrder)) throw new \Exception("订单不存在!");
- $event->mall_id = $aOrder->mall_id;
- // 做处理
- $order = Order::getOne([
- ['id' => $aOrder->order_id]
- ], true, 'detail');
- if (empty($order)) throw new \Exception("订单不存在");
- $t = \Yii::$app->db->beginTransaction();
- try {
- switch ($event->content['content']['data']['fahuo_status']) {
- case 0:
- // 已支付
- break;
- case 3:
- // 配货中
- break;
- case 1:
- // 已发货
- // 执行发货
- // 查快递
- /**
- * @var $express Express
- */
- $express = Express::getOne([
- ['like', 'name', $event->content['content']['data']['ship_name']]
- ]);
- if (empty($express)) {
- $express = Express::getOne([
- ['id' => Express::EXPRESS_OTHER]
- ]);
- }
- $form['mall_id'] = $event->mall_id;
- $form['shipping_type'] = ShippingTypeEnum::LOGISTICS;
- $form['order_detail_ids'] = $aOrder->order_detail_ids;
- $form['express_id'] = $express->id;
- $form['express_no'] = $event->content['content']['data']['ship_sn'][0];
- $ships = Json::encode($event->content['content']['data']['ship_sn']);
- $form['memo'] = "{$event->content['content']['data']['ship_name']}, {$ships}, {$event->content['content']['data']['ship_time']}";
- $form['express_name'] = $express->name;
- $form['id'] = $aOrder->order_id;
- $form['mch_id'] = 0;
- $form['operator_id'] = 0;
- $form['operator_name'] = "企叮咚供应链发货";
- $res = OrderExpress::delivery($form); // 发货
- if ($res === false) throw new \Exception(OrderExpress::getStaticError());
- break;
- case 4:
- // 已完成
- break;
- case 9:
- // 已关闭
- break;
- }
- $event->mall_id = $aOrder->mall_id;
- $aOrder->content = array_merge($aOrder->content, [
- 'event' => [
- $event->content['fahuo_status'] => $event->content
- ]
- ]);
- if (!$aOrder->save()) throw new \Exception($aOrder->getErrorMessage());
- $t->commit();
- } catch (\Exception $e) {
- $t->rollBack();
- \Yii::error(FormatHelper::exception($e, __METHOD__));
- throw new \Exception($e->getMessage());
- }
- }
- /**
- * 补偿
- * @param int $mall_id
- * @param $id
- * @return bool|string
- */
- public function compensate(int $mall_id, $id)
- {
- $aOrder = QiDingDongOrder::findOne(['mall_id' => $mall_id, 'id' => $id]);
- if (empty($aOrder)) return '记录不存在';
- if ($aOrder->req_success == 100) return '当前状态无效补偿';
- try {
- switch ($aOrder->last_req) {
- case 'create':
- $order = Order::getOne([['id' => $aOrder->order_id]],true, ['detail']);
- return $this->create($order, $id);
- }
- } catch (\Exception $e) {
- return $e->getMessage();
- }
- return '当前订单非补偿状态';
- }
- /**
- * @param int $order_id
- * @return bool
- */
- public static function existOrder(int $order_id)
- {
- return !empty(QiDingDongOrder::findOne(['order_id' => $order_id]));
- }
- }
|