<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <thinkcmf@126.com>
// +----------------------------------------------------------------------
namespace app\api\controller;

use app\admin\model\Car;
use app\admin\model\Ogoods;
use app\admin\model\Order;
use app\admin\model\Rcoupon;
use think\Db;
use think\db\Query;
/**
 * 公共方法
 */
class Common
{
    /**
     * 查找单条数据(软删除)
     * @ApiInternal
     */
    public static function findSoftWhereData($table,$where,$field,$except=false,$order='id desc'){
        $res = Db::name($table)
            ->where($where)
            ->field($field,$except)
            ->order($order)
            ->useSoftDelete('deletetime')
            ->find();
        return $res;
    }

    /**
     * 查找单条数据(有排序)
     * @ApiInternal
     */
    public static function findWhereData($table,$where,$field,$order='id desc'){
        $res = Db::name($table)
            ->where($where)
            ->field($field)
            ->order($order)
            ->find();
        return $res;
    }

    /**
     * 查找多条数据(无条件)
     * @ApiInternal
     */
    public static function selectData($table,$field,$order='id desc'){
        $res = Db::name($table)
            ->field($field)
            ->order($order)
            ->select();
        return $res;
    }

    /**
     * 查找多条数据
     * @ApiInternal
     */
    public static function selectWhereData($table,$where,$field,$order='id desc'){
        $res = Db::name($table)
            ->where($where)
            ->field($field)
            ->order($order)
            ->select();
        return $res;
    }

    /**
     * 查找多条数据
     * @ApiInternal
     */
    public static function selectWherePageData($table,$where,$field,$page,$limit='',$order='id desc'){
        if($limit == ''){
            $limit = config('verify.limit');
        }
        $res = Db::name($table)
            ->where($where)
            ->field($field)
            ->page($page,$limit)
            ->order($order)
            ->select();
        return $res;
    }

    /**
     * 查找多条数据(软删除)
     * @ApiInternal
     */
    public static function selectSoftData($table,$field,$order='id desc'){
        $res = Db::name($table)
            ->field($field)
            ->order($order)
            ->useSoftDelete('deletetime')
            ->select();
        return $res;
    }

    /**
     * 查找多条数据
     * @ApiInternal
     */
    public static function selectSoftWhereData($table,$where,$field,$order='id desc'){
        $res = Db::name($table)
            ->where($where)
            ->field($field)
            ->order($order)
            ->useSoftDelete('deletetime')
            ->select();
        return $res;
    }

    /**
     * 查找多条数据(软删除,分页)
     * @ApiInternal
     */
    public static function selectSoftWherePageData($table,$where,$field,$page,$limit='',$order='id desc'){
        if($limit == ''){
            $limit = config('verify.limit');
        }
        $res = Db::name($table)
            ->where($where)
            ->field($field)
            ->page($page,$limit)
            ->order($order)
            ->useSoftDelete('deletetime')
            ->select();
        return $res;
    }

    /**
     * 查找多条数据(软删除,分页)
     * @ApiInternal
     */
    public static function selectSoftPageData($table,$field,$page,$limit='',$order='id desc'){
        if($limit == ''){
            $limit = config('verify.limit');
        }
        $res = Db::name($table)
            ->field($field)
            ->page($page,$limit)
            ->order($order)
            ->useSoftDelete('deletetime')
            ->select();
        return $res;
    }

    /**
     * 查找多条数据(软删除,限制条数)
     * @ApiInternal
     */
    public static function selectSoftWhereLimitData($table,$where,$field,$order='id desc'){
        $limit = config('verify.limit');
        $res = Db::name($table)
            ->where($where)
            ->field($field)
            ->limit($limit)
            ->order($order)
            ->useSoftDelete('deletetime')
            ->select();
        return $res;
    }

    /**
     * 查找多条数据(软删除,无条件,限制条数)
     * @ApiInternal
     */
    public static function selectSoftLimitData($table,$field,$limit,$order='id desc'){
        $res = Db::name($table)
            ->field($field)
            ->limit($limit)
            ->order($order)
            ->useSoftDelete('deletetime')
            ->select();
        return $res;
    }

    /**
     * 查询总页数
     * @ApiInternal
     */
    public static function count($table,$where,$limit=''){
        if($limit == ''){
            $limit = config('verify.limit');
        }
        $count = Db::name($table)
            ->where($where)
            ->count();
        return ceil($count/$limit);
    }

    /**
     * 查询总条数
     * @ApiInternal
     */
    public static function count_count($table,$where){
        $count = Db::name($table)
            ->where($where)
            ->count();
        return $count;
    }

    /**
     * 查询总页数(软删除)
     * @ApiInternal
     */
    public static function countSoft($table,$where='',$limit=''){
        if(empty($limit)){
            $limit = config('verify.limit');
        }

        if(empty($where)){
            $count = Db::name($table)->useSoftDelete('deletetime')->count();
        }else{
            $count = Db::name($table)->where($where)->useSoftDelete('deletetime')->count();
        }
        return ceil($count/$limit);
    }

    /**
     * 查询总数(软删除)
     * @ApiInternal
     */
    public static function countSoftTotal($table,$where){
        $count = Db::name($table)
            ->where($where)
            ->useSoftDelete('deletetime')
            ->count();
        return $count;
    }

    /**
     * 商品列表
     * @ApiInternal
     */
    public static function goodsList($where='',$page,$uid='',$limit='',$order='id desc',$flag = '',$flag1=''){
        $arr = [];
        //默认未登录
        $is_news = self::is_new($uid);
        if(empty($where)){
            if($is_news == 1){
                //去除含有新人标签的数据
                $res = Common::selectSoftWherePageData('goods',['is_new'=>0],'id,image,name,tag,style,sale_price1 sale_price,expense_price,is_new',$page,$limit,$order);
            }else{
                $res = Common::selectSoftPageData('goods','id,image,name,tag,style,sale_price1 sale_price,expense_price,is_new',$page,$limit,$order);
            }
        }else{
            if($is_news == 1){
                //旧人
                $where['is_new'] = 0;
            }
            $res = Common::selectSoftWherePageData('goods',$where,'id,image,name,tag,style,sale_price1 sale_price,expense_price,is_new',$page,$limit,$order);
        }

        foreach ($res as &$value){
            if($is_news == 2 || $is_news == 0){//未登录或者新人
                if($value['is_new'] == 0){
                    //非新人优惠标签
                    $value['is_new_tag'] = 0;//不用显示新人价标签
                }else{
                    //新人优惠标签
                    $value['is_new_tag'] = 1;//显示新人价标签
                }
            }else{
                $value['is_new_tag'] = 0;//不用显示新人价标签(新人价标签商品不会出来)
            }
            $value['image'] = self::absolutionUrlOne($value['image']);
            $value['style'] = explode('|',$value['style']);
            $value['tag'] = explode('|',$value['tag']);
            $sale_price = self::salePrice($value['sale_price']);
            if($sale_price){
                $value['sale_price'] = $sale_price[0];
            }else{
                $value['sale_price'] = '';
            }
            unset($value['is_new']);
        }
        if(!empty($flag1)){
            //销售价格排序
            if($flag1 == 1){
                //倒序
                $sale_price = array_column($res,'sale_price');
                array_multisort($sale_price,SORT_DESC,$res);
            }else{
                //正序
                $sale_price = array_column($res,'sale_price');
                array_multisort($sale_price,SORT_ASC,$res);
            }
        }

        $arr['data'] = $res;
        //总页数
        if(empty($where)){
            if($is_news == 1){
                $arr['total_page'] = self::countSoft('goods',['is_new'=>0],$limit);
            }else{
                $arr['total_page'] = self::countSoft('goods','',$limit);
            }
        }else{
            $arr['total_page'] = self::countSoft('goods',$where,$limit);
        }
        if(empty($flag)){
            return $arr;
        }else{
            return $res;
        }
    }

    /**
     * 是否是新人
     * @ApiInternal
     */
    public static function is_new($uid){
        $is_news = 2;
        if(!empty($uid)){
            //已登录
            $res1 = self::findSoftWhereData('order',['uid'=>$uid,'status'=>config('verify.status')[8]],'id');
            if($res1){
                $is_news = 1;//旧人
            }else{
                $is_news = 0;//新人
            }
        }
        return $is_news;
    }

    /**
     * 检索商品列表
     * @ApiInternal
     */
    public static function searchGoodsList($keyword,$where,$page,$uid){
        $arr = [];
        //默认未登录
        $is_news = self::is_new($uid);
        if($is_news == 1){
            $where['is_new'] = 0;
        }
        $limit = config('verify.limit');
        $res = Db::name('goods')
            ->field('LOCATE("'.$keyword.'",name) as nameIndex,id,image,name,tag,is_new,style,sale_price1 sale_price,expense_price')//获取关键字的位置:LOCATE(关键字,字段) 返回索引位置
            ->where($where)//多字段条件查询
            ->page($page,$limit)
            ->order('nameIndex')//按tIndex 值排序
            ->select();
        foreach ($res as &$value){
            if($is_news == 2 || $is_news == 0){//未登录或者新人
                if($value['is_new'] == 0){
                    //非新人优惠标签
                    $value['is_new_tag'] = 0;//不用显示新人价标签
                }else{
                    //新人优惠标签
                    $value['is_new_tag'] = 1;//显示新人价标签
                }
            }else{
                $value['is_new_tag'] = 0;//不用显示新人价标签(新人价标签商品不会出来)
            }

            $value['image'] = self::absolutionUrlOne($value['image']);
            $value['tag'] = explode('|',$value['tag']);
            $value['style'] = explode('|',$value['style']);
            $sale_price = self::salePrice($value['sale_price']);
            if($sale_price){
                $value['sale_price'] = $sale_price[0];
            }else{
                $value['sale_price'] = '';
            }

            $value['str_count'] = 0;
            if(strpos($value['name'],$keyword) !== false){
                //包含
                $value['name'] = str_replace($keyword,'<a href="javascript:void(0);" style="color:red;">'.$keyword.'</a>',$value['name']);
                $value['str_count'] = substr_count($value['name'],$keyword);
            }
            unset($value['is_new']);
        }
        $str_count = array_column($res,'str_count');
        array_multisort($str_count,SORT_DESC,$res);
        $arr['data'] = $res;
        //总页数
        $arr['total_page'] = Common::countSoft('goods',$where);
        return $arr;
    }

    /**
     * 价格字符串转数组
     * @ApiInternal
     */
    public static function salePrice($string=''){
        $arr = [];
        if(!empty($string)){
            $arr = explode('|',$string);
        }
        return $arr;
    }

    /**
     * 单张相对路径转绝对路径
     * @ApiInternal
     */
    public static function absolutionUrlOne($image){
        $url = '';
        if(!empty($image)){
            $host = config('verify.host');
            $url = $host.$image;
        }
        return $url;
    }

    /**
     * @param $style 传递规格
     * @param $goods_number 传递数量
     * @param $g_style 数据库商品规格
     * @param $g_stock 数据库商品库存
     * @ApiInternal
     * @return bool
     */
    public static function checkStock($style,$goods_number,$g_style,$g_stock){
        $s_index = array_search($style,self::salePrice($g_style));
        $stock = self::salePrice($g_stock)[$s_index];
        if(($stock <=> $goods_number) == -1){
            //库存不足
            return false;
        }
        return true;
    }

    /**
     * 合并数组
     * @ApiInternal
     */
    public static function array_merge_more($keys, ...$arrs){
        // 检查参数是否正确
        if(!$keys || !is_array($keys) || !$arrs || !is_array($arrs) || count($keys)!=count($arrs)){
            return array();
        }
        // 一维数组中最大长度
        $max_len = 0;
        // 整理数据,把所有一维数组转重新索引
        for($i=0,$len=count($arrs); $i<$len; $i++){
            $arrs[$i] = array_values($arrs[$i]);

            if(count($arrs[$i])>$max_len){
                $max_len = count($arrs[$i]);
            }
        }
        // 合拼数据
        $result = array();
        for($i=0; $i<$max_len; $i++){
            $tmp = array();
            foreach($keys as $k=>$v){
                if(isset($arrs[$k][$i])){
                    $tmp[$v] = $arrs[$k][$i];
                }
            }
            $result[] = $tmp;
        }
        return $result;
    }

    /**
     * 订单号
     * @ApiInternal
     */
    public static function genOrderSn() {
        $res = Db::name('order')->field('id,order_sn')->order('id desc')->find();
        if($res){
            $order_sn = $res['order_sn'];
            $order_sn++;
        }else{
            $order_sn = '1000001';
        }
        return $order_sn;
    }

    /**
     * 支付订单号
     * @ApiInternal
     */
    public static function genPayOrderSn($letter = '') {
        $time = explode (" ", microtime ());
        $timeArr = explode('.',$time [0]);
        $mtime = array_pop($timeArr);
        $fulltime = $letter.$time[1].$mtime.mt_rand(1000,9999);
        return $fulltime;
    }

    /**
     * 写入订单数据
     * @ApiInternal
     */
    public static function createOrder($data,$pay_order_sn,$uid,$status=''){
        Db::startTrans();
        //写入订单主表
        $data1['order_sn'] = self::genOrderSn();
        $data1['pay_order_sn'] = $pay_order_sn;
        $data1['uid'] = $uid;
        $data1['receive_name'] = $data['receive_name'];
        $data1['receive_mobile'] = $data['receive_mobile'];
        $data1['receive_address'] = $data['receive_address'];
        if(isset($data['leave_message']) && !empty($data['leave_message'])){
            $data1['leave_message'] = $data['leave_message'];//留言
        }
        if(isset($data['coupon_id']) && !empty($data['coupon_id'])){
            $data1['coupon_id'] = $data['coupon_id'];//优惠券id
        }
        if(!empty($status)){
            $data1['status'] = $status;//更新支付成功
        }
        $data1['total_goods_price'] = $data['total_goods_price'];//商品金额
        $data1['discount_price'] = $data['discount_price'];//优惠金额
        $data1['total_expense_price'] = $data['total_expense_price'];//运费总金额
        $data1['total_price'] = $data['total_price'];//商+运-优惠
        $orderModel = new Order();
        $res1 = $orderModel->create($data1);
        //写入订单附加表
        $goods_id_s = explode(',',$data['goods_id']);
        $price_s = explode(',',$data['price']);
        $goods_number_s = explode(',',$data['goods_number']);
        $style_s = explode(',',$data['style']);
        //合并数组
        $key = ['g_id','price','goods_number','style'];
        $res_goods = self::array_merge_more($key,$goods_id_s,$price_s,$goods_number_s,$style_s);
        $o_id = $res1->id;
        foreach($res_goods as &$value){
            $value['o_id'] = $o_id;
        }
        $oGoodsModel = new Ogoods();
        $res2 = $oGoodsModel->saveAll($res_goods);
        if($res1 && $res2){
            Db::commit();
            $arr['order_id'] = $o_id;
            return $arr;
        }else{
            Db::rollback();
            return false;
        }
    }

    /**
     * 减库存
     * @ApiInternal
     */
    public static function decStock($where){
        $goodsModel = new \app\admin\model\Goods();
        $goodsModel->where($where)->setDec('stock',1);
    }

    /**
     * 增销量
     * @ApiInternal
     */
    public static function incSales($where,$sale_number){
        $goodsModel = new \app\admin\model\Goods();
        $goodsModel->where($where)->setInc('sales',$sale_number);
    }

    /**
     * 减少销量
     * @ApiInternal
     */
    public static function decSales($where,$sale_number){
        $goodsModel = new \app\admin\model\Goods();
        $goodsModel->where($where)->setDec('sales',$sale_number);
    }

    /**
     * 删购物车
     * @ApiInternal
     */
    public static function deleteCar($where){
        $carModel = new Car();
        $carModel->where($where)->delete();
    }

    /**
     * 更新优惠券
     * @ApiInternal
     */
    public static function updateRCoupon($uid,$coupon_id,$is_use){
        $rCouponModel = new Rcoupon();
        $rCouponModel->where(['uid'=>$uid,'c_id'=>$coupon_id])->update(['is_use'=>$is_use]);
    }

    /**
     * 购买成功,更新订单号为待发货,销量增加1,减库存,删除购物车
     * @ApiInternal
     */
    public static function paySuccess($out_trade_no){
        $status = config('verify.status');
        //更新订单号成功
        $orderModel = new Order();
        $orderModel->where(['pay_order_sn'=>$out_trade_no,'status'=>$status[0]])->update(['status'=>$status[2],'paytime'=>time()]);//待发货
        //销量增加1
        $res = self::findSoftWhereData('order',['pay_order_sn'=>$out_trade_no,'status'=>$status[2]],'id,uid,coupon_id');
        if($res){
            $res1 = self::selectSoftWhereData('ogoods',['o_id'=>$res['id']],'id,g_id,style,goods_number');
            $g_ids = array_column($res1,'g_id');
            //减库存
            $goodsModel = new \app\admin\model\Goods();
            //查询商品的库存
            $res_stock = self::selectSoftWhereData('goods',['id'=>['in',$g_ids]],'id,style g_style,stock');
            foreach($res_stock as $g_value){
                $arr_stock = explode('|',$g_value['stock']);
                $sale_number = 1;
                foreach($res1 as $value){
                    if($g_value['id'] == $value['g_id']){
                        $s_index = array_search($value['style'],self::salePrice($g_value['g_style']));
                        $stock = self::salePrice($g_value['stock'])[$s_index] - $value['goods_number'];
                        $arr_stock[$s_index] = $stock;
                        $sale_number = $value['goods_number'];
                    }
                }
                //更新库存
                $stock1 = implode('|',$arr_stock);
                $goodsModel->where(['id'=>$g_value['id']])->update(['stock'=>$stock1]);
                //增加销售
                self::incSales(['id'=>['in',$g_ids]],$sale_number);
            }
            //删除购物车
            self::deleteCar(['uid'=>$res['uid'],'g_id'=>['in',$g_ids]]);

            //更新优惠券已使用
            $flag = config('verify.flag');
            self::updateRCoupon($res['uid'],$res['coupon_id'],$flag[1]);
        }
    }

    /**
     * 支付检测库存
     * @ApiInternal
     */
    public static function checkPayStock($order_goods,$goods_id = ''){
        //检查库存
        if(empty($goods_id)){
            $goods_id_s = array_column($order_goods,'goods_id');
            //查询商品
            $res = self::selectSoftWhereData('goods',['id'=>['in',$goods_id_s]],'id,name,stock,style g_style');
        }else{
            //查询商品
            $res = self::selectSoftWhereData('goods',['id'=>['in',$goods_id]],'id,name,stock,style g_style');
        }

        foreach($order_goods as $g_value){
            foreach ($res as $value){
                if($value['id'] == $g_value['goods_id']){
                    //检测库存
                    $check_stock = self::checkStock($g_value['style'],$g_value['goods_number'],$value['g_style'],$value['stock']);
                    if(!$check_stock){
                        return '商品名称:'.$value['name'].',规格:'.$g_value['style'].'库存不足';
                    }
                }
            }
        }
        return true;
    }

    /**
     * @param $type (0:首页,1:商品浏览,2:商品收藏 )
     * @param int $uid
     * @param int $g_id
     * @ApiInternal
     */
    public static function statistics($type=0,$uid=0,$g_id=0){
        $arr['type'] = $type;
        $arr['uid'] = $uid;
        $arr['g_id'] = $g_id;
        $arr['createtime'] = time();
        Db::name('statistics')->insert($arr);
    }
}