| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 |
- <?php
- /**
- * 重庆赤晓店信息科技有限公司
- * https://www.chixiaodian.com
- * Copyright (c) 2023 赤店商城 All rights reserved.
- */
- namespace app\modules\client\models\v1\alipay;
- use app\models\District;
- use app\models\FreeDeliveryRules;
- use app\models\Goods;
- use app\models\GoodsChainLevel;
- use app\models\Option;
- use app\models\Order;
- use app\models\OrderDetail;
- use app\models\PostageRules;
- use app\models\SaasUser;
- use app\models\ShareHolderLevel;
- use app\models\ShareHolderProfitGoodsLog;
- use app\models\StoreAliMini;
- use app\models\User;
- use app\modules\admin\models\AlipayThirdForm;
- use app\utils\Alipay\Alipay;
- use app\utils\Alipay\AlipayProfit;
- use app\utils\Alipay\alipaySdk\aop\request\AlipayUserInfoShareRequest;
- use app\utils\OrderNo;
- use yii\helpers\ArrayHelper;
- use yii\helpers\Json;
- class OrderForm extends ApiModel
- {
- public $store_id;
- public $mini_id;
- public $money;
- public $goods_id;
- public $attr;
- public $params;
- public $authCode;
- public $sourceId;
- public $user_id;
- public function rules()
- {
- return [
- [['money'], 'number'],
- [['params', 'sourceId', 'authCode'], 'string'],
- [['user_id', 'mini_id', 'store_id'], 'integer']
- ];
- }
- public function pay() {
- $res = AlipayProfit::mini(null, null, null);
- if ($res['code'] != 0) {
- return [
- 'code' => 1,
- 'msg' => $res['msg'],
- ];
- }
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => ['trade_no' => $res['data']['trade_no']]
- ];
- }
- //获取运费
- public function getFreight() {
- try {
- $params = json_decode($this->params ?? '', true);
- if (empty($params['addressInfo']['mobilePhone'])) {
- throw new \Exception('参数缺失');
- }
- $result = $this->getUserInfo($params['addressInfo']['mobilePhone'], $this->authCode, $this->store_id);
- if ($result['code']) {
- return [
- 'code' => 0,
- 'msg' => $result['msg'],
- 'data' => [
- 'freight' => 0,
- 'purchaseRestriction' => true,
- 'purchaseRestrictionCode' => 'OTHER'
- ]
- ];
- }
- if ($result['data']['user']['blacklist'] == User::USER_IN_BLACKLIST) {
- return [
- 'code' => 0,
- 'msg' => $result['msg'],
- 'data' => [
- 'freight' => 0,
- 'purchaseRestriction' => true,
- 'purchaseRestrictionCode' => 'BUYER_RISK'
- ]
- ];
- }
- $prov = $params['addressInfo']['prov'];
- $city = $params['addressInfo']['city'];
- $area = $params['addressInfo']['area'];
- $quantity = $params['orderDetailInfo']['quantity'];
- $salePrice = $params['itemInfo']['salePrice'];
- $outItemId = $params['itemInfo']['outItemId'];
- $outItemIdArr = explode('_', $outItemId);
- $goods = Goods::findOne(['id' => $outItemIdArr[1], 'store_id' => $this->store_id]);
- if (!$goods) {
- return [
- 'code' => 0,
- 'msg' => '商品不存在',
- 'data' => [
- 'freight' => 0,
- 'purchaseRestriction' => true,
- 'purchaseRestrictionCode' => 'ITEM_CANNOT_FOUND'
- ]
- ];
- }
- if (!intval($goods->status)) {
- return [
- 'code' => 0,
- 'msg' => '商品已下架',
- 'data' => [
- 'freight' => 0,
- 'purchaseRestriction' => true,
- 'purchaseRestrictionCode' => 'ITEM_OFFLINE'
- ]
- ];
- }
- if (!intval($goods->goods_num)) {
- return [
- 'code' => 0,
- 'msg' => '商品已售完',
- 'data' => [
- 'freight' => 0,
- 'purchaseRestriction' => true,
- 'purchaseRestrictionCode' => 'ITEM_SELLOUT'
- ]
- ];
- }
- Goods::skuAttr($goods);
- $price_open = false;
- $attr_open = false;
- $attr = json_decode($goods->attr, true);//$params['itemInfo']['outSkuId'];
- foreach ($attr as $attr_item) {
- if ($attr_item['cyy_skuId'] === $params['itemInfo']['outSkuId']) {
- $attr_open = true;
- if (floor_num($salePrice, 2) !== floor_num($attr_item['price'], 2)) {
- $price_open = true;
- }
- }
- }
- if ($price_open || !$attr_open) {
- return [
- 'code' => 0,
- 'msg' => '价格不对应',
- 'data' => [
- 'freight' => 0,
- 'purchaseRestriction' => true,
- 'purchaseRestrictionCode' => 'ITEM_SKU_NOT_MATCH'
- ]
- ];
- }
- $mch = [
- 'goods_list' => [
- [
- 'goods_id' => $goods->id,
- 'freight' => $goods->freight,
- 'num' => $quantity,
- 'weight' => $goods->weight,
- 'price' => $salePrice,
- ]
- ],
- 'total_price' => bcmul($salePrice, $quantity, 2)
- ];
- $province = District::find()->where(['LIKE', 'name', $prov])->asArray()->one();
- $city = District::find()->where(['LIKE', 'name', $city])->asArray()->one();
- $area = District::find()->where(['LIKE', 'name', $area])->asArray()->one();
- if (empty($province) || empty($city) || empty($area)) {
- throw new \Exception('区域错误');
- }
- $address = [
- 'province_id' => $province['id'],
- 'city_id' => $city['id'],
- 'district_id' => $area['id']
- ];
- $err_data = [];
- $expressPrice = 0;
- if ($address) {
- //先计算单品满件包邮和满额包邮
- $resGoodsList = Goods::cutFull($mch['goods_list']);
- //再通过运费规则计算运费
- $expressPrice = PostageRules::getExpressPriceMore($this->store_id ?? get_store_id(), $address['city_id'], $resGoodsList, $address['province_id'], $err_data);
- }
- $mchTotalPrice = array_sum(array_column($mch['goods_list'], 'price'));
- $expressPrice = $this->getFreeDeliveryRules($mch, $expressPrice, $mchTotalPrice, $address);
- return [
- 'code' => 0,
- 'msg' => '',
- 'data' => [
- 'freight' => $expressPrice['expressPrice'] >= 0 ? $expressPrice['expressPrice'] : 0,
- 'purchaseRestriction' => !empty($err_data),
- 'purchaseRestrictionCode' => !empty($err_data) ? 'OTHER' : '',
- 'user_id' => $result['data']['user']['id']
- ]
- ];
- } catch (\Exception $e) {
- return [
- 'code' => 0,
- 'msg' => $e->getMessage(),
- 'data' => [
- 'freight' => 0,
- 'purchaseRestriction' => true,
- 'purchaseRestrictionCode' => 'OTHER'
- ]
- ];
- }
- }
- //创建订单信息
- public function createOrder() {
- try {
- $sourceId = $this->sourceId;
- $user_id = $this->user_id;
- $store_id = $this->store_id;
- $params = json_decode($this->params, true);
- $prov = $params['addressInfo']['prov'];
- $city = $params['addressInfo']['city'];
- $area = $params['addressInfo']['area'];
- $address_detail = $params['addressInfo']['address'];
- $province = District::find()->where(['LIKE', 'name', $prov])->asArray()->one();
- $city = District::find()->where(['LIKE', 'name', $city])->asArray()->one();
- $area = District::find()->where(['LIKE', 'name', $area])->asArray()->one();
- $express_price = $params['priceInfo']['freight'];
- $quantity = $params['orderInfo']['quantity'];
- $salePrice = $params['itemInfo']['salePrice'];
- $outItemId = $params['itemInfo']['outItemId'];
- $outItemIdArr = explode('_', $outItemId);
- $goods = Goods::findOne(['id' => $outItemIdArr[1], 'store_id' => $this->store_id]);
- if (!$goods) {
- throw new \Exception('商品不存在');
- }
- Goods::skuAttr($goods);
- $goods_attr = [];
- $attr = json_decode($goods->attr, true);//$params['itemInfo']['outSkuId'];
- foreach ($attr as $attr_item) {
- if ($attr_item['cyy_skuId'] === $params['itemInfo']['outSkuId']) {
- $goods_attr = $attr_item['attr_list'];
- if (floor_num($salePrice, 2) !== floor_num($attr_item['price'], 2)) {
- $cost_price = $attr_item['cost_price'];
- }
- }
- }
- $t = \Yii::$app->db->beginTransaction();
- try {
- $order = new Order();
- $order->order_no = OrderNo::getOrderNo(OrderNo::ORDER_MALL);
- $order->order_origin = Order::ORDER_SOURCE_MINI;
- $order->store_id = $store_id;
- $order->user_id = $user_id;
- $order->name = $params['addressInfo']['fullname'];
- $order->mobile = $params['addressInfo']['mobilePhone'];
- $order->address = $province['name'] ?? '' . $city['name'] ?? '' . $area['name'] ?? '' . $address_detail;
- $order->province_id = $province['id'] ?: 0;
- $order->city_id = $city['id'] ?: 0;
- $order->district_id = $area['id'] ?: 0;
- $order->town_id = 0;
- $order->village_id = 0;
- $order->address_data = json_encode([
- 'province' => trim($province['name']),
- 'city' => trim($city['name']),
- 'district' => trim($area['name']),
- 'detail' => trim($address_detail),
- 'town' => '',
- 'village' => '',
- 'latitude' => 0,
- 'longitude' => 0,
- ], JSON_UNESCAPED_UNICODE);
- $order->buy_level_id = 0;
- $order->total_price = $order->pay_price = bcadd(bcmul($salePrice, $quantity, 2), $express_price, 2);
- $order->express_price = $express_price;
- $order->md_id = 0;
- $order->is_fugou = 0;
- $order->created_at = time();
- $order->order_type = 0;
- $order->integral_price = 0;
- $order->integral_difference_price = 0;
- $order->is_platform = 0;
- $order->first_price = 0.00;
- $order->second_price = 0.00;
- $order->third_price = 0.00;
- $order->transaction_id = '';
- $order->integral = json_encode(['forehead' => 0, 'forehead_integral' => 0]);
- // $order->order_no = OrderNo::getOrderNo(OrderNo::ORDER_MALL);
- $order->is_pay = 0;
- $order->version = cyy_version();
- if (!$order->save()) {
- throw new \Exception(json_encode($order->errors));
- }
- $order_detail = new OrderDetail();
- $order_detail->order_id = $order->id;
- $order_detail->goods_id = $goods->id;
- $order_detail->num = $quantity;
- $order_detail->cost_price = $cost_price;
- $order_detail->total_price = bcmul($salePrice, $quantity, 2);
- // 计算单个商品可分红金额
- $profit = $goods->rate_type == 0 ? floatval($order_detail->total_price * $goods->rate / 100) : floatval($goods->rate) * $quantity;
- $goods_profit = $profit;
- $order_detail->profit = $profit;
- // 链动
- $chain_profit = $goods->chain_rate_type == 0 ? floatval($order_detail->total_price * $goods->chain_rate / 100) : floatval($goods->chain_rate) * $quantity;
- $chain_goods_profit = $chain_profit;
- $order_detail->chain_profit = $chain_profit;
- $order_detail->is_delete = 0;
- $chainGoodsList[] = [
- 'id' => $goods->id,
- 'num' => $quantity,
- 'pay_price' => $order_detail->total_price,
- ];
- $shareHolderRepeatProfitSwitch = (int)Option::get('shareHolderRepeatProfitSwitch', $order->store_id, 'bonus_pool', 0)['value'];
- //判断是否是升级产品
- $open = false;
- $shareHolderLevelList = ShareHolderLevel::find()->where(['store_id' => $order->store_id, 'status' => 1, 'is_delete' => 0])
- ->select('condition, id, level, member_level')->asArray()->all();
- foreach ($shareHolderLevelList as $item) {
- $condition = json_decode($item['condition'], true);
- if ((int)$condition['goods']['is_open'] === 1 && !empty($condition['goods']['value']['id']) && in_array($goods->id, $condition['goods']['value']['id'])) {
- $open = true;
- break;
- }
- }
- //如果是分红产品或者是升级产品则添加记录
- if (floatval(sprintf("%.2f", ($profit / $quantity))) > 0 || $open) {
- if ($shareHolderRepeatProfitSwitch) {
- $profitGoodsLog = new ShareHolderProfitGoodsLog();
- $profitGoodsLog->user_id = get_user_id();
- $profitGoodsLog->goods_id = $goods->id;
- $profitGoodsLog->order_id = $order->id;
- $profitGoodsLog->goods_price = floatval(sprintf("%.2f", ($order_detail->total_price / $quantity)));
- $profitGoodsLog->goods_profit = floatval(sprintf("%.2f", ($profit / $quantity)));
- $profitGoodsLog->is_switch = intval($shareHolderRepeatProfitSwitch);
- if (!$profitGoodsLog->save()) {
- return [
- 'code' => 1,
- 'msg' => implode(';', array_values($profitGoodsLog->firstErrors))
- ];
- };
- // }
- }
- }
- //
- $order_detail->attr = json_encode($goods_attr, JSON_UNESCAPED_UNICODE);
- $order_detail->food_ext_goods = '';
- $order_detail->pic = $goods->cover_pic;
- $order_detail->goods_name = $goods->name;
- if (!empty($goods)) {
- //在添加下单商品信息时增加链动等级记录 为了实现小推大功能
- $goods = $goods->toArray();
- $goods['goods_chain_level'] = GoodsChainLevel::find()->where(['goods_id' => $goods['id']])->asArray()->one();
- }
- $order_detail->goods_info = $goods ? Json::encode($goods) : Json::encode([]);
- $order_detail->delivery_type = OrderDetail::GOODS_DELIVERY_EXPRESS;
- $order_detail->integral = 0;
- $attr_id_list = [];
- foreach ($goods_attr as $item) {
- array_push($attr_id_list, $item['attr_id']);
- }
- $order_detail->batch_price_tips = $goods['current_batch_price_tips'];
- if (!$order_detail->save()) {
- throw new \Exception('订单详情信息错误');
- }
- // goods_profit 计算之后存入订单表中
- $order->profit = $goods_profit;
- $order->chain_profit = $chain_goods_profit;
- $orderChainLevelProfit = \app\utils\Share\BonusPool::getOrderLevelProfit(get_store_id(), $chainGoodsList);
- $order->chain_level_value = json_encode($orderChainLevelProfit);
- if (!$order->save()) {
- throw new \Exception('订单信息错误');
- }
- $t->commit();
- } catch (\Exception $e) {
- $t->rollBack();
- throw new \Exception($e->getMessage());
- }
- $goods_detail = [
- [
- 'goods_id' => $outItemIdArr[1],
- 'goods_name' => $order_detail->goods_name,
- 'quantity' => $order_detail->num,
- 'price' => $order_detail->total_price / $order_detail->num,
- ]
- ];
- $user = User::findOne($user_id);
- $goods_names = mb_substr($order_detail->goods_name . ';', 0, 32, 'utf-8');
- $orderInfo = [
- 'body' => $goods_names,
- 'out_trade_no' => $order->order_no,
- 'total_amount' => $order->pay_price,
- 'subject' => $goods_names,
- 'buyer_id' => $user->alipay_open_id
- ];
- $goods_detail && $orderInfo['goods_detail'] = $goods_detail;
- $alipayForm = new AlipayThirdForm();
- $alipayForm->mini_id = $this->mini_id;
- $openOrder = $alipayForm->AlipayOpenMiniOrderCreate($order, $orderInfo, (object)[
- 'ali_sourceId' => $sourceId,
- 'activity_consult_id' => $params['orderInfo']['activityConsultId']
- ]);
- if($openOrder['code'] != 0){
- return $openOrder;
- }
- $orderInfo['product_code'] = 'JSAPI_PAY';
- $orderInfo['extend_params'] = array_merge((array)$orderInfo['extend_params'], [
- 'trade_component_order_id' => $openOrder['data']
- ]);
- $orderInfo['goods_detail'] = [];
- foreach($openOrder['biz_content']['order_detail']['item_infos'] as $info_item){
- $orderInfo['goods_detail'][] = [
- 'goods_id' => $info_item['goods_id'],
- 'goods_name' => $info_item['goods_name'],
- 'quantity' => $info_item['item_cnt'],
- 'price' => $info_item['sale_price'],
- 'out_item_id' => $info_item['out_item_id'],
- 'out_sku_id' => $info_item['out_sku_id']
- ];
- }
- if (is_profit_pay('ali')) {
- AlipayProfit::init($order->store_id, '');
- $result = AlipayProfit::$alipay->mini($orderInfo);
- } else {
- Alipay::init('');
- $result = Alipay::$alipay->mini($orderInfo);
- }
- if ($result && $result->code === '10000' && $result->msg === 'Success') {
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $result->toArray()
- ];
- }
- throw new \Exception($result->msg);
- } catch (\Exception $e) {
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- //获取运费规则
- public function getFreeDeliveryRules($mch, $expressPrice, $mchTotalPrice, $address) {
- if ($expressPrice == 0) {
- // return $expressPrice;
- return ['expressPrice' => $expressPrice, 'diff' => 0];
- }
- $freeDeliveryPrice = 0;
- $free = FreeDeliveryRules::find()->where(['store_id' => $this->store_id ?? get_store_id(), 'is_delete' => 0, 'mch_id' => 0])->asArray()->all();
- foreach ($free as $k => $v) {
- $city = json_decode($v['city'], true);
- foreach ($city as $v1) {
- if ($address['district_id'] == $v1['id'] && $mch['total_price'] >= $v['price']) {
- $expressPrice = 0;
- break;
- }
- if ($address['district_id'] == $v1['id']) {
- $freeDeliveryPrice = max($freeDeliveryPrice, $v['price']);
- }
- }
- }
- $diff = 0;
- // echo $mchTotalPrice;die;
- if ($freeDeliveryPrice > 0) {
- $diff = $freeDeliveryPrice - $mchTotalPrice;
- }
- if ($expressPrice > 0) {
- return ['expressPrice' => $expressPrice, 'diff' => $diff];
- } else {
- return ['expressPrice' => $expressPrice, 'diff' => 0];
- }
- }
- //创建/获取用户
- public function getUserInfo($mobile, $authCode, $store_id) {
- //查询用户是否存在 不存在就创建一个用户
- $open = false;
- $saas_user = SaasUser::findOne(['mobile' => $mobile, 'is_delete' => 0]);
- if (!$saas_user) {
- $open = true;
- }
- $user = User::findOne(['binding' => $mobile, 'is_delete' => 0, 'store_id' => $store_id]);
- if (!$user) {
- $open = true;
- }
- if ($open) {
- $storeAliMini = StoreAliMini::findOne(['store_id' => $store_id, 'is_cancel' => 0, 'is_use' => 1]);
- $auth_form = new AuthForm();
- $auth_form->mini_id = $storeAliMini->id;
- $auth_form->store_id = $store_id;
- [$token, $aop, $auth_token] = $auth_form->getToken($authCode);
- $auth_time = (strtotime($token['auth_start']) + $token['expires_in']);
- if ($auth_time < time()) {
- [$token, $aop, $auth_token] = $auth_form->getToken($authCode, 1, $token['refresh_token']);
- }
- // $request = new AlipayUserInfoShareRequest();
- //
- // $result = $aop->execute($request, $token['access_token'], $auth_token);
- // $result = json_encode($result);
- // $result = json_decode($result,true);
- // \Yii::error($result);
- // $token = $result['alipay_user_info_share_response'];
- // if ((int)$token['code'] !== 10000) {
- // return [
- // 'code' => 1,
- // 'msg' => $token['msg']
- // ];
- // }
- if (!$saas_user) {
- $saas_user = new SaasUser();
- $saas_user->access_token = \Yii::$app->security->generateRandomString();
- $saas_user->avatar = $token['avatar'] ?: (\Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/avatar.png');
- $saas_user->mobile = $mobile ?? '';
- $saas_user->name = $token['nick_name'] ?: '';
- $saas_user->store_id = $store_id;
- $saas_user->ali_user_id = $token['user_id'] ?: '';
- if (!$saas_user->save()) {
- return [
- 'code' => 1,
- 'msg' => '获取失败',
- ];
- }
- }
- if (!$user) {
- $default_user_info_arr = OptionSetting::default_user_info_arr();
- $default_user_info = [
- 'default_user_nickname' => $default_user_info_arr['default_user_nickname'] ?? '',
- 'default_user_pic' => $default_user_info_arr['default_user_pic'] ?? '',
- ];
- $user = new User();
- $user->type = User::USER_TYPE_NORMAL;
- $user->binding = $mobile ?? '';
- $user->avatar_url = $token['avatar'] ?: ($default_user_info['default_user_pic'] ?: \Yii::$app->request->hostInfo . '/web/v1/statics/images/avatar.png');
- $user->username = \Yii::$app->security->generateRandomString();
- $user->nickname = $token['nick_name'] ?: $default_user_info['default_user_nickname'];
- $user->password = \Yii::$app->security->generatePasswordHash(\Yii::$app->security->generateRandomString(), 5);
- $user->auth_key = \Yii::$app->security->generateRandomString();
- $user->access_token = \Yii::$app->security->generateRandomString();
- $user->is_delete = User::USER_NOT_DELETE;
- $user->alipay_open_id = $token['user_id'] ?: '';
- $user->store_id = $store_id;
- $user->platform = User::USER_FROM_ALIPAY; // 支付宝
- if (!$user->save()) {
- return [
- 'code' => 1,
- 'msg' => '获取失败',
- ];
- }
- }
- }
- return [
- 'code' => 0,
- 'msg' => '操作成功',
- 'data' => [
- 'user' => ArrayHelper::toArray($user)
- ]
- ];
- }
- }
|