<?php
/**
 * 易优CMS
 * ============================================================================
 * 版权所有 2016-2028 海南赞赞网络科技有限公司，并保留所有权利。
 * 网站地址: http://www.eyoucms.com
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 小虎哥 <1105415366@qq.com>
 * Date: 2018-4-3
 */

namespace app\plugins\model;

use think\Db;
use think\Cache;
use app\api\logic\v1\WechatLogic;

/**
 * 积分商品订单模型
 */

load_trait('controller/Jump');
class PointsOrder extends PointsShopBase
{
    use \traits\controller\Jump;

    private $times = 0;
    private $param = [];
    private $users = [];
    private $users_id = 0;
    private $wechatLogic;
    private $usersConfig;


    // 构造函数
    public function __construct($param = [], $users = [])
    {
        // 统一接收参数处理
        $this->times = getTime();
        $this->param = !empty($param) ? $param : [];
        $this->users = !empty($users) ? $users : [];
        $this->users_id = !empty($this->users['users_id']) ? intval($this->users['users_id']) : 0;
        // 微信公众号业务层
        $this->wechatLogic = new WechatLogic;
        // 配置信息
        $this->usersConfig = getUsersConfigData('all');
        // 积分商品表
        $this->points_goods_db = Db::name('weapp_points_goods');
        // 积分商品表
        $this->points_goods_spec_db = Db::name('weapp_points_goods_spec');

    }

    // 积分商品订单创建逻辑
    public function pointsGoodsOrderCreate(&$result = [], $weappInfoData = [])
    {
        // 基础判断
        $address = !empty($result['address']) ? $result['address'] : [];
        $pointsGoods = !empty($result['pointsGoods']) ? $result['pointsGoods'] : [];
        if (empty($result) || empty($pointsGoods)) $this->error('订单提交失败，请重新选择商品提交');

        // 判断会员积分是否足够支付
        $usersInfo = Db::name('users')->field('users_money, scores')->where('users_id', $this->users_id)->find();
        if (intval($pointsGoods['goodsTotalPoints']) > intval($usersInfo['scores'])) $this->error('您的积分不足');

        // 判断会员余额是否足够支付
        if (2 === intval($this->param['pay_type']) && !empty($result['payBalanceOpen'])) {
            if (unifyPriceHandle($pointsGoods['goodsTotalPrice']) > unifyPriceHandle($usersInfo['users_money'])) $this->error('您的余额不足');
        }

        // 添加到订单主表
        $orderData = [
            'order_code'         => date('Ymd') . $this->times . rand(10, 100),
            'users_id'           => $this->users_id,
            'order_status'       => 0,
            'add_time'           => $this->times,
            'payment_method'     => 0,
            'pay_time'           => 0,
            'pay_name'           => 'wechat',
            'wechat_pay_type'    => 'WeChatInternal',
            'order_terminal'     => 3,
            'pay_details'        => '',
            'order_total_amount' => unifyPriceHandle($pointsGoods['goodsSinglePrice']),
            'order_amount'       => unifyPriceHandle($pointsGoods['goodsTotalPrice']),
            'order_total_num'    => intval($pointsGoods['goodsBuyNumber']),
            'prom_type'          => intval($pointsGoods['prom_type']),
            'virtual_delivery'   => '',
            'admin_note'         => '',
            'user_note'          => $this->param['user_note'],
            'logistics_type'     => !empty($this->param['deliveryShow']) ? 1 : 2,
            'points_shop_order'  => 1,
        ];

        // 快递配送
        if (!empty($address) && !empty($this->param['deliveryShow'])) {
            $orderData['city'] = !empty($address['city']) ? $address['city'] : '';
            $orderData['mobile'] = !empty($address['mobile']) ? $address['mobile'] : '';
            $orderData['country'] = !empty($address['country']) ? $address['country'] : '';
            $orderData['address'] = !empty($address['address']) ? $address['address'] : '';
            $orderData['province'] = !empty($address['province']) ? $address['province'] : '';
            $orderData['district'] = !empty($address['district']) ? $address['district'] : '';
            $orderData['consignee'] = !empty($address['consignee']) ? $address['consignee'] : '';
            $orderData['shipping_fee'] = !empty($address['template_money']) ? $address['template_money'] : '';
        }

        // 积分商品售后服务处理
        if (!empty($weappInfoData['afterSale']) && 1 === intval($weappInfoData['afterSale'])) {
            // 读取系统设置
            $order_right_protect_time = getUsersConfigData('order.order_right_protect_time');
            $orderData['allow_service'] = empty($order_right_protect_time) ? 1 : 0;
        } else if (!empty($weappInfoData['afterSale']) && 2 === intval($weappInfoData['afterSale'])) {
            // 积分商城自定义售后规则
            $orderData['allow_service'] = !empty($weappInfoData['afterSaleRule']) && 1 === intval($weappInfoData['afterSaleRule']) ? 1 : 0;
        }

        // 如果实际支付金额和运费都为0则为纯积分支付，订单支付类型变更为无需支付
        if (3 === intval($this->param['pay_type']) && empty($orderData['order_amount'])) {
            $orderData['pay_name'] = 'noNeedPay';
            $orderData['wechat_pay_type'] = '';
        }

        // 支付方式处理
        if (1 === intval($this->param['pay_type']) && !empty($this->param['payment_type']) && 'h5' == $this->param['terminal']) {
            $pay_mark = explode('_', $this->param['payment_type'])[1];
            $payApiConfig = Db::name('pay_api_config')->where(['pay_mark' => $pay_mark])->find();
            if (empty($payApiConfig)) $this->error('请选择正确的支付方式');
            $orderData['pay_name'] = $pay_mark;
            $orderData['wechat_pay_type'] = '';
            $result['payApiConfig'] = $payApiConfig;
        }
        else if (!empty($this->param['provider']) && 'h5' == $this->param['provider']) {
            $pay_mark = 'wechat';
            $payApiConfig = Db::name('pay_api_config')->where(['pay_mark' => $pay_mark])->find();
            if (empty($payApiConfig)) $this->error('请选择正确的支付方式');
            $orderData['pay_name'] = $pay_mark;
            $orderData['wechat_pay_type'] = '';
            $result['payApiConfig'] = $payApiConfig;
        }

        // 获取消费获得积分数据
        $orderData['obtain_scores'] = getConsumObtainScores($orderData, getUsersConfigData('all'), true);
        $orderData['is_obtain_scores'] = !empty($orderData['obtain_scores']) ? 0 : 1;

        // 如果已经提交过订单则删除原先的订单
        if ('h5' == $this->param['terminal'] && !empty($this->param['order_id']) && !empty($this->param['order_code'])) {
            $where = [
                'order_id' => $this->param['order_id'],
                'order_code' => $this->param['order_code'],
            ];
            Db::name('shop_order')->where($where)->delete(true);
        }

        // 添加积分商城订单
        $orderID = Db::name('shop_order')->insertGetId($orderData);
        if (!empty($orderID)) {
            $orderData['order_id'] = $orderID;

            // 订单创建后续处理 -- 其他逻辑公共调用方法，部分逻辑改动不适合直接修改原文件时请在此方法做处理和兼容
            $orderData = model('ShopPublicHandle')->orderCreatePublicHandle($orderData, [], $this->users_id, $this->param);

            // 系统商品规格表信息
            $spec_value = $this->getSystemGoodsSpec($pointsGoods['aid'], $pointsGoods['goodsSpecKeys'], true);

            // 系统商品属性表信息
            $attr_value_new = $this->getSystemGoodsAttr($pointsGoods['aid'], $pointsGoods['attrlist_id'], true);

            // 获取积分商品下单购买需要存入订单副表的字段数据
            $pointsGoodsBuyField = $this->getPointsGoodsBuyField($pointsGoods);

            // 规格及属性
            $paramData = [
                // 系统商品规格表信息
                'spec_value' => htmlspecialchars($spec_value),
                // 系统商品规格表组合值
                'spec_value_id' => $pointsGoods['goodsSpecKeys'],
                // 系统商品属性表信息
                'attr_value_new' => htmlspecialchars($attr_value_new),
                // 积分商品下单购买需要存入订单副表的字段数据
                'pointsGoodsBuyField' => json_encode($pointsGoodsBuyField),
            ];

            // 添加订单副表
            $detailsData = [
                'order_id'      => $orderID,
                'users_id'      => $this->users_id,
                'product_id'    => $pointsGoods['aid'],
                'product_name'  => $pointsGoods['title'],
                'num'           => $pointsGoods['goodsBuyNumber'],
                'data'          => serialize($paramData),
                'product_price' => $pointsGoods['goods_price'],
                'prom_type'     => $pointsGoods['prom_type'],
                'litpic'        => $pointsGoods['litpic'],
                'add_time'      => $this->times,
            ];
            $details_id = Db::name('shop_order_details')->insertGetId($detailsData);
            if (!empty($details_id)) {
                // 数据赋值返回
                $result['usersInfo'] = $usersInfo;
                $result['orderData'] = $orderData;
                $result['detailsData'] = $detailsData;

                // 清除缓存数据
                // if ('h5' != $this->param['terminal']) Cache::rm($this->param['cacheKeys']);

                // 添加订单操作记录
                AddOrderAction($orderID, $this->users_id, 0, 0, 0, 0, '提交订单', '会员提交积分订单成功');
            } else {
                Db::name('shop_order')->where('order_id', $orderID)->delete(true);
                $this->error('订单提交失败，请重新选择商品提交');
            }
        }
    }

    // 积分商品订单提交支付逻辑
    public function pointsGoodsOrderBuyPay($result = [])
    {
        // 微信小程序支付
        if (1 === intval($this->param['pay_type'])) {
            if ('h5' == $this->param['terminal']) {
                // 返回支付所需参数
                $resultData = [
                    'transaction_type' => 2,
                    'pay_id' => $result['payApiConfig']['pay_id'],
                    'pay_mark' => $result['payApiConfig']['pay_mark'],
                    'unified_id' => $result['orderData']['order_id'],
                    'unified_number' => $result['orderData']['order_code'],
                ];
            }
            else if (!empty($this->param['provider']) && 'h5' == $this->param['provider']) {
                $openid = Db::name('users')->where('users_id', $this->users_id)->value('open_id');
                $row = $this->wechatLogic->get_wechat_pay_config();
                $order_id = $result['orderData']['order_id'];
                $order_code = $result['orderData']['order_code'];
                $order_amount = $result['orderData']['order_amount'];

                $payApiModel = new \app\user\model\PayApi;
                $weChatPay = $payApiModel->getWechatPay($openid, $order_code, $order_amount, $row);
                if (!empty($weChatPay['postCode']) && 'error' === $weChatPay['postCode']) {
                    $this->error($weChatPay['return_msg']);
                } else if (!empty($weChatPay)) {
                    $result = [
                        'weChatPay' => $weChatPay,
                        'orderData' => [
                            'order_id' => $order_id,
                            'order_code' => $order_code,
                        ]
                    ];
                    $this->success('正在支付', null, $result);
                }
            }
            else {
                if (!empty($this->param['sendTerminal']) && 'visualiz' == $this->param['sendTerminal']) {
                    $openid = Db::name('weapp_diyminipro_mall_users')->where('users_id', $this->users_id)->getField('openid');
                    $data = model('DiyminiproMallShop')->GetWechatAppletsPay($openid, $result['orderData']['order_code'], $result['orderData']['order_amount']);
                } else {
                    $notify_url = '';//url('plugins/PointsShop/wechatPayCallback', [], true, true, 1, 1, 0);
                    $openid = !empty($this->users['open_id']) ? $this->users['open_id'] : Db::name('wx_users')->where('users_id', $this->users_id)->getField('openid');
                    $data = model('v1.Shop')->GetWechatAppletsPay($openid, $result['orderData']['order_code'], $result['orderData']['order_amount'], $notify_url);
                }
                $resultData = [
                    'weChatPay' => $data,
                    'orderData' => [
                        'order_id'   => $result['orderData']['order_id'],
                        'order_code' => $result['orderData']['order_code']
                    ],
                ];
            }
            // 已开启的微信订阅消息模板
            // $where = [
            //     'is_open' => 1,
            //     'send_scene' => ['IN', [7]],
            //     'template_code' => ['GT', 0],
            // ];
            // $tmplData = Db::name('applets_template')->where($where)->order('send_scene asc')->getAllWithIndex('template_id');
            $resultData['tmplData'] = [];//$tmplData;
            // 返回提示
            $this->success('正在支付', null, $resultData);
        }
        // 余额支付
        else if (2 === intval($this->param['pay_type'])) {
            // 设置订单为已付款
            $where = [
                'order_id' => $result['orderData']['order_id'],
            ];
            $payDetails = [
                'unified_id'     => $result['orderData']['order_id'],
                'unified_number' => $result['orderData']['order_code'],
                'payment_amount' => $result['orderData']['order_amount'],
                'payment_type'   => '余额支付'
            ];
            $update = [
                'order_status'    => 1,
                'pay_name'        => 'balance',
                'wechat_pay_type' => '',
                'pay_details'     => serialize($payDetails),
                'pay_time'        => $this->times,
                'update_time'     => $this->times
            ];
            $result['orderData'] = array_merge($result['orderData'], $update);
            $updateID = Db::name('shop_order')->where($where)->update($update);
            if (!empty($updateID)) {
                // 扣除会员余额和积分
                $where = [
                    'users_id' => $this->users_id,
                ];
                $update = [
                    'scores' => floatval($result['usersInfo']['scores']) - floatval($result['pointsGoods']['goodsTotalPoints']),
                    'users_money' => floatval($result['usersInfo']['users_money']) - floatval($result['pointsGoods']['goodsTotalPrice']),
                    'update_time' => $this->times
                ];
                $updateID = Db::name('users')->where($where)->update($update);
                if (!empty($updateID)) {
                    // 添加会员余额记录
                    $params = [
                        'users_id' => $this->users_id,
                        'users_money' => $result['usersInfo']['users_money'],
                    ];
                    UsersMoneyAction($result['orderData']['order_code'], $params, $result['orderData']['order_amount'], '积分订单支付');

                    // 积分商品支付处理数据
                    $resultData = $this->pointsOrderPayHandleData($result, 'balancePay');

                    // 返回结束
                    $this->success('支付完成', '/pages/order/index', $resultData);
                }
            }
        }
        // 纯积分支付(无需支付)
        else if (3 === intval($this->param['pay_type'])) {
            // 设置订单为已付款
            $where = [
                'order_id' => $result['orderData']['order_id'],
            ];
            $payDetails = [
                'unified_id'     => $result['orderData']['order_id'],
                'unified_number' => $result['orderData']['order_code'],
                'payment_amount' => $result['orderData']['order_amount'],
                'payment_type'   => '纯积分支付'
            ];
            $update = [
                'order_status'    => 1,
                'pay_name'        => 'noNeedPay',
                'wechat_pay_type' => '',
                'pay_details'     => serialize($payDetails),
                'pay_time'        => $this->times,
                'update_time'     => $this->times
            ];
            $updateID = Db::name('shop_order')->where($where)->update($update);
            if (!empty($updateID)) {
                // 扣除会员积分
                $where = [
                    'users_id' => $this->users_id,
                ];
                $update = [
                    'scores' => floatval($result['usersInfo']['scores']) - floatval($result['pointsGoods']['goodsTotalPoints']),
                    'update_time' => $this->times
                ];
                $updateID = Db::name('users')->where($where)->update($update);
                if (!empty($updateID)) {
                    // 积分商品支付处理数据
                    $resultData = $this->pointsOrderPayHandleData($result, 'noNeedPay');

                    // 返回结束
                    $this->success('支付完成', '/pages/order/index', $resultData);
                }
            }
        }
    }

    // 积分商品支付处理数据
    public function pointsOrderPayHandleData($result = [], $pay_method = 'balancePay')
    {
        $resultData['orderData'] = $result['orderData'];

        // 添加会员积分记录
        $insert = [
            'type' => 11, // 积分商城订单支付
            'users_id' => $this->users_id,
            'score' => $result['pointsGoods']['goodsTotalPoints'],
            'info' => '积分商城订单支付',
            'remark' => '积分商城订单支付',
        ];
        addConsumObtainScores($insert, 1, false);

        // 添加订单操作记录
        $pay_method_name = 'balancePay' === trim($pay_method) ? '余额' : '积分';
        AddOrderAction($result['orderData']['order_id'], $this->users_id, 0, 1, 0, 1, '支付成功', '会员使用'.$pay_method_name.'完成积分订单支付');

        // 虚拟自动发货
        $systemPayModel = new \app\user\model\Pay();
        $where = [
            'users_id' => $this->users_id,
            'order_id' => $result['orderData']['order_id']
        ];
        $systemPayModel->afterVirtualProductPay($where);

        // 统计销售额
        eyou_statistics_data(2);
        eyou_statistics_data(3, $result['orderData']['order_amount']);

        // 发送站内信给后台
        $result['orderData']['pay_method'] = 'balancePay' === trim($pay_method) ? '余额支付' : '无需支付';
        SendNotifyMessage($result['orderData'], 5, 1, 0);

        // 已开启的微信订阅消息模板
        // $where = [
        //     'is_open' => 1,
        //     'send_scene' => ['IN', [7]],
        //     'template_code' => ['GT', 0],
        // ];
        // $tmplData = Db::name('applets_template')->where($where)->order('send_scene asc')->getAllWithIndex('template_id');
        $resultData['tmplData'] = [];//$tmplData;

        // 微信公众号消息推送
        $resultData['weChat'] = model('ShopPublicHandle')->getSendWeChatContent($this->users, $result['orderData'], [30, 50]);

        // 邮箱消息推送
        $resultData['email'] = [];
        // 订单付款邮箱推送
        $orderPay = model('ShopPublicHandle')->getSendEamilContent($this->users, $result['orderData'], [30, 50]);
        if (!empty($orderPay)) $resultData['email'] = [$orderPay];
        // 余额变动邮箱推送
        if ('balancePay' === trim($pay_method) && !empty($result['pointsGoods']['goods_price'])) {
            $usersMoney = model('ShopPublicHandle')->getSendEamilContent($this->users, $result['orderData'], [35]);
            if (!empty($usersMoney)) $resultData['email'] = array_merge($resultData['email'], [$usersMoney]);
        }
        // 积分变动邮箱推送
        if (!empty($result['pointsGoods']['goods_points'])) {
            $result['orderData']['order_points'] = intval($result['pointsGoods']['goods_points']);
            $usersPoints = model('ShopPublicHandle')->getSendEamilContent($this->users, $result['orderData'], [34]);
            if (!empty($usersPoints)) $resultData['email'] = array_merge($resultData['email'], [$usersPoints]);
        }
        // 商品库存预警邮箱推送
        $stockWarningEmail = model('ShopPublicHandle')->goodsStockWarningSendContent($this->users, [$result['pointsGoods']], $result['orderData']['order_id'], $this->usersConfig['goods_stock_warning']);
        if (!empty($stockWarningEmail)) $resultData['email'] = array_merge($resultData['email'], $stockWarningEmail);
        // 把发送的ID进行字符串处理
        $resultData['email'] = !empty($resultData['email']) ? implode(',', $resultData['email']) : false;

        // 手机短信消息推送
        $resultData['mobile'] = [];
        // 订单付款手机短信
        $orderPay = model('ShopPublicHandle')->getSendMobileContent($this->users, $result['orderData'], [30, 50]);
        if (!empty($orderPay)) $resultData['mobile'] = [$orderPay];
        // 余额变动手机短信
        if ('balancePay' === trim($pay_method) && !empty($result['pointsGoods']['goods_price'])) {
            $usersMoney = model('ShopPublicHandle')->getSendMobileContent($this->users, $result['orderData'], [35]);
            if (!empty($usersMoney)) $resultData['mobile'] = array_merge($resultData['mobile'], [$usersMoney]);
        }
        // 积分变动手机短信
        if (!empty($result['pointsGoods']['goods_points'])) {
            $result['orderData']['order_points'] = intval($result['pointsGoods']['goods_points']);
            $usersPoints = model('ShopPublicHandle')->getSendMobileContent($this->users, $result['orderData'], [34]);
            if (!empty($usersPoints)) $resultData['mobile'] = array_merge($resultData['mobile'], [$usersPoints]);
        }
        // 商品库存预警手机短信
        $stockWarningMobile = model('ShopPublicHandle')->goodsStockWarningSendContent($this->users, [$result['pointsGoods']], $result['orderData']['order_id'], $this->usersConfig['goods_stock_warning'], 'mobile');
        if (!empty($stockWarningMobile)) $resultData['mobile'] = array_merge($resultData['mobile'], $stockWarningMobile);
        // 把发送的ID进行字符串处理
        $resultData['mobile'] = !empty($resultData['mobile']) ? implode(',', $resultData['mobile']) : false;

        // 清除缓存数据
        // if ('h5' == $this->param['terminal']) Cache::rm($this->param['cacheKeys']);

        // 返回数据
        return $resultData;
    }

    // 积分商城插件积分订单商品详情处理
    public function pointsGoodsOrderDetails($goodsList = [])
    {
        // 提取订单详情记录的积分商品信息
        $pointsGoodsBuyField = [];
        foreach ($goodsList as $key => $value) {
            $data = !empty($value['data']) ? unserialize($value['data']) : [];
            $pointsGoodsBuyField[$value['order_id']] = !empty($data['pointsGoodsBuyField']) ? json_decode($data['pointsGoodsBuyField'], true) : [];
        }
        return $pointsGoodsBuyField;
    }
}
