[self::IMMEDIATELY_PAY, self::HANGING_ORDER, self::HANGING_ORDER_DETAIL, self::DEL_HANGING_ORDER,self::GET_HANGING_ORDER]], ['price', 'number', 'on' => [self::IMMEDIATELY_PAY]], [['store_id', 'price'], 'required', 'on' => [self::IMMEDIATELY_PAY]], [['goods_list'], 'safe', 'on' => [self::HANGING_ORDER]], [['keywords'], 'string', 'on' => [self::HANGING_ORDER_LIST,self::ORDER_LIST]], ['hanging_order_id', 'required', 'on' => [self::HANGING_ORDER_DETAIL, self::DEL_HANGING_ORDER,self::GET_HANGING_ORDER]] ]; } public function attributeLabels(): array { return [ 'store_id' => '商城ID', 'price' => '收款金额' ]; } public function getPayQrcode(): array { try { if (!$this->validate()) { throw new \Exception($this->getErrorSummary(FALSE)[0]); } $store_id = $this->store_id; $md_id = $this->md_id; $filename = md5('scan_' . $store_id . '_' . $this->price . '_md_id_' . $md_id); $ag = AggregateQrcode::findOne(['store_id' => $store_id]); $store = Store::findOne($store_id); $self_mini = Option::get('self_mini', $store_id, 'store', 0)['value']; $data = []; if (!\Yii::$app->isSaas()) { $data['mini_url'] = '/face-pay/face-pay/payOut'; $data['param_url'] = 'https://' . \Yii::$app->request->hostName . '/web/face/pay/' . $store_id . '?p=' . $this->price . '&md_id=' . $md_id; } if (!empty($store) && ((int)$store->business_model !== 1 || (\Yii::$app->prod_is_dandianpu()) && !$self_mini)) { $asg = AggregateSaasQrcode::findOne(['store_id' => $store_id]); if (empty($asg->qrcode_url) || !file_exists(str_replace(\Yii::$app->request->hostInfo, \Yii::$app->basePath, $asg->qrcode_url))) { if (!empty($asg->param_url)) { $path = \Yii::$app->runtimePath . '/image/' . $filename . '.jpg'; $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/runtime/image/' . $filename . '.jpg'); $text = $asg->param_url . '?p=' . $this->price . '&md_id=' . $md_id; QrCode::image($text, 500, FALSE, 'L', 'JPEG', 0, ['255,255,255', '0,0,0'], 1, FALSE, $path); return [ 'code' => 0, 'data' => [ 'qr_url' => $pic_url, 'business_model' => $store->business_model, 'is_saas' => (int)\Yii::$app->isSaas(), 'data' => [ 'param_url' => $pic_url ] ] ]; } } $path = \Yii::$app->runtimePath . '/image/' . $filename . '.jpg'; $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/runtime/image/' . $filename . '.jpg'); if (file_exists($path)) { return [ 'code' => 0, 'data' => [ 'qr_url' => $pic_url, 'business_model' => $store->business_model, 'is_saas' => (int)\Yii::$app->isSaas(), 'data' => [ 'param_url' => $pic_url ] ] ]; } $text = 'store_id:' . $store_id . ',p:' . $this->price . ',md_id:' . $md_id; $app = ShareQrcode::setBussinessWechat(); $response = $app->getUnlimit($text, [ 'width' => 500, 'page' => "face-pay/face-pay/payOut" ]); if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) { $filename = $response->save(\Yii::$app->runtimePath . '/image/', $filename); } else { return [ 'code' => 1, 'data' => [ 'response' => $response, 'business_model' => $store->business_model, ] ]; } return [ 'code' => 0, 'data' => [ 'qr_url' => $pic_url, 'business_model' => $store->business_model, 'is_saas' => (int)\Yii::$app->isSaas(), 'data' => [ 'param_url' => $pic_url ] ] ]; } else if (empty($ag->param_url)) { $path = \Yii::$app->runtimePath . '/image/' . $filename . '.jpg'; $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/runtime/image/' . $filename . '.jpg'); if (file_exists($path)) { return [ 'code' => 0, 'data' => [ 'qr_url' => $pic_url, 'business_model' => $store->business_model, 'is_saas' => (int)\Yii::$app->isSaas(), 'data' => $data ] ]; } //$text = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/scan/' . $store_id); $text = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/web/face/pay/' . $store_id . '?p=' . $this->price . '&md_id=' . $md_id); QrCode::image($text, 500, FALSE, 'L', 'JPEG', 0, ['255,255,255', '0,0,0'], 1, FALSE, $path); } else { //同步后端的聚合码 $filename = md5(date('YmdHis') . $ag->id . $this->price); $path = \Yii::$app->runtimePath . '/image/' . $filename . '.jpg'; $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/runtime/image/' . $filename . '.jpg'); $ag = AggregateQrcode::find()->where(['id' => $ag->id])->select('param_url,id,qrcode_url')->one(); if (empty($ag->qrcode_url) || !file_exists(str_replace(\Yii::$app->request->hostInfo, \Yii::$app->basePath, $ag->qrcode_url))) { if (!empty($ag->param_url)) { $text = $ag->param_url . '?p=' . $this->price . '&md_id=' . $md_id; QrCode::image($text, 500, FALSE, 'L', 'JPEG', 0, ['255,255,255', '0,0,0'], 1, FALSE, $path); } } } return [ 'code' => 0, 'data' => [ 'qr_url' => $pic_url, 'business_model' => $store->business_model, 'data' => [ 'param_url' => $pic_url, ], 'is_saas' => (int)\Yii::$app->isSaas(), ] ]; } catch (\Exception $e) { return ['code' => 1, 'msg' => $e->getMessage()]; } } public function hangingOrder(): array { try { if (!$this->validate()) { throw new \Exception($this->getErrorSummary(FALSE)[0]); } $t = \Yii::$app->db->beginTransaction(); // 需要下检测一下商品 $totalPrice = 0; $orderGoods = []; $this->goods_list = json_decode($this->goods_list, TRUE); foreach ($this->goods_list as $value) { // 商品数据 $goods = Goods::findOne($value['goods_id']); // 购买商品的规格数据 $attr = []; foreach ($value['attr'] as $attrItem) { if (!empty($attrItem['attr_id'])) { $attr[] = intval($attrItem['attr_id']); } } // 根据规格获取商品的库存及规格价格信息 $attr_info = $goods->getAttrInfo($attr); if (isset($value['new_price']) && $value['new_price'] > 0) { $goods->price = $attr_info['price'] = $value['new_price']; } $goodsPrice = sprintf('%.2f', ($value['new_price'] > 0 ? $value['new_price'] : ($goods->use_attr ? $attr_info['price'] : $goods->price)) * $value['num']); // 整理detail数据 $dataItem = [ 'goods_id' => $goods->id, 'goods_name' => $goods->name, 'num' => $value['num'], 'total_price' => $goodsPrice, 'attr' => json_encode($attr, JSON_UNESCAPED_UNICODE), 'new_price' => $value['new_price'] ?: 0 ]; $orderGoods[] = $dataItem; // 商品的价格乘以商品的数量 $totalPrice += $goodsPrice; } if ($this->hanging_order_id > 0) { $hangingOrder = HangingOrder::findOne($this->hanging_order_id); } else { $hangingOrder = new HangingOrder(); } if (!$this->user_id) { return [ 'code' => 1, 'msg' => '生成挂单记录失败,挂单用户id不能为空' ]; } $hangingOrder->store_id = $this->store_id; $hangingOrder->user_id = $this->user_id; $hangingOrder->md_id = 0; if ($this->hanging_order_id <= 0) { // 不修改原来的挂单订单编号 $hangingOrder->order_no = self::createOrderNo(); } $hangingOrder->total_price = $totalPrice; $hangingOrder->create_at = time(); $hangingOrder->is_delete = 0; $hangingOrder->status = 0; if (!$hangingOrder->save()) { $t->rollBack(); return [ 'code' => 1, 'msg' => '生成挂单记录失败', 'data' => $hangingOrder->getErrors() ]; } // 先删除之前所有挂单商品 if ($this->hanging_order_id > 0) { HangingOrderDetail::updateAll(['is_delete' => 1], ['order_id' => $hangingOrder->id]); } // 处理挂单商品信息 foreach ($orderGoods as $detailItem) { $hangingOrderDetail = new HangingOrderDetail(); $hangingOrderDetail->order_id = $hangingOrder->id; $hangingOrderDetail->goods_id = $detailItem['goods_id']; $hangingOrderDetail->num = $detailItem['num']; $hangingOrderDetail->attr = $detailItem['attr']; $hangingOrderDetail->total_price = $detailItem['total_price']; $hangingOrderDetail->new_price = $detailItem['new_price']; $hangingOrderDetail->is_delete = 0; if (!$hangingOrderDetail->save()) { $t->rollBack(); return [ 'code' => 1, 'data' => $hangingOrderDetail->getErrors() ]; } } // 生成操作记录 CashierActionLog::setLog($this->store_id,get_user_id(),CashierActionLog::HANGINF_ORDER,'提交挂单信息', $hangingOrder->md_id); $t->commit(); return [ 'code' => 0, 'data' => '订单挂单成功' ]; } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } /** * 生成订单号 * @return string * User: hankaige * DATE TIME: 2022/12/5 15:11 */ private static function createOrderNo(): string { $order_no = NULL; while (TRUE) { $order_no = HangingOrder::ORDER_PREFIX . date('YmdHis') . mt_rand(100000, 999999); $exist_order_no = HangingOrder::find()->where(['order_no' => $order_no])->exists(); if (!$exist_order_no) { break; } } return $order_no; } /** * 获取挂单订单列表 * @return array * User: hankaige * DATE TIME: 2022/12/6 09:31 */ public function getHangingOrderList(): array { $query = HangingOrder::find()->alias('ho')->leftJoin(['u' => User::tableName()], 'ho.user_id=u.id')->with(['orderDetail'])->where(['ho.is_delete' => 0, 'ho.store_id' => $this->store_id]); if (!empty($this->keywords)) { $query->andWhere(['or', ['u.nickname', 'like', $this->keywords], ['ho.order_no', 'like', $this->keywords], ['u.binding', 'like', $this->keywords]]); } $md_id = $this->md_id; if ($md_id < 0) { $md_id = [0, -1]; } $query->andWhere(['ho.md_id' => $md_id]); $query->orderBy('ho.create_at DESC')->select('ho.*,u.nickname,u.binding,u.avatar_url,u.id as user_id'); $list = pagination_make($query); foreach ($list['list'] as &$item) { foreach ($item['orderDetail'] as &$value) { $goods = Goods::findOne([ 'id' => $value['goods_id'], 'is_delete' => 0, 'status' => 1, ]); if (!$goods) { continue; } $goods_id_list[] = $value['goods_id']; $attr_list = Attr::find()->alias('a') ->select('ag.attr_group_name,a.attr_name,a.id as attr_id,a.attr_group_id') ->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id') ->where(['a.id' => json_decode($value['attr'], TRUE)]) ->asArray()->all(); $attr = $goods->attr; $price = $goods->price; $goodsData = [ 'attr' => $attr, 'price' => $price, 'is_level' => $goods->is_level, 'use_attr' => $goods->use_attr, ]; $user_id = $item['user_id']; $user = User::findOne($user_id); // todo 忘记这里是干什么用的 if ($user) { \Yii::$app->jwt->setUser($user); } $goods_attr_info = CommonGoods::currentGoodsAttr($goodsData, (array)json_decode($value['attr'], TRUE)); $goods_pic = isset($goods_attr_info['pic']) && !empty($goods_attr_info['pic']) ? $goods->getGoodsPic(0)->pic_url : $goods->cover_pic; $value['total_price'] = sprintf('%.2f', $value['total_price']); $value['goods_name'] = $goods->name; $value['attr_list'] = $attr_list; $value['goods_pic'] = $goods_pic; } $total_price_arr = array_column($item['orderDetail'], 'total_price'); $item['total_price'] = round(array_sum($total_price_arr), 2); $item['create_at'] = date('Y-m-d H:i:s', $item['create_at']); } return [ 'code' => 0, 'data' => $list ]; } // 获取挂单商品列表 public function getHangingOrderDetail(): array { if (empty($this->hanging_order_id)) { return ['code' => 1, 'msg' => '挂单订单ID有误']; } $md_id = $this->md_id; $query = HangingOrderDetail::find()->alias('hod')->leftJoin(['g' => Goods::tableName()], 'hod.goods_id = g.id')->where(['hod.order_id' => $this->hanging_order_id, 'hod.is_delete' => 0]); $list = $query->select('hod.*,g.name')->asArray()->all(); foreach ($list as &$value) { $goods = Goods::findOne([ 'id' => $value['goods_id'], 'is_delete' => 0, 'status' => 1, ]); if (!$goods) { continue; } $goods_id_list[] = $value['goods_id']; $attr_list = Attr::find()->alias('a') ->select('ag.attr_group_name,a.attr_name,a.id as attr_id,a.attr_group_id') ->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id') ->where(['a.id' => json_decode($value['attr'], TRUE)]) ->asArray()->all(); $attr = $goods->attr; $price = $goods->price; if ($md_id > 0) { $mdGoods = MdGoods::findOne(['goods_id' => $value['goods_id'], 'md_id' => $md_id]); $attr = $mdGoods->attr; $price = $mdGoods->price; } if ($value['new_price'] > 0) { $mch_attr_id = json_decode($value['attr'], TRUE); sort($mch_attr_id); $attr_ = json_decode($attr, TRUE); foreach ($attr_ as &$goods_attr_item) { $goods_attr_id = array_column($goods_attr_item['attr_list'], 'attr_id'); sort($goods_attr_id); if (!array_diff($goods_attr_id, $mch_attr_id)) { $goods_attr_item['price'] = $value['new_price']; } } $attr = json_encode($attr_, JSON_UNESCAPED_UNICODE); $price = $value['new_price']; } $goodsData = [ 'attr' => $attr, 'price' => $price, 'is_level' => $goods->is_level, 'use_attr' => $goods->use_attr, ]; $goods_attr_info = CommonGoods::currentGoodsAttr($goodsData, (array)json_decode($value['attr'], TRUE)); $goods_pic = isset($goods_attr_info['pic']) && !empty($goods_attr_info['pic']) ? $goods->getGoodsPic(0)->pic_url : $goods->cover_pic; $value['goods_name'] = $goods->name; $value['attr_list'] = $attr_list; $value['price'] = isset($goods_attr_info['level_price']) && !empty($goods_attr_info['level_price']) ? $goods_attr_info['level_price'] : $goods->price; foreach ($attr_list as $m) { $value['attr_text'] .= $m['attr_name'] . ' '; } $warn_goods_timeout = Goods::warn_goods_timeout($goods->store_id); $value['timeout_day'] = $goods->time_made_day ? date('Y-m-d', $goods->time_made_day + 86400 * $goods->time_shelf_life) : '--'; $value['is_warn_goods_timeout'] = ($goods->time_made_day && ($goods->time_made_day + 86400 * $goods->time_shelf_life) < (time() + $warn_goods_timeout * 86400)) ? 1 : 0; $value['total_price'] = $value['price'] * $value['num']; $value['pic'] = $goods_pic; } return [ 'code' => 0, 'data' => $list ]; } public function delHanging(): array { if (empty($this->hanging_order_id)) { return ['code' => 1, 'msg' => '订单ID错误']; } $hangingModel = HangingOrder::findOne($this->hanging_order_id); if (!$hangingModel) { return ['code' => 1, 'msg' => '挂单不存在,请刷新再试']; } $t = \Yii::$app->db->beginTransaction(); try { $hangingModel->is_delete = 1; if (!$hangingModel->save()) { $t->rollBack(); return ['code' => 1, 'msg' => '删除失败']; } HangingOrderDetail::updateAll(['is_delete' => 1], ['order_id' => $this->hanging_order_id]); // 生成操作记录 CashierActionLog::setLog($this->store_id,get_user_id(),CashierActionLog::DEL_HANGINF_ORDER,'删除挂单信息', $hangingModel->md_id); $t->commit(); return ['code' => 0, 'msg' => '挂单订单删除成功']; } catch (\Exception $e) { $t->rollBack(); return ['code' => 1, 'msg' => '系统错误', 'data' => $e->getMessage()]; } } public function getHangingOrder(){ if(empty($this->hanging_order_id)){ return ['code' => 1,'msg'=>'订单ID错误']; } $md_id = $this->md_id; $hangingOrder = HangingOrder::find()->where(['id'=>$this->hanging_order_id,'is_delete' => 0])->with(['orderDetail','user'])->asArray()->one(); // if ($hangingOrder) { // $user_id = $hangingOrder['user_id']; // $user = User::findOne($user_id); // if ($user) { // \Yii::$app->jwt->setUser($user); // } // } if(empty($hangingOrder)){ return ['code' => 0, 'msg' => '挂单信息不存在']; } // 处理商品规格 foreach($hangingOrder['orderDetail'] as &$item){ $goods = Goods::findOne($item['goods_id']); $item['attr_list'] = Attr::find()->alias('a') ->select('ag.attr_group_name,a.attr_name,a.id as attr_id,a.attr_group_id') ->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id') ->where(['a.id' => json_decode($item['attr'], true)]) ->asArray()->all(); $attr = $goods->attr; $price = $goods->price; $md_id = 0; if ($this->md_id > 0) { $md_id = $this->md_id; $mdGoods = MdGoods::findOne(['goods_id' => $item['goods_id'], 'md_id' => $md_id]); $attr = $mdGoods->attr; $price = $mdGoods->price; } $mch_attr_id = json_decode($item['attr'], true); sort($mch_attr_id); $attr_ = json_decode($attr, true); foreach ($attr_ as &$goods_attr_item) { $goods_attr_id = array_column($goods_attr_item['attr_list'], 'attr_id'); sort($goods_attr_id); if (!array_diff($goods_attr_id, $mch_attr_id)) { $goods_attr_item['price'] = $item['new_price']; if ($goods_attr_item['old_price']) { $item['old_price'] = $goods_attr_item['old_price']; } } } $attr = json_encode($attr_, JSON_UNESCAPED_UNICODE); // $price = $item['new_price']; $goodsData = [ 'attr' => $attr, 'price' => $price, 'is_level' => $goods->is_level, 'use_attr' => $goods->use_attr, 'md_id' => $md_id ]; $goods_attr_info = CommonGoods::currentGoodsAttr($goodsData, (array) json_decode($item['attr'], true)); $item['pic'] = isset($goods_attr_info['pic']) && !empty($goods_attr_info['pic']) ? $goods->getGoodsPic(0)->pic_url : $goods->cover_pic; $item['name'] = $goods->name; $item['price'] = isset($goods_attr_info['price']) && !empty($goods_attr_info['price']) ? $goods_attr_info['price'] : $goods->price; $item['goods_id'] = $goods->id; $item['level_price'] = sprintf('%.2f', $goods_attr_info['level_price']); } return [ 'code'=>0, 'msg' => '获取数据成功', 'data'=> $hangingOrder ]; } public function orderList():array { try { $query = Order::find()->alias('o')->leftJoin(['u' => User::tableName()],'o.user_id=u.id')->where(['u.store_id' => $this->store_id,'u.is_delete' => Order::IS_DELETE_FALSE,'o.trade_status' => [Order::ORDER_FLOW_NO_SEND,Order::ORDER_FLOW_SEND,Order::ORDER_FLOW_CONFIRM],'o.mch_id' => 0])->select('o.id,o.order_no,o.created_at,o.trade_status,o.pay_type,o.ready_money,o.user_id,u.nickname,u.avatar_url,u.binding,o.total_price,o.pay_price'); if($this->keywords){ $query->andWhere(['or',['like','o.order_no',$this->keywords],['like','u.nickname',$this->keywords],['like','u.binding',$this->keywords]]); } $md_id = $this->md_id; if ($this->md_id <= 0) { $md_id = [0, -1]; } $query->andWhere(['o.md_id' => $md_id]); $result = pagination_make($query,TRUE,'created_at DESC'); foreach($result['list'] as &$item){ $item['ready_money'] = json_decode($item['ready_money']); $item['created_at'] = date('Y/m/d H:i:s',$item['created_at']); $item['trade_status_text'] = Order::TRADE_STATUS_TEXT[$item['trade_status']]; $item['pay_type_text'] = Order::PAY_TYP_NAME[$item['pay_type']]; $item['orderDetail'] = OrderDetail::find()->where(['order_id' => $item['id']])->select('id,order_id,goods_name,num,total_price,attr,pic')->all(); foreach($item['orderDetail'] as &$orderDetail){ $orderDetail['attr'] = json_decode($orderDetail['attr'],true); } } return [ 'code' => 0, 'data' => $result ]; }catch (\Exception $e){ return ['code' => 1, 'msg' => $e->getMessage()]; } } }