* Date: 2020-05-07 */ namespace app\api\model\v1; use think\Db; use think\Cache; use think\Config; /** * 微信小程序商城订单模型 */ load_trait('controller/Jump'); class Shop extends UserBase { use \traits\controller\Jump; private $miniproInfo = []; //初始化 protected function initialize() { // 需要调用`Model`的`initialize`方法 parent::initialize(); $this->times = getTime(); $dataConf = tpSetting("OpenMinicode.conf_".self::$provider, [], self::$lang); $this->miniproInfo = json_decode($dataConf, true); } public function getCartTotalNum() { $cart_total_num = 0; if (!empty($this->users_id)){ $cart_total_num = Db::name('shop_cart')->where(['users_id' => $this->users_id])->sum('product_num'); } return $cart_total_num; } /*购物车操作--Start*/ // 页面点击直接添加购物车 public function ShopPageAddCart($post = []) { $post['product_id'] = intval($post['product_id']); $post['users_id'] = intval($post['users_id']); $post['product_num'] = intval($post['product_num']); // 查询条件 $ArchivesWhere = [ 'aid' => $post['product_id'], 'lang' => get_home_lang(), 'arcrank' => ['>=', 0] ]; $count = Db::name('archives')->where($ArchivesWhere)->count(); // 加入购物车处理 if (!empty($count)) { // 查询条件 $CartWhere = [ 'users_id' => $post['users_id'], 'product_id' => $post['product_id'], 'lang' => get_home_lang() ]; /*若开启多规格则执行*/ $usersConfig = getUsersConfigData('shop'); if (!empty($usersConfig['shop_open_spec'])) { $combiWhere = [ 'aid' => $post['product_id'], 'spec_stock' => ['>', 0], ]; //获取第一个有库存的规格 $Field = 'spec_value_id, spec_stock'; $SpecValue = Db::name('product_spec_value')->field($Field)->where($combiWhere)->order('value_id asc')->find(); if (!empty($SpecValue)) { if ($SpecValue['spec_stock'] > 0) { $post['spec_value_id'] = $CartWhere['spec_value_id'] = $SpecValue['spec_value_id']; } else { $this->error('商品已售罄'); } } } /* END */ $ProductNum = Db::name('shop_cart')->field('product_num')->where($CartWhere)->getField('product_num'); if (!empty($ProductNum)) { // 购物车内已有相同商品,进行数量更新。 $ResultID = Db::name('shop_cart')->where($CartWhere)->setInc('product_num', $post['product_num']); } else { // 购物车内还未有相同商品,进行添加。 $data = [ 'users_id' => $post['users_id'], 'product_id' => $post['product_id'], 'product_num' => $post['product_num'], 'spec_value_id' => empty($post['spec_value_id']) || 'undefined' == $post['spec_value_id'] ? '' : $post['spec_value_id'], 'selected' => 1, 'lang' => get_home_lang(), 'add_time' => getTime(), 'update_time' => getTime() ]; $ResultID = Db::name('shop_cart')->add($data); } if (!empty($ResultID)) { $cart_total_num = Db::name('shop_cart')->where(['users_id' => $post['users_id']])->sum('product_num'); $this->success('加入成功','',['cart_total_num'=>$cart_total_num]); } else { $this->error('加入失败'); } } else { $this->error('商品已下架'); } } /*购物车操作--Start*/ // 添加购物车 public function ShopAddCart($post = []) { $post['product_id'] = intval($post['product_id']); $post['users_id'] = intval($post['users_id']); $post['product_num'] = intval($post['product_num']); // 查询条件 $ArchivesWhere = [ 'aid' => $post['product_id'], 'lang' => get_home_lang(), 'arcrank' => ['>=', 0] ]; $count = Db::name('archives')->where($ArchivesWhere)->count(); // 加入购物车处理 if (!empty($count)) { // 查询条件 $CartWhere = [ 'users_id' => $post['users_id'], 'product_id' => $post['product_id'], 'lang' => get_home_lang() ]; if (!empty($post['discount_active_id'])){ $CartWhere['discount_active_id'] = $post['discount_active_id']; }else{ $CartWhere['discount_active_id'] = 0; } /*若开启多规格则执行*/ $usersConfig = getUsersConfigData('shop'); if (!empty($post['spec_value_id']) && 'undefined' != $post['spec_value_id'] && !empty($usersConfig['shop_open_spec'])) { $CartWhere['spec_value_id'] = $post['spec_value_id']; } /* END */ $ProductNum = Db::name('shop_cart')->field('product_num')->where($CartWhere)->getField('product_num'); if (!empty($ProductNum)) { // 购物车内已有相同商品,进行数量更新。 $ResultID = Db::name('shop_cart')->where($CartWhere)->setInc('product_num', $post['product_num']); } else { // 购物车内还未有相同商品,进行添加。 $data = [ 'users_id' => $post['users_id'], 'product_id' => $post['product_id'], 'product_num' => $post['product_num'], 'spec_value_id' => empty($post['spec_value_id']) || 'undefined' == $post['spec_value_id'] ? '' : $post['spec_value_id'], 'selected' => 1, 'lang' => get_home_lang(), 'add_time' => getTime(), 'update_time' => getTime(), 'discount_active_id' => !empty($CartWhere['discount_active_id']) ? $CartWhere['discount_active_id'] : 0 ]; $ResultID = Db::name('shop_cart')->add($data); } if (!empty($ResultID)) { $totalCart = Db::name('shop_cart')->where(['users_id' => $post['users_id']])->sum('product_num'); $this->success('加入成功','',['cart_total_num'=>$totalCart]); } else { $this->error('加入失败'); } } else { $this->error('商品已下架'); } } // 删除购物车商品 public function ShopCartDelete($param = []) { if (empty($param['users_id'])) $this->error('请先登录'); if (empty($param['action'])) $this->error('数据错误,请重试'); if ('[]' == $param['cart_id']) $this->error('选择要删除的商品'); $where = [ 'users_id' => intval($param['users_id']), 'cart_id' => ['IN', $param['cart_id']], ]; $ResultID = Db::name('shop_cart')->where($where)->delete(); if (!empty($ResultID)) { $totalCart = Db::name('shop_cart')->where(['users_id' => $param['users_id']])->sum('product_num'); $this->success('操作成功','',['cart_total_num'=>$totalCart]); } else { $this->error('操作失败'); } } // 购物车数据列表 public function ShopCartList($users_id = null, $level_discount = 100, $level_id = 0) { $result = []; $result['cart_list'] = []; if (!empty($users_id)) { // 查询购物车数据 $condition = [ 'a.users_id' => $users_id, 'a.lang' => get_home_lang(), 'b.arcrank' => array('egt', 0) ]; $field = 'a.*, b.aid, b.title, b.litpic, b.users_price, b.users_discount_type, b.stock_count, b.attrlist_id, c.spec_price, c.spec_stock'; if ('v1.5.1' < getVersion()) { $field .= ',c.seckill_price, c.seckill_stock'; } if ('v1.5.7' < getVersion()) { $field .= ',c.discount_price, c.discount_stock'; } $ShopCart = Db::name("shop_cart") ->field($field) ->alias('a') ->join('__ARCHIVES__ b', 'a.product_id = b.aid', 'LEFT') ->join('__PRODUCT_SPEC_VALUE__ c', 'a.spec_value_id = c.spec_value_id and a.product_id = c.aid', 'LEFT') ->where($condition) ->order('a.selected desc, a.add_time desc') ->select(); if (!empty($ShopCart)) { // 获取商城配置信息 $ConfigData = getUsersConfigData('shop'); // 会员折扣 $users_discount = strval($level_discount) / strval(100); // 处理购物车数据 $ShopCart = $this->OrderProductProcess($ShopCart, $ConfigData, $users_discount, $level_id); } $result['cart_list'] = $ShopCart; } $result['product'] = model('v1.Api')->getRecomProduct(); return $result; } // 购物车数量增加 public function ShopCartNumAdd($param = []) { if (empty($param['users_id'])) $this->error('请先登录'); if (empty($param['action']) || empty($param['product_id'])) $this->error('数据错误,请重试'); $where = [ 'users_id' => intval($param['users_id']), 'product_id' => intval($param['product_id']), ]; if (!empty($param['spec_value_id']) && 'undefined' != $param['spec_value_id']) { $where['spec_value_id'] = $param['spec_value_id']; } $ResultID = Db::name('shop_cart')->where($where)->setInc('product_num'); if (!empty($ResultID)) { $cart_total_num = Db::name('shop_cart')->where('users_id',$param['users_id'])->sum('product_num'); $this->success('操作成功','',['cart_total_num'=>$cart_total_num]); } else { $this->error('操作失败'); } } // 购物车数量减少 public function ShopCartNumLess($param = []) { if (empty($param['users_id'])) $this->error('请先登录'); if (empty($param['action']) || empty($param['product_id'])) $this->error('数据错误,请重试'); $where = [ 'users_id' => intval($param['users_id']), 'product_id' => intval($param['product_id']), ]; if (!empty($param['spec_value_id']) && 'undefined' != $param['spec_value_id']) { $where['spec_value_id'] = $param['spec_value_id']; } $product_num_tmp = Db::name('shop_cart')->where($where)->getField('product_num'); if (!empty($product_num_tmp)) { if ($product_num_tmp > 1) { $ResultID = Db::name('shop_cart')->where($where)->setDec('product_num'); if (!empty($ResultID)) { $cart_total_num = Db::name('shop_cart')->where('users_id',$param['users_id'])->sum('product_num'); $this->success('操作成功','',['cart_total_num'=>$cart_total_num]); } } else { $this->error('数量至少一件!'); } } $this->error('操作失败'); } // 购物车商品更新是否选中 public function ShopCartSelected($param = []) { if (empty($param['users_id'])) $this->error('请先登录'); if (empty($param['action']) || empty($param['product_id'])) $this->error('数据错误,请重试'); $where = [ 'users_id' => intval($param['users_id']), 'product_id' => intval($param['product_id']), ]; if (!empty($param['spec_value_id']) && 'undefined' != $param['spec_value_id']) { $where['spec_value_id'] = $param['spec_value_id']; } $update = [ 'selected' => $param['selected'] == 1 ? 0 : 1, 'update_time' => getTime() ]; $ResultID = Db::name('shop_cart')->where($where)->update($update); if (!empty($ResultID)) { $this->success('操作成功'); } else { $this->error('操作失败'); } } // 全选/反选 public function ShopCartAllSelected($param = []) { if (empty($param['users_id'])) $this->error('请先登录'); if (empty($param['action'])) $this->error('数据错误,请重试'); $where = [ 'users_id' => intval($param['users_id']), ]; $update = [ 'selected' => $param['all_selected'], 'update_time' => getTime() ]; $ResultID = Db::name('shop_cart')->where($where)->update($update); if (!empty($ResultID)) { $this->success('操作成功'); } else { $this->error('操作失败'); } } /*购物车操作--END*/ /*商城购物流程--Start*/ // 立即购买 public function ShopBuyNow($post = []) { // 查询条件 $ArchivesWhere = [ 'aid' => $post['product_id'], 'lang' => get_home_lang(), 'arcrank' => ['>=', 0] ]; $count = Db::name('archives')->where($ArchivesWhere)->count(); // 加入购物车处理 if (!empty($count)) { // 对ID和订单号加密,拼装url路径 $querydata = [ 'product_id' => $post['product_id'], 'product_num' => $post['product_num'], 'active_time_id' => isset($post['active_time_id']) ? $post['active_time_id'] : 0, 'discount_active_id' => isset($post['discount_active_id']) ? $post['discount_active_id'] : 0, ]; /*存在规格则执行*/ if (!empty($post['spec_value_id']) && 'undefined' != $post['spec_value_id']) { $querydata['spec_value_id'] = $post['spec_value_id']; } /* END */ // 先 json_encode 后 md5 加密信息 $querystr = md5(json_encode($querydata)); // 存入缓存,一天有效期 Cache::set($querystr, $querydata, 86400); // 跳转链接 if (1 == input('param.fenbao/d')) { $url = '?querystr=' . $querystr; } else { $url = '/pages/product_buy/index?querystr=' . $querystr; } $this->success('数据正确', $url, ['url'=>$url]); } else { $this->error('该商品不存在或已下架!'); } } // 获取商品信息进行展示 public function GetProductData($querystr = null, $users_id = null, $level_discount = 100, $users = [], $post = []) { if (empty($users_id)) $this->error('请先登录'); /* 商品信息 */ $CacheData = Cache::get($querystr); // 是否存在购买商品 $list = $this->GetBuyOrderList($CacheData, $users_id, $post); if (empty($list)) $this->error('链接失效,请重新下单'); //购物车下单 if (empty($CacheData)) { $logistics_type_arr = get_arr_column($list, 'logistics_type'); if (empty($post['deliveryShow']) && empty($post['verifyShow']) && in_array(1, $logistics_type_arr)) { $post['deliveryShow'] = 1; } } // 获取商城配置信息 $ConfigData = getUsersConfigData('shop'); // 会员折扣 $users_discount = strval($level_discount) / strval(100); if (!empty($CacheData['active_time_id'])){ //秒杀商品没有会员折扣 $users_discount = 0; } /* 商品规格/折扣数据处理 */ $list = $this->OrderProductProcess($list, $ConfigData, $users_discount, $users['level_id']); if (empty($list)) $this->error('商品库存不足或已过期!'); /* END */ /* 全局信息组装 */ $GlobalInfo = $this->GetGlobalInfo($ConfigData, $CacheData); /* END */ /* 商品数据整合处理 */ foreach ($list as $key => $value) { // 合计金额、合计数量计算 if ($value['users_price'] >= 0 && !empty($value['product_num'])) { // 计算单品小计 $list[$key]['subtotal'] = unifyPriceHandle($value['users_price'] * $value['product_num']); // 计算合计金额 $GlobalInfo['TotalAmount'] += $list[$key]['subtotal']; $GlobalInfo['TotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount']); // 计算合计数量 $GlobalInfo['TotalNumber'] += $value['product_num']; // 判断订单类型,目前逻辑:一个订单中,只要存在一个普通商品(实物商品,需要发货物流),则为普通订单 // 0表示为普通订单,1表示为虚拟订单,虚拟订单无需发货物流,无需选择收货地址,无需计算运费 if (empty($value['prom_type'])) $GlobalInfo['PromType'] = 0; } // 仅到店核销 if ('2' === $value['logistics_type']) $GlobalInfo['onlyVerify'] = true; // 仅物流配送 if ('1' === $value['logistics_type']) $GlobalInfo['onlyDelivery'] = true; // 物流配送 和 到店核销 都支持 if ('1,2' === $value['logistics_type']) $GlobalInfo['allLogisticsType'] = true; } /* END */ /* 默认地址 */ $address = Db::name('shop_address')->where('users_id', $users_id)->order('is_default desc')->find(); if (!empty($address)) { $address['region']['province'] = $this->GetRegionName($address['province']); $address['region']['city'] = $this->GetRegionName($address['city']); $address['region']['district'] = $this->GetRegionName($address['district']); $address['region']['detail'] = $address['address']; $address['address_all'] = $address['region']['province'] . $address['region']['city'] . $address['region']['district'] . $address['region']['detail']; if (!empty($GlobalInfo['shop_open_shipping'])) { /* 查询运费 */ $where['province_id'] = $address['province']; $template_money = Db::name('shop_shipping_template')->where($where)->getField('template_money'); if (0 == $template_money) { $where['province_id'] = 100000; $template_money = Db::name('shop_shipping_template')->where($where)->getField('template_money'); } $address['template_money'] = $template_money; /* END */ } else { $address['template_money'] = 0; } } else { $address['template_money'] = 0; } /* END */ // 最终支付总金额 if (!empty($post['deliveryShow']) && 1 === intval($post['deliveryShow'])) { // 订单总金额 + 运费金额 $GlobalInfo['PayTotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount'] + $address['template_money']); } else { $GlobalInfo['PayTotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount']); } // 数据返回 $ResultData = [ 'users' => $users, 'address' => $address, 'global_info' => $GlobalInfo, 'product_data' => $list ]; $ResultData['coupon_data'] = $this->getOrderCoupon($list,$users_id); $coupon_ids = get_arr_column($ResultData['coupon_data'],'coupon_id'); $ResultData['unuse_coupon_data'] = $this->getUnuseOrderCoupon($coupon_ids,$users_id); $this->success('数据正确', null, $ResultData); } /** * 获取该订单可用优惠券 */ public function getOrderCoupon($product_data,$user_id) { $aids = []; $aid_price = 0; $totol_price = 0; foreach ($product_data as $k => $v){ if (!empty($v['stop_buy']) && 1 == $v['stop_buy']){ continue; } if (!in_array($v['aid'],$aids)){ $aids[] = $v['aid']; $aid_price += $v['subtotal']; } $totol_price += $v['subtotal']; } $where['a.users_id'] = $user_id; $where['a.start_time'] = ['<=',getTime()]; $where['a.end_time'] = ['>=',getTime()]; $where['a.use_status'] = 0; $where['b.coupon_id'] = ['>',1]; $use_data = []; //查出全部的没过期优惠券 $data = Db::name('shop_coupon_use') ->alias('a') ->join('shop_coupon b','a.coupon_id = b.coupon_id','left') ->where($where) ->getAllWithIndex('use_id'); $type_coupon_arr = []; if (!empty($data)){ foreach ($data as $k => $v){ if (1 == $v['coupon_form']){ $v['coupon_form_name'] = '满减券'; } $v['start_time'] = date('Y/m/d', $v['start_time']); $v['end_time'] = date('Y/m/d', $v['end_time']); switch ($v['coupon_type']) { case 2: $v['coupon_type_name'] = '指定商品'; //指定商品 if (!empty($v['product_id'])){ $product_arr = explode(",",$v['product_id']); $in = 0; foreach ($aids as $m){ if (in_array($m,$product_arr) && $aid_price >= $v['conditions_use']){ //此优惠券可用 $in = 1; break; } } if (!empty($in)){ $use_data[] = $v; } } break; case 3: $v['coupon_type_name'] = '指定分类'; //指定分类 if (!empty($v['arctype_id'])){ $arctype_arr = explode(",",$v['arctype_id']); $is_have = 0; foreach ($product_data as $key => $val){ if (in_array($val['typeid'],$arctype_arr)){ $is_have = 1; if (empty($v['goods_total_price'])){ $v['goods_total_price'] = $val['subtotal']; }else{ $v['goods_total_price'] += $val['subtotal']; } } } if (!empty($is_have)) $type_coupon_arr[] = $v; } break; default: $v['coupon_type_name'] = '全部商品'; if ($totol_price >= $v['conditions_use']) { $use_data[] = $v; } break; } } if (!empty($type_coupon_arr)){ foreach ($type_coupon_arr as $k => $v) { if ($v['goods_total_price'] >= $v['conditions_use']){ unset($type_coupon_arr[$k]['goods_total_price']); $use_data[] = $v; } } } } return $use_data; } /** * 获取该订单不可用优惠券 */ public function getUnuseOrderCoupon($coupon_ids = [],$users_id) { $where['a.users_id'] = $users_id; $where['a.use_status'] = 0; $where['a.end_time'] = ['>=',getTime()]; $where['b.coupon_id'] = ['not in',$coupon_ids]; $unuse_data = []; //查出全部的优惠券 $data = Db::name('shop_coupon_use') ->alias('a') ->join('shop_coupon b','a.coupon_id = b.coupon_id','left') ->where($where) ->getAllWithIndex('use_id'); if (!empty($data)){ foreach ($data as $k => $v){ if (1 == $v['coupon_form']){ $v['coupon_form_name'] = '满减券'; } $v['start_time'] = date('Y/m/d', $v['start_time']); $v['end_time'] = date('Y/m/d', $v['end_time']); switch ($v['coupon_type']) { case '1': $v['coupon_type_name'] = '全部商品'; break; case '2'; $v['coupon_type_name'] = '指定商品'; break; case '3'; $v['coupon_type_name'] = '指定分类'; break; } $unuse_data[] = $v; } } return $unuse_data; } // 订单结算 public function ShopOrderPay($post = [], $level_discount = 100, $level_id = 0, $usersData = []) { // 基础判断 if (empty($post['users_id'])) $this->error('请先登录'); if (1 != $post['prom_type']){ if (empty($post['addr_id']) || $post['addr_id'] == 'undefined') $this->error('请添加收货地址'); } if (empty($post['pay_type'])) $this->error('请选择支付方式'); // 获取商城配置信息 $ConfigData = getUsersConfigData('shop'); // 会员折扣 $users_discount = strval($level_discount) / strval(100); if (isset($post['order_source']) && 20 == $post['order_source']) $users_discount = 0; // 获取下单的商品数据 $CacheData = Cache::get($post['querystr']); $list = $this->GetBuyOrderList($CacheData, $post['users_id'], $post); if (empty($list)) $this->error('链接失效,请重新下单'); // 订单商品数据处理 $list = $this->OrderProductProcess($list, $ConfigData, $users_discount, $level_id); if (empty($list)) $this->error('商品库存不足或已过期'); // 组装订单流程所需全局信息 $GlobalInfo = $this->GetGlobalInfo($ConfigData, $CacheData); /* 商品数据整合处理 */ foreach ($list as $key => $value) { /* 合计金额、合计数量计算 */ if ($value['users_price'] >= 0 && !empty($value['product_num'])) { // 计算合计金额 $GlobalInfo['TotalAmount'] += unifyPriceHandle($value['users_price'] * $value['product_num']); $GlobalInfo['TotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount']); // 计算合计数量 $GlobalInfo['TotalNumber'] += $value['product_num']; // 判断订单类型,目前逻辑:一个订单中,只要存在一个普通商品(实物商品,需要发货物流),则为普通订单 // 0表示为普通订单,1表示为虚拟订单,虚拟订单无需发货物流,无需选择收货地址,无需计算运费 if (empty($value['prom_type'])) $GlobalInfo['PromType'] = 0; } /* END */ } /* END */ $AddrData = []; if (!empty($post['deliveryShow']) && 1 === intval($post['deliveryShow'])) { // 获取用户下单时提交的收货地址及运费 $AddrData = $this->GetUsersAddrData($post, $GlobalInfo['PromType']); // 订单总金额 + 运费金额 $GlobalInfo['PayTotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount'] + $AddrData['shipping_fee']); } else { $GlobalInfo['PayTotalAmount'] = unifyPriceHandle($GlobalInfo['TotalAmount']); } // 应付总金额 $PayAmount = $GlobalInfo['PayTotalAmount']; // 使用优惠券 if (!empty($post['coupon_id'])){ $coupon_where = [ 'a.coupon_id'=>$post['coupon_id'], 'a.use_status'=>0, 'a.users_id' => $post['users_id'], ]; $coupon_where['a.start_time'] = ['<=',getTime()]; $coupon_where['a.end_time'] = ['>=',getTime()]; $coupon_info = Db::name('shop_coupon_use') ->alias('a') ->join('shop_coupon b','a.coupon_id = b.coupon_id','left') ->where($coupon_where) ->find(); if (!empty($coupon_info)){ $PayAmount = $PayAmount-$coupon_info['coupon_price'] < 0 ? 0 : $PayAmount-$coupon_info['coupon_price']; } } if (2 == $post['pay_type']) { $UsersMoney = Db::name('users')->where('users_id', $post['users_id'])->getField('users_money'); if ($GlobalInfo['PayTotalAmount'] > $UsersMoney) $this->error('您的余额不足,支付失败'); } // 添加到订单主表 $time = getTime(); $OrderData = [ 'order_code' => date('Ymd') . $time . rand(10, 100), 'users_id' => $post['users_id'], 'order_status' => 0, // 订单未付款 'add_time' => $time, 'payment_method' => 0, 'pay_time' => 0, 'pay_name' => 'wechat', 'wechat_pay_type' => 'WeChatInternal', 'order_terminal' => 3, 'pay_details' => '', 'order_total_amount' => $GlobalInfo['PayTotalAmount'], 'order_amount' => $PayAmount, 'order_total_num' => $GlobalInfo['TotalNumber'], 'prom_type' => $GlobalInfo['PromType'], 'order_source' => isset($post['order_source']) ? $post['order_source'] : 10, 'order_source_id' => isset($post['order_source_id']) ? $post['order_source_id'] : 0, 'virtual_delivery' => '', 'admin_note' => '', 'user_note' => $post['remark'], 'lang' => get_home_lang() ]; if (!empty($coupon_info)) { $OrderData['coupon_id'] = $coupon_info['coupon_id']; $OrderData['use_id'] = $coupon_info['use_id']; $OrderData['coupon_price'] = $coupon_info['coupon_price']; } // 存在收货地址则追加合并到主表数组 if (!empty($AddrData)) $OrderData = array_merge($OrderData, $AddrData); // 订单提交处理 -- 其他逻辑公共调用方法,部分逻辑改动不适合直接修改原文件时请在此方法做处理和兼容 $OrderData = model('ShopPublicHandle')->orderSubmitPublicHandle($OrderData, $this->usersConfig, $this->users_id, $post, $list); // 抖音支付时更新订单支付类型 if (9 === intval($post['pay_type'])) { $OrderData['pay_name'] = 'tikTokPay'; $OrderData['wechat_pay_type'] = ''; } // 添加订单及后续处理 $OrderId = Db::name('shop_order')->add($OrderData); if (!empty($OrderId)) { $OrderData['order_id'] = $OrderId; // 订单创建后续处理 -- 其他逻辑公共调用方法,部分逻辑改动不适合直接修改原文件时请在此方法做处理和兼容 $OrderData = model('ShopPublicHandle')->orderCreatePublicHandle($OrderData, $this->usersConfig, $this->users_id, $post, $list); //锁定优惠券 if (!empty($coupon_info)){ $coupon_update = [ 'coupon_id'=>$post['coupon_id'], 'use_status'=> 0, 'users_id' => $post['users_id'], ]; Db::name('shop_coupon_use')->where($coupon_update)->update(['use_status'=> 1,'use_time'=>getTime(),'update_time'=>getTime()]); } $cart_ids = $UpSpecValue = []; $contains_virtual = 1;//是否包含虚拟产品 foreach ($list as $key => $value) { $attr_value = $attr_value_new = $spec_value = ''; // 旧商品属性处理 $attr_value = $this->ProductAttrProcessing($value); // 新商品属性处理 $attr_value_new = $this->ProductNewAttrProcessing($value); // 商品规格处理 $spec_value = $this->ProductSpecProcessing($value); // 规格及属性 $ParamData = [ // 商品属性 'attr_value' => htmlspecialchars($attr_value), // 商品属性 'attr_value_new' => htmlspecialchars($attr_value_new), // 商品规格 'spec_value' => htmlspecialchars($spec_value), // 商品规格值ID 'spec_value_id' => $value['spec_value_id'], // 对应规格值ID的唯一标识ID,数据表主键ID 'value_id' => $value['value_id'], // 后续添加 ]; // 订单副表添加数组 $OrderDetailsData[] = [ 'order_id' => $OrderId, 'users_id' => $post['users_id'], 'product_id' => $value['aid'], 'product_name' => $value['title'], 'num' => $value['product_num'], 'data' => serialize($ParamData), 'product_price' => $value['users_price'], 'prom_type' => $value['prom_type'], 'litpic' => $value['litpic'], 'add_time' => $time, 'lang' => get_home_lang() ]; // 处理购物车ID if (empty($GlobalInfo['submit_order_type'])) { array_push($cart_ids, $value['cart_id']); } // 商品库存处理 $UpSpecValue[] = [ 'aid' => $value['aid'], 'value_id' => $value['value_id'], 'quantity' => $value['product_num'], 'spec_value_id' => $value['spec_value_id'], 'order_source' => isset($post['order_source']) ? $post['order_source'] : 10, 'order_source_id' => isset($post['order_source_id']) ? $post['order_source_id'] : 0, ]; if (in_array($value['prom_type'],[1,2,3])){ $contains_virtual = 2; } } if (2 == $contains_virtual) { Db::name('shop_order')->where('order_id',$OrderId)->update(['contains_virtual'=>$contains_virtual]); } $DetailsId = Db::name('shop_order_details')->insertAll($OrderDetailsData); if (!empty($OrderId) && !empty($DetailsId)) { // 清理购物车中已下单的ID if (!empty($cart_ids)) Db::name('shop_cart')->where('cart_id', 'IN', $cart_ids)->delete(); // 商品库存、销量处理 $this->ProductStockProcessing($UpSpecValue); // 添加订单操作记录 AddOrderAction($OrderId, $post['users_id']); // 微信支付 if (1 === intval($post['pay_type'])) { $weChatPay = $this->GetWechatAppletsPay($post['openid'], $OrderData['order_code'], $OrderData['order_amount']); $result = [ 'WeChatPay' => $weChatPay, 'OrderData' => [ 'order_id' => $OrderId, 'order_code' => $OrderData['order_code'] ] ]; $result['tmplData'] = []; // 返回提示 $this->success('正在支付', null, $result); } // 余额支付 else if (2 === intval($post['pay_type'])) { $pay_details = [ 'unified_id' => $OrderId, 'unified_number' => $OrderData['order_code'], 'payment_amount' => $OrderData['order_amount'], 'payment_type' => '余额支付' ]; $UpOrderData = [ 'order_status' => 1, 'pay_name' => 'balance', 'wechat_pay_type' => '', 'pay_details' => serialize($pay_details), 'pay_time' => getTime(), 'update_time' => getTime() ]; $ReturnID = Db::name('shop_order')->where('order_id', $OrderId)->update($UpOrderData); if (!empty($ReturnID)) { $UsersData = [ 'users_money' => $UsersMoney - $OrderData['order_amount'], 'update_time' => getTime() ]; $users_id = Db::name('users')->where('users_id', $post['users_id'])->update($UsersData); if (!empty($users_id)) { // 添加会员余额记录 $getParam = [ 'users_money' => $UsersMoney, 'users_id' => $post['users_id'] ]; UsersMoneyAction($OrderData['order_code'], $getParam, $OrderData['order_amount'], '订单支付'); // 添加订单操作记录 AddOrderAction($OrderId, $post['users_id'], 0, 1, 0, 1, '支付成功!', '会员使用余额完成支付!'); // 虚拟自动发货 $ShopModel = new \app\user\model\Pay(); $Where = [ 'lang' => get_home_lang(), 'users_id' => $post['users_id'], 'order_id' => $OrderId ]; $ShopModel->afterVirtualProductPay($Where); // 统计销售额 eyou_statistics_data(2); eyou_statistics_data(3, $OrderData['order_amount']); $result['tmplData'] = []; // 邮箱发送 $result['email'] = GetEamilSendData(tpCache('smtp'), $usersData, $OrderData, 1, 'balance'); // 短信发送 $result['mobile'] = GetMobileSendData(tpCache('sms'), $usersData, $OrderData, 1, 'balance'); // 发送站内信给后台 $OrderData['pay_method'] = '余额支付'; SendNotifyMessage($OrderData, 5, 1, 0); // 返回数据 $result['OrderData'] = $OrderData; $this->success('支付完成', '/pages/order/index', $result); } } } // 抖音支付 else if (9 === intval($post['pay_type'])) { $tikTokPay = model('TikTok')->getTikTokAppletsPay($OrderId, $OrderData['order_code'], $OrderData['order_amount'], $this->usersConfig['order_unpay_close_time']); $result = [ 'tikTokPay' => $tikTokPay, 'OrderData' => [ 'order_id' => $OrderId, 'order_code' => $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'); // $result['tmplData'] = $tmplData; $result['tmplData'] = []; // 返回提示 $this->success('正在支付', null, $result); } } else if (!empty($OrderId) && empty($DetailsId)) { // 订单详情添加失败则删除已添加的订单主表数据 Db::name('shop_order')->delete($OrderId); $this->error('订单生成失败,商品数据有误!'); } } $this->error('订单生成失败,商品数据有误!'); } //生成核销码 public function create_verify_code($length = 12) { $chars = "0123456789"; $char_len = strlen($chars); $verify_code = ''; for ($i = 0; $i < $length; $i++) { $loop = mt_rand(0, ($char_len - 1)); $verify_code .= $chars[$loop]; } $is_have = Db::name('shop_order_verify')->where('verify_code',$verify_code)->count(); if (!empty($is_have)){ $verify_code = $this->create_verify_code(12); } return $verify_code; } // 微信小程序支付后续处理 public function WechatAppletsPayDealWith($PostData = [], $notify = false) { $OpenID = !empty($PostData['openid']) ? $PostData['openid'] : ''; $UsersID = !empty($PostData['users_id']) ? $PostData['users_id'] : ''; $OrderID = $PostData['order_id']; $OrderCode = $PostData['order_code']; if (!empty($OrderID) && !empty($OrderCode)) { /* 查询本站订单状态 */ $where = [ 'users_id' => $UsersID, 'order_id' => $OrderID, 'order_code' => $OrderCode, ]; $order = Db::name('shop_order')->where($where)->find(); if (empty($order)) { $this->error('无效订单!'); } else if (0 < $order['order_status']) { // 订单已支付 if ($notify === true) { // 异步 return [ 'code' => 1, 'msg' => 'ok', ]; } else { // 同步 $usersData = Db::name('users')->where('users_id', $UsersID)->find(); // 邮箱发送 $resultData['email'] = GetEamilSendData(tpCache('smtp'), $usersData, $order, 1, 'wechat'); // 短信发送 $resultData['mobile'] = GetMobileSendData(tpCache('sms'), $usersData, $order, 1, 'wechat'); $this->success('支付完成', '/pages/order/index', $resultData); } } // 当前时间戳 $time = getTime(); // 当前时间戳 + OpenID 经 MD5加密 $nonceStr = md5($time . $OpenID); // 调用支付接口参数 $params = [ 'appid' => $this->miniproInfo['appid'], 'mch_id' => $this->miniproInfo['mchid'], 'nonce_str' => $nonceStr, 'out_trade_no' => $OrderCode ]; // 生成参数签名 $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']); // 生成参数XML格式 $ParamsXml = $this->ParamsXml($params); // 调用接口返回数据 $url = 'https://api.mch.weixin.qq.com/pay/orderquery'; $result = $this->HttpsPost($url, $ParamsXml); // 解析XML格式 $ResultData = $this->ResultXml($result); // 订单是否存在 if (!empty($ResultData) && 'SUCCESS' == $ResultData['return_code'] && 'OK' == $ResultData['return_msg']) { // if ('NOTPAY' == $ResultData['trade_state'] && !empty($ResultData['trade_state_desc'])) { // // 订单未支付 // $this->error($ResultData['trade_state_desc']); // } if ('SUCCESS' == $ResultData['trade_state']) { // 订单已支付,处理订单流程 $OrderWhere = [ 'order_id' => $OrderID, 'users_id' => $order['users_id'] ]; $OrderData = [ 'order_status' => 1, 'pay_details' => serialize($ResultData), 'pay_time' => getTime(), 'update_time' => getTime() ]; $ResultID = Db::name('shop_order')->where($OrderWhere)->update($OrderData); if (!empty($ResultID)) { // 添加订单操作记录 AddOrderAction($OrderID, $order['users_id'], 0, 1, 0, 1, '支付成功', '会员使用微信小程序完成支付'); // 虚拟自动发货 $ShopModel = new \app\user\model\Pay(); $Where = [ 'lang' => get_home_lang(), 'users_id' => $UsersID, 'order_id' => $OrderID ]; $ShopModel->afterVirtualProductPay($Where); // 站内信通知 $order['pay_method'] = '微信支付'; SendNotifyMessage($order, 5, 1, 0); // 添加会员积分记录 $where = [ 'users_id' => $UsersID, 'order_id' => $OrderID ]; $data = Db::name('shop_order_details')->where($where)->getField('data'); $data = !empty($data) ? unserialize($data) : []; $pointsGoodsBuyField = !empty($data['pointsGoodsBuyField']) ? json_decode($data['pointsGoodsBuyField'], true) : []; if (!empty($pointsGoodsBuyField['goodsTotalPoints'])) { $insert = [ 'type' => 11, // 积分商城订单支付 'users_id' => $UsersID, 'score' => $pointsGoodsBuyField['goodsTotalPoints'], 'info' => '积分商城订单支付', 'remark' => '积分商城订单支付', ]; addConsumObtainScores($insert, 1, false); } // 订单支付完成 if ($notify === true) { // 异步 return [ 'code' => 1, 'msg' => 'ok', ]; } else {// 同步 // 统计销售额 eyou_statistics_data(2); eyou_statistics_data(3, $order['order_amount']); $usersData = Db::name('users')->where('users_id', $UsersID)->find(); // 邮箱发送 $resultData['email'] = GetEamilSendData(tpCache('smtp'), $usersData, $order, 1, 'wechat'); // 短信发送 $resultData['mobile'] = GetMobileSendData(tpCache('sms'), $usersData, $order, 1, 'wechat'); $this->success('支付完成', '/pages/order/index', $resultData); } } } } } } // 用于订单列表和订单详情页直接支付 public function OrderDirectPay($post = []) { $where = [ 'users_id' => $post['users_id'], 'order_id' => $post['order_id'], 'order_code' => $post['order_code'] ]; $field = 'order_status, order_amount'; $Result = Db::name('shop_order')->where($where)->field($field)->find(); if (!empty($Result)) { if (0 == $Result['order_status']) { $Data = $this->GetWechatAppletsPay($post['openid'], $post['order_code'], $Result['order_amount']); $ResultData = [ 'WeChatPay' => $Data, 'OrderData' => [ 'order_id' => $post['order_id'], 'order_code' => $post['order_code'] ] ]; $url = '/pages/order/index'; $this->success('正在支付', $url, $ResultData); } else if (in_array($Result['order_status'], [1, 2, 3])) { $this->success('订单已支付'); } else if ($Result['order_status'] == 4) { $this->success('订单已过期'); } else if ($Result['order_status'] == -1) { $this->success('订单已关闭'); } } $this->error('订单不存在'); } // 微信小程序支付 public function GetWechatAppletsPay($OpenID = null, $out_trade_no = null, $total_fee = null, $notify_url = '') { $notify_url = !empty($notify_url) ? $notify_url : url('api/v1.Api/wxpay_notify', [], true, true, 1, 1); // 当前时间戳 $time = time(); // 当前时间戳 + OpenID 经 MD5加密 $nonceStr = md5($time . $OpenID); // 调用支付接口参数 $params = [ 'appid' => $this->miniproInfo['appid'], 'attach' => "微信小程序支付", 'body' => "商品支付", 'mch_id' => $this->miniproInfo['mchid'], 'nonce_str' => $nonceStr, 'notify_url' => $notify_url, 'openid' => $OpenID, 'out_trade_no' => $out_trade_no, 'spbill_create_ip' => $this->GetClientIP(), 'total_fee' => strval($total_fee * 100), 'trade_type' => 'JSAPI' ]; // 生成参数签名 $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']); // 生成参数XML格式 $ParamsXml = $this->ParamsXml($params); // 调用接口返回数据 $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; $result = $this->HttpsPost($url, $ParamsXml); // 解析XML格式 $ResultData = $this->ResultXml($result); // 数据返回 if ($ResultData['return_code'] == 'SUCCESS' && $ResultData['return_msg'] == 'OK') { // 返回支付所需参数 $ReturnData = [ 'prepay_id' => $ResultData['prepay_id'], 'nonceStr' => $nonceStr, 'timeStamp' => strval($time), 'return_code' => $ResultData['return_code'] ]; // 生成支付所需的签名 $ReturnData['paySign'] = $this->PaySign($this->miniproInfo['appid'], $params['nonce_str'], $ResultData['prepay_id'], $time); return $ReturnData; } else if ($ResultData['return_code'] == 'FAIL') { if ($ResultData['return_msg'] == '签名错误') { $ResultData['return_msg'] = '小程序支付配置不正确!'; } return $ResultData; } else { return $ResultData; } } private function ParamsSign($values, $apikey) { //签名步骤一:按字典序排序参数 ksort($values); $string = $this->ParamsUrl($values); //签名步骤二:在string后加入KEY $string = $string . '&key=' . $apikey; //签名步骤三:MD5加密 $string = md5($string); //签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result; } private function ParamsUrl($values) { $Url = ''; foreach ($values as $k => $v) { if ($k != 'sign' && $v != '' && !is_array($v)) { $Url .= $k . '=' . $v . '&'; } } return trim($Url, '&'); } private function ParamsXml($values) { if (!is_array($values) || count($values) <= 0 ) { return false; } $xml = ""; foreach ($values as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . ""; } else { $xml .= "<" . $key . ">"; } } $xml .= ""; return $xml; } private function ResultXml($xml) { // 禁止引用外部xml实体 @libxml_disable_entity_loader(true); return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); } private function GetClientIP() { if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) { $ip = getenv('HTTP_CLIENT_IP'); } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) { $ip = getenv('HTTP_X_FORWARDED_FOR'); } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) { $ip = getenv('REMOTE_ADDR'); } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) { $ip = $_SERVER['REMOTE_ADDR']; } return preg_match('/[\d\.]{7,15}/', $ip, $matches) ? $matches [0] : ''; } private function HttpsPost($url, $data) { $result = httpRequest($url, 'POST', $data); return $result; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 ); curl_setopt($ch, CURLOPT_AUTOREFERER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); if (curl_errno($ch)) { return 'Errno: ' . curl_error($ch); } curl_close($ch); return $result; } private function PaySign($appid, $nonceStr, $prepay_id, $timeStamp) { $data = [ 'appId' => $appid, 'nonceStr' => $nonceStr, 'package' => 'prepay_id=' . $prepay_id, 'signType' => 'MD5', 'timeStamp' => $timeStamp, ]; // 签名步骤一:按字典序排序参数 ksort($data); $string = $this->ParamsUrl($data); // 签名步骤二:在string后加入KEY $string = $string . '&key=' . $this->miniproInfo['apikey']; // 签名步骤三:MD5加密 $string = md5($string); // 签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result; } // 扣除商品库存 private function ProductStockProcessing($SpecValue = []) { if (!empty($SpecValue)) { $SpecUpData = []; // 有规格 $ArcUpData = []; // 无规格 foreach ($SpecValue as $key => $value) { if (!empty($value['value_id'])) { if (!empty($value['order_source']) && $value['order_source'] == 20){ //秒杀订单 $SpecUpData[] = [ 'value_id' => $value['value_id'], 'seckill_stock' => Db::raw('seckill_stock-' . ($value['quantity'])), 'seckill_sales_num' => Db::raw('seckill_sales_num+' . ($value['quantity'])), ]; }else{ //普通订单 $SpecUpData[] = [ 'value_id' => $value['value_id'], 'spec_stock' => Db::raw('spec_stock-' . ($value['quantity'])), 'spec_sales_num' => Db::raw('spec_sales_num+' . ($value['quantity'])), ]; $ArcUpData[] = [ 'aid' => $value['aid'], 'stock_count' => Db::raw('stock_count-' . ($value['quantity'])), 'sales_num' => Db::raw('sales_num+' . ($value['quantity'])), 'sales_all' => Db::raw('sales_all+' . ($value['quantity'])), ]; } } else { if ($value['order_source'] != 20){ //普通订单 $ArcUpData[] = [ 'aid' => $value['aid'], 'stock_count' => Db::raw('stock_count-' . ($value['quantity'])), 'sales_num' => Db::raw('sales_num+' . ($value['quantity'])), 'sales_all' => Db::raw('sales_all+' . ($value['quantity'])), ]; } } //秒杀订单无论单规格还是多规格都要更改sharp_goods的库存和销量 if (!empty($value['order_source']) && $value['order_source'] == 20){ $SharpUpData = [ 'aid' => $value['aid'], 'seckill_stock' => Db::raw('seckill_stock-' . ($value['quantity'])), 'sales' => Db::raw('sales+' . ($value['quantity'])) ]; Db::name('sharp_goods')->where('aid',$value['aid'])->update($SharpUpData); Db::name('sharp_active_goods') ->where(['active_time_id'=>$value['order_source_id'],'aid'=> $value['aid']]) ->update(['sales_actual'=>Db::raw('sales_actual+' . ($value['quantity']))]); } } // 更新规格库存销量 if (!empty($SpecUpData)) { $ProductSpecValueModel = new \app\user\model\ProductSpecValue(); $ProductSpecValueModel->saveAll($SpecUpData); } // 更新商品库存销量 if (!empty($ArcUpData)) { $ArchivesModel = new \app\user\model\Archives(); $ArchivesModel->saveAll($ArcUpData); } } } // 获取下单的商品数据 private function GetBuyOrderList($CacheData = [], $users_id = null, $post = []) { $list = []; if (!empty($CacheData)) { // 立即购买下单 $where['a.aid'] = $CacheData['product_id']; if (!empty($CacheData['spec_value_id'])) $where['b.spec_value_id'] = $CacheData['spec_value_id']; $field = 'a.aid, a.typeid, a.title, a.litpic, a.users_price, a.users_discount_type, a.stock_count, a.prom_type, a.attrlist_id, a.logistics_type, b.value_id, b.aid as product_id, b.spec_value_id, b.spec_price, b.spec_stock'; if ('v1.5.1' < getVersion()) { $field .= ',b.seckill_price, b.seckill_stock'; } if ('v1.5.7' < getVersion()) { $field .= ',b.discount_price, b.discount_stock'; } $list = Db::name('archives')->alias('a')->field($field) ->join('__PRODUCT_SPEC_VALUE__ b', 'a.aid = b.aid', 'LEFT') ->where($where) ->limit('0, 1') ->select(); $list[0]['product_num'] = $CacheData['product_num']; if (isset($CacheData['active_time_id']) && !empty($CacheData['active_time_id'])){ $list[0]['active_time_id'] = $CacheData['active_time_id']; //判断是否还在秒杀时间内 $hour = date('H'); $date = strtotime(date('Y-m-d')); $active_time = Db::name('sharp_active_time') ->alias('a') ->join('sharp_active b','a.active_id = b.active_id') ->where('b.active_date',$date) ->where('a.active_time',$hour) ->getField('active_time_id'); if (empty($active_time) || $CacheData['active_time_id'] != $active_time){ if (empty($list)) $this->error('秒杀活动已结束!'); } //判断该秒杀商品是多规格还是单规格 $is_sku = Db::name('sharp_active_goods') ->alias('a') ->join('sharp_goods b','a.aid = b.aid') ->where('a.aid',$CacheData['product_id']) ->where('a.active_time_id',$CacheData['active_time_id']) ->getField('b.is_sku'); $list[0]['is_sku'] = $is_sku; if (empty($is_sku)){ //单规格 $active_goods = Db::name('sharp_goods')->where('aid',$CacheData['product_id'])->field('seckill_price,seckill_stock')->find(); if (!empty($active_goods)){ $list[0]['users_price'] = $list[0]['seckill_price'] = $active_goods['seckill_price']; $list[0]['stock_count'] = $list[0]['seckill_stock'] = $active_goods['seckill_stock']; } } }elseif (isset($CacheData['discount_active_id']) && !empty($CacheData['discount_active_id'])){ $list[0]['discount_active_id'] = $CacheData['discount_active_id']; $end_date = Db::name('discount_active')->where('active_id',$CacheData['discount_active_id'])->value('end_date'); if ($end_date < getTime()){ if (empty($list)) $this->error('活动已结束!'); } //判断该秒杀商品是多规格还是单规格 $discount_goods = Db::name('discount_active_goods') ->alias('a') ->field('b.is_sku,b.discount_price,b.discount_stock') ->join('discount_goods b','a.aid = b.aid') ->where('a.aid',$CacheData['product_id']) ->where('a.active_id',$CacheData['discount_active_id']) ->find(); $list[0]['is_sku'] = $discount_goods['is_sku']; if (empty($discount_goods['is_sku'])){ //单规格 $list[0]['users_price'] = $list[0]['discount_price'] = $discount_goods['discount_price']; $list[0]['stock_count'] = $list[0]['discount_stock'] = $discount_goods['discount_stock']; } } } else { // 购物车下单 $where = [ 'a.users_id' => $users_id, 'a.lang' => get_home_lang(), 'a.selected' => 1, ]; $list = Db::name('shop_cart')->field('a.*,b.typeid, b.aid, b.title, b.litpic, b.users_price, b.users_discount_type, b.stock_count, b.prom_type, b.attrlist_id, b.logistics_type, c.spec_price, c.spec_stock, c.value_id') ->alias('a') ->join('__ARCHIVES__ b', 'a.product_id = b.aid', 'LEFT') ->join('__PRODUCT_SPEC_VALUE__ c', 'a.spec_value_id = c.spec_value_id and a.product_id = c.aid', 'LEFT') ->where($where) ->select(); $logistics_type_arr = get_arr_column($list,'logistics_type'); if (empty($post['deliveryShow']) && empty($post['verifyShow']) && in_array(1,$logistics_type_arr)){ $post['deliveryShow'] = 1; } foreach ($list as $key => $value) { // 仅购买支持到店核销商品 if (!empty($post['verifyShow']) && 1 === intval($post['verifyShow'])) { if ('1' === $value['logistics_type']) unset($list[$key]); } // 仅购买支持快递配送商品 else if (!empty($post['deliveryShow']) && 1 === intval($post['deliveryShow'])) { if ('2' === $value['logistics_type']) unset($list[$key]); } } } return $list; } // 商品规格/折扣数据处理 private function OrderProductProcess($list = [], $ConfigData = [], $users_discount = 1, $level_id = 0) { foreach ($list as $key => $value) { // 规格处理 $list[$key]['product_spec_list'] = !empty($value['spec_value_id']) ? model('ShopPublicHandle')->getGoodsSpecList($value) : []; /* 未开启多规格则执行 */ if (!isset($ConfigData['shop_open_spec']) || empty($ConfigData['shop_open_spec'])) { $value['spec_value_id'] = $value['spec_price'] = $value['spec_stock'] = 0; $list[$key]['spec_value_id'] = $list[$key]['spec_price'] = $list[$key]['spec_stock'] = 0; } /* END */ /* 商品存在规格且价格不为空,则覆盖商品原来的价格 */ if (!empty($value['spec_value_id']) && 'undefined' != $value['spec_value_id'] && $value['spec_price'] >= 0) { // 规格价格覆盖商品原价 $list[$key]['users_price'] = $value['users_price'] = $value['spec_price']; } /* END */ /* 商品原价 */ $list[$key]['old_price'] = unifyPriceHandle($list[$key]['users_price']); /* END */ /* 计算折扣后的价格 */ if (!empty($users_discount) && 0 === intval($value['users_discount_type'])) { // 会员折扣价 $list[$key]['users_price'] = unifyPriceHandle($value['users_price'] * $users_discount); } /* END */ $list[$key]['discount_end_date'] = 0; /* 限时折扣商品多规格商品,则覆盖商品原来的价格 */ if (!empty($value['discount_active_id'])) { if (empty($value['discount_price'])){ $value['discount_price'] = Db::name('discount_goods')->where('aid',$value['aid'])->value('discount_price'); } $list[$key]['users_price'] = $value['spec_price'] = $value['discount_price']; $list[$key]['discount_end_date'] = Db::name('discount_active')->where('active_id',$value['discount_active_id'])->value('end_date'); } /* END */ /* 商品存在规格且库存不为空,则覆盖商品原来的库存 */ if (!empty($value['spec_stock'])) { // 规格库存覆盖商品库存 $list[$key]['stock_count'] = $value['stock_count'] = $value['spec_stock']; } if ($value['product_num'] > $value['stock_count']) { // 购买数量超过最大库存量则默认购买最大库存量 $list[$key]['stock_count'] = $list[$key]['product_num'] = $value['stock_count']; } /* END */ // 图片处理 $list[$key]['litpic'] = $this->get_default_pic($value['litpic'], true); // 商品是 单规格 且 设置会员折扣价 则处理 if (empty($list[$key]['product_spec']) && 1 === intval($value['users_discount_type']) && !empty($level_id)) { $list[$key]['users_price'] = model('ShopPublicHandle')->handleUsersDiscountPrice($value['aid'], $level_id); } /* 若库存为空则清除这条数据 */ if (empty($value['stock_count'])) { unset($list[$key]); continue; } /* END */ } return $list; } // 组装订单流程所需全局信息 private function GetGlobalInfo($ConfigData = [], $CacheData = []) { $GlobalInfo = [ // 温馨提示内容,为空则不展示 'shop_prompt' => !empty($ConfigData['shop_prompt']) ? $ConfigData['shop_prompt'] : '', // 是否开启线下支付(货到付款) 'shop_open_offline' => !empty($ConfigData['shop_open_offline']) ? $ConfigData['shop_open_offline'] : 0, // 是否开启运费设置 'shop_open_shipping' => !empty($ConfigData['shop_open_shipping']) ? $ConfigData['shop_open_shipping'] : 0, // 初始化支付总额 'TotalAmount' => 0, // 初始化支付总额,包含运费 'PayTotalAmount' => 0, // 初始化总数 'TotalNumber' => 0, // 提交来源:0购物车;1直接下单 'submit_order_type' => !empty($CacheData) ? 1 : 0, // 1表示为虚拟订单 'PromType' => 1, // 虚拟订单文案 'virtual_text1' => '1、该产品为虚拟产品,仅支持在线支付且无需选择收货地址及运费计算。', 'virtual_text2' => '2、若产品是充值类产品,请将您的手机号或需充值的卡号填入留言中。', // 仅到店核销 'onlyVerify' => false, // 仅物流配送 'onlyDelivery' => false, // 物流支持 'allLogisticsType' => false, ]; return $GlobalInfo; } // 获取用户下单时提交的收货地址及运费 private function GetUsersAddrData($post = [], $PromType = 0) { $AddrData = []; if (0 == $PromType) { // 查询收货地址 $AddrWhere = [ 'addr_id' => $post['addr_id'], 'users_id' => $post['users_id'], 'lang' => get_home_lang() ]; $AddressData = Db::name('shop_address')->where($AddrWhere)->find(); if (empty($AddressData)) $this->error('收货地址不存在!'); $shop_open_shipping = getUsersConfigData('shop.shop_open_shipping'); $template_money = '0.00'; if (!empty($shop_open_shipping)) { // 通过省份获取运费模板中的运费价格 $where['province_id'] = $AddressData['province']; $template_money = Db::name('shop_shipping_template')->where($where)->getField('template_money'); if (0 == $template_money) { // 省份运费价格为0时,使用统一的运费价格,固定ID为100000 $where['province_id'] = 100000; $template_money = Db::name('shop_shipping_template')->where($where)->getField('template_money'); } } } // 拼装数组 $AddrData = [ 'consignee' => !empty($AddressData['consignee']) ? $AddressData['consignee'] : '', 'country' => !empty($AddressData['country']) ? $AddressData['country'] : '', 'province' => !empty($AddressData['province']) ? $AddressData['province'] : '', 'city' => !empty($AddressData['city']) ? $AddressData['city'] : '', 'district' => !empty($AddressData['district']) ? $AddressData['district'] : '', 'address' => !empty($AddressData['address']) ? $AddressData['address'] : '', 'mobile' => !empty($AddressData['mobile']) ? $AddressData['mobile'] : '', 'shipping_fee' => !empty($template_money) ? $template_money : 0, ]; return $AddrData; } // 旧产品属性处理 private function ProductAttrProcessing($value = array()) { $attr_value = ''; $AttrWhere = [ 'a.aid' => $value['aid'], 'b.lang' => get_home_lang() ]; $attrData = Db::name('product_attr') ->alias('a') ->field('a.attr_value as value, b.attr_name as name') ->join('__PRODUCT_ATTRIBUTE__ b', 'a.attr_id = b.attr_id', 'LEFT') ->where($AttrWhere) ->order('b.sort_order asc, a.attr_id asc') ->select(); foreach ($attrData as $val) { $attr_value .= $val['name'] . ':' . $val['value'] . '
'; } return $attr_value; } // 新商品属性处理 private function ProductNewAttrProcessing($value = array()) { $attr_value = ''; $where = [ 'a.list_id' => $value['attrlist_id'], 'a.status' => 1, 'b.aid' => $value['aid'] ]; $attrData = Db::name('shop_product_attribute') ->alias('a') ->field('a.attr_name as name, b.attr_value as value') ->join('__SHOP_PRODUCT_ATTR__ b', 'a.attr_id = b.attr_id', 'LEFT') ->where($where) ->order('a.sort_order asc, a.attr_id asc') ->select(); foreach ($attrData as $val) { $attr_value .= $val['name'] . ':' . $val['value'] . '
'; } return $attr_value; } // 商品规格处理 private function ProductSpecProcessing($value = array()) { $spec_value_s = ''; if (!empty($value['spec_value_id'])) { $spec_value_id = explode('_', $value['spec_value_id']); if (!empty($spec_value_id)) { $SpecWhere = [ 'aid' => $value['aid'], 'lang' => get_home_lang(), 'spec_value_id' => ['IN', $spec_value_id], ]; $ProductSpecData = Db::name("product_spec_data")->where($SpecWhere)->field('spec_name,spec_value')->select(); foreach ($ProductSpecData as $spec_value) { $spec_value_s .= $spec_value['spec_name'] . ':' . $spec_value['spec_value'] . '
'; } } } return $spec_value_s; } /*商城购物流程--END*/ /* 判断商品库存 */ public function IsSoldOut($post = []) { if (!empty($post['product_id'])) { if (!empty($post['spec_value_id'])) { $SpecWhere = [ 'aid' => $post['product_id'], 'lang' => get_home_lang(), 'spec_stock' => ['>', 0], 'spec_value_id' => $post['spec_value_id'] ]; $find_field = 'spec_stock'; if (!empty($post['active_time_id'])){ $find_field = 'seckill_stock'; } if (!empty($post['discount_active_id'])){ $find_field = 'discount_stock'; } $spec_stock = Db::name('product_spec_value')->where($SpecWhere)->getField($find_field); if (empty($spec_stock)) { $this->error('商品已售罄!'); } if ($spec_stock < $post['product_num']) { $this->error('商品最大库存:' . $spec_stock); } } else { $ArchivesWhere = [ 'aid' => $post['product_id'], 'lang' => get_home_lang(), 'arcrank' => ['>=', 0] ]; if (!empty($post['active_time_id'])){ $stock_count = Db::name('sharp_goods')->where('aid',$post['product_id'])->getField('seckill_stock'); }elseif (!empty($post['discount_active_id'])){ $stock_count = Db::name('discount_goods')->where('aid',$post['product_id'])->getField('discount_stock'); }else{ $stock_count = Db::name('archives')->where($ArchivesWhere)->getField('stock_count'); } if (empty($stock_count)) { $this->error('商品已售罄!'); } if ($stock_count < $post['product_num']) { $this->error('商品最大库存:' . $stock_count); } } } } /* END */ /*收货地址--Start*/ // 收货地址列表 public function GetAllAddressList($users = []) { $ReturnData = []; $list = !empty($users['address_1588820149']) ? $users['address_1588820149'] : []; $default_id = !empty($users['address_default_1588820149']) ? $users['address_default_1588820149']['addr_id'] : 0; if (!empty($list)) { // 将地址ID转成地址名称 foreach ($list as $key => $value) { $list[$key]['provinceName'] = $this->GetRegionName($value['province']); $list[$key]['cityName'] = $this->GetRegionName($value['city']); $list[$key]['districtName'] = $this->GetRegionName($value['district']); } // 若没有默认收货地址则默认第一个地址为默认地址 if (empty($default_id)) { $default_id = $list[0]['addr_id']; $where = [ 'addr_id' => $default_id, 'users_id' => $this->users_id ]; $update = [ 'is_default' => 1, 'update_time' => getTime() ]; Db::name('shop_address')->where($where)->update($update); } } // 返回数据 $ReturnData = [ 'list' => $list, 'default_id' => $default_id ]; $this->success('查询成功', null, $ReturnData); } // 获取单条收货地址 public function GetFindAddrDetail($post = [], $users = []) { if (!empty($users['address_1588820149'])) { $ResultData['detail'] = []; foreach ($users['address_1588820149'] as $key => $value) { if ($post['addr_id'] == $value['addr_id']) { $ResultData['detail'] = $value; break; } } if (!empty($ResultData)) { // 查询地址名称 $ProvinceName = $this->ProcessingProvince($this->GetRegionName($ResultData['detail']['province'])); $CityName = $this->GetRegionName($ResultData['detail']['city']); $DistrictName = $this->GetRegionName($ResultData['detail']['district']); // 拼装地址 $region = $ProvinceName . ',' . $CityName . ',' . $DistrictName; $ResultData['detail']['region'] = [ 'province' => $ProvinceName, 'city' => $CityName, 'region' => $DistrictName ]; $ResultData['region'] = explode(',', $region); // 查询地址名称 $ProvinceName = $this->GetRegionName($ResultData['detail']['province']); // 拼装地址 $regionNew = $ProvinceName . ',' . $CityName . ',' . $DistrictName; $ResultData['detail']['regionNew'] = [ 'province' => $ProvinceName, 'city' => $CityName, 'region' => $DistrictName ]; $ResultData['regionNew'] = explode(',', $regionNew); $this->success('查询成功', null, $ResultData); } } $this->error('数据错误'); } // 添加单条收货地址 public function FindAddAddr($post = [], $users_id = null) { if (!empty($post['name']) && !empty($post['phone']) && !empty($post['region']) && !empty($users_id)) { /* 微信地址名称换取本站地址ID */ $AddrData = $this->GetAddrData($post['region']); /* END */ $AddData = [ 'users_id' => $users_id, 'consignee' => $post['name'], 'country' => 1, 'province' => $AddrData['province'], 'city' => $AddrData['city'], 'district' => $AddrData['district'], 'address' => $post['detail'], 'mobile' => $post['phone'], 'lang' => get_home_lang(), 'add_time' => getTime(), 'update_time' => getTime() ]; $ResultID = Db::name('shop_address')->add($AddData); if (!empty($ResultID)) $this->success('添加成功'); } $this->error('数据错误'); } // 编辑单条收货地址 public function FindEditAddr($post = [], $users_id = null) { if (!empty($post['name']) && !empty($post['phone']) && !empty($post['region']) && !empty($users_id)) { /* 微信地址名称换取本站地址ID */ $AddrData = $this->GetAddrData($post['region']); /* END */ $UpData = [ 'users_id' => $users_id, 'consignee' => $post['name'], 'country' => 1, 'province' => $AddrData['province'], 'city' => $AddrData['city'], 'district' => $AddrData['district'], 'address' => $post['detail'], 'mobile' => $post['phone'], 'update_time' => getTime() ]; $ResultID = Db::name('shop_address')->where('addr_id', $post['addr_id'])->update($UpData); if (!empty($ResultID)) $this->success('编辑成功'); } $this->error('数据错误'); } // 设置默认地址 public function SetDefaultAddr($post = [], $users_id = null) { if (empty($post['addr_id']) || empty($users_id)) $this->error('请刷新重试'); /*设置默认地址*/ $where = [ 'addr_id' => $post['addr_id'], 'users_id' => $users_id ]; $update = [ 'is_default' => 1, 'update_time' => getTime() ]; $ResultID = Db::name('shop_address')->where($where)->update($update); /* END */ if (!empty($ResultID)) { /*将其他地址设置为非默认地址*/ $where = [ 'addr_id' => ['NEQ', $post['addr_id']], 'users_id' => $users_id ]; $update = [ 'is_default' => 0, 'update_time' => getTime() ]; Db::name('shop_address')->where($where)->update($update); /* END */ $this->success('更新成功'); } $this->error('更新失败,请刷新重试'); } // 删除单条收货地址 public function FindDelAddr($post = [], $users_id = null) { if (!empty($post['addr_id']) && !empty($users_id)) { $where = [ 'users_id' => $users_id, 'addr_id' => $post['addr_id'] ]; $ResultID = Db::name('shop_address')->where($where)->delete(); if (!empty($ResultID)) $this->success('操作成功'); } $this->error('数据错误'); } // 微信地址名称换取本站地址ID private function GetAddrData($region = null) { $region = explode(',', $region); $province = substr($region[0], 0, 6); // 截取前两个汉字 $ResultData['province'] = $this->GetRegionID(1, $province); $ResultData['city'] = $this->GetRegionID(2, $region[1], $ResultData['province']); $ResultData['district'] = $this->GetRegionID(3, $region[2], $ResultData['city']); return $ResultData; } // 微信地址名称换取本站地址ID private function GetRegionID($level = 1, $name = 1, $parent_id = 0) { $old_name = $name; // 当区域名称大于2两个字是,就去除末尾指定的字 if ($level > 1 && strlen($name) >= 9) { $name = preg_replace('/(省|市|县|区|乡|镇)$/i', '', $name); } $where = [ 'level' => $level, 'parent_id' => $parent_id, 'name' => ['LIKE', "{$name}%"], ]; $id = Db::name('region')->where($where)->getField('id'); if (empty($id) && 2 <= $level) { $addData = [ 'name' => $old_name, 'level' => $level, 'parent_id' => $parent_id, 'initial' => getFirstCharter($old_name), ]; $id = Db::name('region')->insertGetId($addData); } return $id; } // 地址ID换取地址名称 private function GetRegionName($id = 1) { $name = Db::name('region')->where('id', $id)->getField('name'); return $name; } // 特殊地区处理 private function ProcessingProvince($province = null) { if (empty($province)) return $province; if ('山西' == $province) { $province = '山西省'; } else if ('内蒙古' == $province) { $province = '内蒙古自治区'; } else if ('广西' == $province) { $province = '广西壮族自治区'; } else if ('西藏' == $province) { $province = '西藏自治区'; } else if ('宁夏' == $province) { $province = '宁夏回族自治区'; } else if ('新疆' == $province) { $province = '新疆维吾尔族自治区'; } else if ('香港' == $province) { $province = '香港特别行政区'; } else if ('澳门' == $province) { $province = '澳门特别行政区'; } else if ('台湾' == $province) { $province = '台湾省'; } return $province; } /* 收货地址--END */ /** * 获取订单总数 * @param $user * @param string $type * @return int|string * @throws \think\Exception */ public function getOrderCount($users, $type = 'all') { if ($users === false) { return false; } // 筛选条件 $filter = []; // 订单数据类型 switch ($type) { case 'all': // 全部订单 break; case 'payment'; // 待付款订单 $filter['order_status'] = 0; break; case 'delivery'; // 待发货 $filter['order_status'] = 1; break; case 'received'; // 待收货订单 $filter['order_status'] = 2; break; case 'complete'; // 已完成 $filter['order_status'] = 3; break; } $filter['users_id'] = $users['users_id']; $filter['lang'] = get_home_lang(); $count = Db::name('shop_order') ->where($filter) ->count(); return $count; } /** * 用户中心订单列表 * @param $users_id * @param string $type * @return \think\Paginator * @throws \think\exception\DbException */ public function getOrderList($users_id = 0, $type = 'all') { // 筛选条件 $where = [ 'lang' => get_home_lang(), 'users_id' => intval($users_id), ]; // 订单数据类型 switch ($type) { case 'all': // 全部 break; case 'payment'; // 待付款 $where['order_status'] = 0; break; case 'delivery'; // 待发货 $where['order_status'] = 1; break; case 'received'; // 待收货 $where['order_status'] = 2; break; case 'complete'; // 待评价 $where['order_status'] = 3; // $where['is_comment'] = 0; break; case 'close'; // 订单关闭 $where['order_status'] = -1; break; } $result = Db::name('shop_order')->where($where)->order('order_id desc')->paginate(15, false, ['query' => request()->param()]); !empty($result) && $result = $result->toArray(); $order_ids = get_arr_column($result['data'], 'order_id'); // 订单商品详情 $orderGoods = []; $where = [ 'users_id' => intval($users_id), 'order_id' => ['IN', $order_ids], ]; $goodsList = Db::name('shop_order_details')->where($where)->order('order_id desc')->select(); // 安装积分商城插件则执行 if (!empty($goodsList)) { $weappInfo = model('ShopPublicHandle')->getWeappPointsShop(); if (!empty($weappInfo)) { // 积分商城插件积分订单商品详情处理 $pointsOrderModel = new \app\plugins\model\PointsOrder(); $pointsGoodsBuyField = $pointsOrderModel->pointsGoodsOrderDetails($goodsList); } } foreach ($goodsList as $key => $_goods) { $_goods['product_price'] = unifyPriceHandle($_goods['product_price']); // 获取订单商品规格列表(购买时的商品规格) $_goods['product_spec_list'] = model('ShopPublicHandle')->getOrderGoodsSpecList($_goods); $_goods['litpic'] = $this->get_default_pic($_goods['litpic'], true); $orderGoods[$_goods['order_id']][] = $_goods; } // 模型名称 $channeltype_row = \think\Cache::get('extra_global_channeltype'); $channeltypeInfo = !empty($channeltype_row[2]) ? $channeltype_row[2] : []; $channel_ntitle = !empty($channeltypeInfo['ntitle']) ? $channeltypeInfo['ntitle'] : '商品'; $pay_method_arr = config('global.pay_method_arr'); $order_status_arr = config('global.order_status_arr'); foreach ($result['data'] as $key => &$_order) { $_order['shipping_fee'] = unifyPriceHandle($_order['shipping_fee']); $_order['order_amount'] = unifyPriceHandle($_order['order_amount']); $_order['order_total_amount'] = unifyPriceHandle($_order['order_total_amount']); $_order['pay_name_text'] = !empty($pay_method_arr[$_order['pay_name']]) ? $pay_method_arr[$_order['pay_name']] : '未支付'; $_order['order_status_text'] = $order_status_arr[$_order['order_status']]; $_order['add_time'] = MyDate('Y-m-d H:i:s', $_order['add_time']); $_order['goods'] = !empty($orderGoods[$_order['order_id']]) ? $orderGoods[$_order['order_id']] : []; $_order['channel_ntitle'] = '商品'; // $channel_ntitle; $_order['pointsGoodsBuyField'] = !empty($pointsGoodsBuyField[$_order['order_id']]) ? $pointsGoodsBuyField[$_order['order_id']] : []; } return $result; } // 取消订单 public function orderCancel($order_id, $users_id) { // 更新条件 $Where = [ 'order_id' => $order_id, 'users_id' => $users_id, ]; // 更新数据 $Data = [ 'order_status' => -1, 'update_time' => getTime(), ]; // 更新订单主表 $return = Db::name('shop_order')->where($Where)->update($Data); if (!empty($return)) { //还原优惠券 $use_id = Db::name('shop_order')->where($Where)->value('use_id'); if (!empty($use_id)){ $coupon_use = Db::name('shop_coupon_use')->where(['use_id'=>$use_id])->find(); if (!empty($coupon_use)){ if ($coupon_use['start_time'] <= getTime() && $coupon_use['end_time'] >= getTime()){ $use_update = ['use_status'=>0]; }else{ $use_update = ['use_status'=>2]; } $use_update['use_time'] = 0; $use_update['update_time'] = getTime(); Db::name('shop_coupon_use')->where(['use_id'=>$use_id,'users_id' => $users_id])->update($use_update); } } //查询是否是秒杀订单 $order_info = Db::name('shop_order')->where($Where)->find(); $productSpecValue = new \app\user\model\ProductSpecValue; if (20 == $order_info['order_source']){ $productSpecValue->SaveSharpStock($order_id, $users_id,$order_info); }else{ // 订单取消,还原单内产品数量 $productSpecValue->SaveProducSpecValueStock($order_id, $users_id); } // 如果安装了秒杀插件则执行 if (is_dir('./weapp/Seckill/')) { $SeckillRow = model('Weapp')->getWeappList('Seckill'); //is_seckill_order 只有安装了秒杀插件 shop_order表才会有这个字段 if (!empty($SeckillRow) && 1 == intval($SeckillRow['status']) && !empty($order['is_seckill_order'])) { // 调用秒杀逻辑层方法 $weappSeckillLogic = new \weapp\Seckill\logic\SeckillLogic; $weappSeckillLogic->cancelOrderHandle($order_id, $users_id); } } // 添加订单操作记录 AddOrderAction($order_id, $users_id, 0, 0, 0, 0, '订单取消!', '会员关闭订单!'); $this->success('订单取消成功!'); } } // 订单提醒发货 public function orderRemind($order_id = 0, $users_id = 0) { $post = input('post.'); // 添加订单操作记录 AddOrderAction($order_id, $users_id, 0, 1, 0, 1, '提醒成功!', '会员提醒管理员及时发货!'); $this->success('提醒成功'); } // 确认收货 public function orderReceipt($order_id, $users_id) { // 更新条件 $where = [ 'order_id' => $order_id, 'users_id' => $users_id, ]; $order = Db::name('shop_order')->where($where)->find(); $orderStatus = empty($order['order_status']) ? 0 : intval($order['order_status']); if (2 === intval($orderStatus)) { // 更新数据 $update = [ 'order_status' => 3, 'confirm_time' => getTime(), 'update_time' => getTime(), ]; // 更新订单主表 $return = Db::name('shop_order')->where($where)->update($update); if (!empty($return)) { // 更新数据 $update = [ 'update_time' => getTime(), ]; // 更新订单明细表 Db::name('shop_order_details')->where($where)->update($update); // 添加订单操作记录 AddOrderAction($order_id, $users_id, 0, 3, 1, 1, '确认收货!', '会员已确认收到货物,订单完成!'); // 如果安装了分销插件则执行 if (is_dir('./weapp/DealerPlugin/')) { // 开启分销插件则执行 $data = model('Weapp')->getWeappList('DealerPlugin'); if (!empty($data['status']) && 1 == $data['status']) { // 调用分销逻辑层方法 $dealerCommonLogic = new \weapp\DealerPlugin\logic\DealerCommonLogic; $dealerCommonLogic->dealerOrderSettlementExecute($order_id, $users_id); } } // 如果安装了秒杀插件则执行 if (is_dir('./weapp/Seckill/')) { $SeckillRow = model('Weapp')->getWeappList('Seckill'); //is_seckill_order 只有安装了秒杀插件 shop_order表才会有这个字段 if (!empty($SeckillRow) && 1 == intval($SeckillRow['status']) && !empty($order['is_seckill_order'])) { // 调用秒杀逻辑层方法 $weappSeckillLogic = new \weapp\Seckill\logic\SeckillLogic; $weappSeckillLogic->confirmOrderHandle($order_id, $users_id); } } $this->success('确认收货成功'); } else { $this->error('101:订单异常,请刷新重试'); } } else { $this->error('102:订单异常,请刷新重试'); } } /** * 订单详情 * @param $order_id * @param null $user_id * @return null|static * @throws BaseException * @throws \think\exception\DbException */ public function getOrderDetail($order_id, $users_id) { // 公共条件 $Where = [ 'order_id' => $order_id, 'users_id' => $users_id, ]; // 订单主表 $result = Db::name("shop_order")->where($Where)->find(); if (empty($result)) { $this->error('订单不存在!'); } // 优化显示金额 $result['coupon_price'] = unifyPriceHandle($result['coupon_price']); $result['shipping_fee'] = unifyPriceHandle($result['shipping_fee']); $result['order_amount'] = unifyPriceHandle($result['order_amount']); $result['order_total_amount'] = unifyPriceHandle($result['order_total_amount']); // 模型名称 $channeltype_row = \think\Cache::get('extra_global_channeltype'); $channeltypeInfo = !empty($channeltype_row[2]) ? $channeltype_row[2] : []; $result['channel_ntitle'] = '商品'; // !empty($channeltypeInfo['ntitle']) ? $channeltypeInfo['ntitle'] : '商品'; // 获取订单状态 $order_status_arr = config('global.order_status_arr'); $result['order_status_text'] = $order_status_arr[$result['order_status']]; // 获取订单支付方式 $pay_method_arr = config('global.pay_method_arr'); $result['pay_name_text'] = !empty($pay_method_arr[$result['pay_name']]) ? $pay_method_arr[$result['pay_name']] : '未支付'; // 收货地址 $result['province_text'] = $this->GetRegionName($result['province'], 1); $result['city_text'] = $this->GetRegionName($result['city'], 2); $result['district_text'] = $this->GetRegionName($result['district'], 3); // 下单时间 $result['add_time'] = MyDate('Y-m-d H:i:s', $result['add_time']); // 订单总金额 $result['TotalAmount'] = 0.00; // 订单明细表 $result['goods'] = Db::name("shop_order_details")->order('product_price desc, product_name desc')->where($Where)->select(); // 订单操作记录 $result['orderLog'] = Db::name('shop_order_log')->where('order_id', $order_id)->order('action_id desc')->select(); foreach ($result['orderLog'] as $key => $value) { $result['orderLog'][$key]['add_time'] = MyDate('Y-m-d H:i:s', $value['add_time']); } // 安装积分商城插件则执行 $result['pointsGoodsBuyField'] = []; if (!empty($result['goods'])) { $weappInfo = model('ShopPublicHandle')->getWeappPointsShop(); if (!empty($weappInfo)) { // 积分商城插件积分订单商品详情处理 $pointsOrderModel = new \app\plugins\model\PointsOrder(); $pointsGoodsBuyField = $pointsOrderModel->pointsGoodsOrderDetails($result['goods']); $result['pointsGoodsBuyField'] = !empty($pointsGoodsBuyField[$result['order_id']]) ? $pointsGoodsBuyField[$result['order_id']] : []; } } // 安装订单核销插件则执行 $result['verify'] = []; if (!empty($result['verify_id'])) { $weappInfo = model('ShopPublicHandle')->getWeappVerifyInfo(); if (!empty($weappInfo)) { // 订单核销插件核销订单商品详情处理 $verifyModel = new \app\plugins\model\Verify(); $result['verify'] = $verifyModel->verifyOrderDetails($result); } } //虚拟商品拼接回复 $virtual_delivery = ''; // 虚拟发货 $virtual_delivery_status = false; // 商品处理 foreach ($result['goods'] as $key => $value) { $result['prom_type'] = $value['prom_type']; $result['goods'][$key]['product_price'] = unifyPriceHandle($value['product_price']); $result['goods'][$key]['product_spec_list'] = model('ShopPublicHandle')->getOrderGoodsSpecList($value); //虚拟需要自动发货的商品卖家回复拼接 if ($value['prom_type'] == 2 && 2 <= intval($result['order_status'])) { $virtual_delivery_status = true; //查询商品名称 // $product_title = Db::name('archives')->where('aid', $value['product_id'])->getField('title'); //查网盘信息 $netdisk = Db::name("product_netdisk")->where('aid', $value['product_id'])->find(); if ($netdisk) { // $virtual_delivery .= "商品标题:" . $product_title . ""; $virtual_delivery .= "网盘地址:" . $netdisk['netdisk_url'] . ""; if (!empty($netdisk['netdisk_pwd'])) { $virtual_delivery .= "提取码:" . $netdisk['netdisk_pwd'] . ""; } if (!empty($netdisk['unzip_pwd'])) { $virtual_delivery .= "解压密码:" . $netdisk['unzip_pwd'] . ""; } $virtual_delivery .= "--------------------"; } $result['netdisk'] = $netdisk; } else if ($value['prom_type'] == 3 && 2 <= intval($result['order_status'])) { $virtual_delivery_status = true; //查询商品名称 // $product_title = Db::name('archives')->where('aid', $value['product_id'])->getField('title'); //查网盘信息 $netdisk = Db::name("product_netdisk")->where('aid', $value['product_id'])->find(); if ($netdisk) { // $virtual_delivery .= "商品标题:" . $product_title . ""; $virtual_delivery .= "文本内容:" . $netdisk['text_content'] . ""; $virtual_delivery .= "--------------------"; } $result['netdisk'] = $netdisk; } else if ($value['prom_type'] == 1) { $virtual_delivery_status = true; //查询商品名称 if (!empty($result['virtual_delivery'])) { // $product_title = Db::name('archives')->where('aid', $value['product_id'])->getField('title'); // $virtual_delivery .= "商品标题:" . $product_title . ""; $virtual_delivery .= filter_line_return($result['virtual_delivery'], '') . ""; $virtual_delivery .= "--------------------"; } } $result['virtual_delivery_status'] = $virtual_delivery_status; if ($virtual_delivery_status && !empty($virtual_delivery)) $result['virtual_delivery'] = $virtual_delivery; // 商品属性处理 $ValueData = unserialize($value['data']); $spec_value = !empty($ValueData['spec_value']) ? htmlspecialchars_decode($ValueData['spec_value']) : ''; $spec_value = !empty($spec_value) ? htmlspecialchars_decode($spec_value) : ''; // 旧参数+规格值 // $attr_value = !empty($ValueData['attr_value']) ? htmlspecialchars_decode($ValueData['attr_value']) : ''; // $attr_value = htmlspecialchars_decode($attr_value); // $spec_data = $spec_value . $attr_value; // $spec_data = str_replace('
', ';', $spec_data); // $result['goods'][$key]['data'] = trim($spec_data, ';'); $result['goods'][$key]['data'] = trim(str_replace('
', ';', $spec_value), ';'); // 新参数+规格值 // $attr_value_new = !empty($ValueData['attr_value_new']) ? htmlspecialchars_decode($ValueData['attr_value_new']) : ''; // $attr_value_new = htmlspecialchars_decode($attr_value_new); // $new_spec_data = $spec_value . $attr_value_new; // $new_spec_data = str_replace('
', ';', $new_spec_data); // $result['goods'][$key]['new_data'] = trim($new_spec_data, ';'); $result['goods'][$key]['new_data'] = trim(str_replace('
', ';', $spec_value), ';'); // 图片处理 $result['goods'][$key]['litpic'] = $this->get_default_pic($value['litpic'], true); // 小计 $result['goods'][$key]['subtotal'] = $value['product_price'] * $value['num']; $result['goods'][$key]['subtotal'] = unifyPriceHandle($result['goods'][$key]['subtotal']); // 合计金额 $result['TotalAmount'] += $result['goods'][$key]['subtotal']; $result['TotalAmount'] = unifyPriceHandle($result['TotalAmount']); } // 自动关闭未付款订单时间 $orderUnpayCloseTime = getUsersConfigData('order.order_unpay_close_time'); $result['orderUnpayCloseTime'] = !empty($orderUnpayCloseTime) ? intval($orderUnpayCloseTime) / 60 : 0; return $result; } /** * 获取评价订单商品列表 * @param $order_id * @param $users_id */ public function getOrderComment($order_id, $users_id) { //判断该订单是否已经评价 $comment_count = Db::name('shop_order_comment')->where(['order_id' => $order_id, 'users_id' => $users_id, 'lang' => get_home_lang()])->count(); if (!empty($comment_count)) { $this->error('该订单已经评价!'); } $order_data = $this->getOrderDetail($order_id, $users_id); return $order_data['goods']; } public function getSaveComment($post, $users_id) { $order_id = intval($post['order_id']); //判断该订单是否已经评价 $comment_count = Db::name('shop_order_comment')->where(['order_id' => $order_id, 'users_id' => $users_id])->count(); if (!empty($comment_count)) { $this->error('该订单已经评价!'); } if (!empty($post['formData'])) { $post['formData'] = json_decode(htmlspecialchars_decode($post['formData']), true); $insert = []; $detail_ids = []; $order_code = Db::name('shop_order')->where(['order_id'=>$order_id])->value('order_code'); foreach ($post['formData'] as $k => $v) { $detail_ids[] = $v['order_details_id']; $uploadImg = ''; if (!empty($v['uploaded'])) { $uploadImg = implode(',', $v['uploaded']); } else if (!empty($v['image_list'])) { $uploadImg = implode(',', $v['image_list']); } $insert[] = [ 'upload_img' => serialize($uploadImg), 'total_score' => $v['score'], 'content' => serialize($v['content']), 'users_id' => $users_id, 'order_id' => $order_id, 'order_code' => $order_code, 'product_id' => $v['goods_id'], 'details_id' => $v['order_details_id'], 'add_time' => getTime(), 'update_time' => getTime(), ]; } $insert_data = Db::name('shop_order_comment')->insertAll($insert); if ($insert_data) { Db::name('shop_order') ->where([ 'order_id' => $order_id, 'users_id' => $users_id, 'order_status' => 3, ]) ->update(['is_comment' => 1, 'update_time' => getTime()]); if (!empty($detail_ids)) { Db::name('shop_order_details') ->where('details_id', 'in', $detail_ids) ->where('users_id', $users_id) ->update(['is_comment' => 1, 'update_time' => getTime()]); } \think\Cache::clear('archives'); $this->success('评价成功!'); } } $this->error('评价失败!'); } /** * 获取评论列表 */ public function getGoodsCommentList($goods_id = 0 ,$score = 0 ,$page = 1 ) { $field='a.*,u.nickname,u.head_pic'; // 筛选条件 $condition = [ 'a.product_id' => $goods_id, 'a.is_show' => 1, 'a.lang' => get_home_lang(), ]; $score > 0 && $condition['total_score'] = $score; $pagesize = empty($pagesize) ? config('paginate.list_rows') : $pagesize; $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args())); $result = cache($cacheKey); if (true || empty($result)) { $paginate = array( 'page' => $page, ); $pages = Db::name('shop_order_comment') ->field($field) ->alias('a') ->join('users u','a.users_id = u.users_id') ->where($condition) ->order('a.add_time desc') ->paginate($pagesize, false, $paginate); $result = $pages->toArray(); foreach ($result['data'] as $key => $val) { if ($val['is_anonymous'] == 1){ //匿名用户 $val['head_pic'] = get_head_pic(); $val['nickname'] = '匿名用户'; }else{ if (empty($val['head_pic'])){ $val['head_pic'] = get_head_pic(); } } $val['head_pic'] = get_default_pic($val['head_pic'],true); if (isset($val['add_time'])) { $val['add_time'] = date('Y-m-d H:i:s', $val['add_time']); } if (!empty($val['upload_img'])){ $val['upload_img'] = unserialize($val['upload_img']); $val['upload_img'] = explode(',',$val['upload_img']); foreach ($val['upload_img'] as $k => $v){ $val['upload_img'][$k] = get_default_pic($v,true); } } if (!empty($val['content'])){ $val['content'] = unserialize($val['content']); } $result['data'][$key] = $val; } $score_type = Db::name('shop_order_comment') ->where([ 'product_id' => $goods_id, 'is_show' => 1, 'lang' => get_home_lang(), ])->field('count(*) as count,total_score') ->group('total_score') ->getAllWithIndex('total_score'); $result['count']['goods'] = isset($score_type[1]) ? $score_type[1]['count'] : 0; $result['count']['middle'] = isset($score_type[2]) ? $score_type[2]['count'] : 0; $result['count']['bad'] = isset($score_type[3]) ? $score_type[3]['count'] : 0; $result['count']['all'] = $result['count']['goods']+$result['count']['middle']+$result['count']['bad'] ; cache($cacheKey, $result, null, 'getGoodsCommentList'); } return $result; } /** * 获取秒杀tabbar */ public function GetSharpTabbar() { $time = strtotime(date('Y-m-d')); $hour = date('H'); $where['b.status'] = 1; $where['a.status'] = 1; $where['b.is_del'] = 0; //非当日预告 $active = Db::name('sharp_active_time') ->alias('a') ->field('a.*,b.active_date') ->join('sharp_active b','a.active_id = b.active_id') ->where($where) ->where('b.active_date', '>',$time) ->order('b.active_date asc,a.active_time asc') ->select(); //当天 $data = Db::name('sharp_active_time') ->alias('a') ->field('a.*,b.active_date') ->join('sharp_active b','a.active_id = b.active_id') ->where($where) ->where('b.active_date', $time) ->where('a.active_time', '>=',$hour) ->order('active_time asc') ->select(); if (!empty($data) && !empty($active)){ $data[] = $active[0]; }else if (empty($data) && !empty($active)){ $data[] = $active; } $date = date('Y-m-d'); foreach ($data as $k => $v){ if ($v['active_time'] < 10){ $v['active_time'] = '0'.$v['active_time']; } $active_time = $v['active_time']; $v['active_time'] = $v['active_time'].':00'; $date_time = $date.' '.$v['active_time']; //2020-15-2-15 15:00 $time_plus = strtotime($date_time . "+1 hours"); //2020-15-2-15 15:00 $time_plus = date('Y-m-d H:i',$time_plus); //2020-15-2-15 16:00 if ($time == $v['active_date']){ if ($active_time == $hour){ $v['status'] = 10; $arr = ['正在疯抢','已开抢','正在疯抢',$time_plus,$time_plus,$date_time]; }else if ($active_time > $hour){ $v['status'] = 20; $arr = [$v['active_time'].' 场预告','即将开抢','即将开抢',$date_time,$time_plus,$date_time]; } }else{ $v['status'] = 30; $arr = [$date_time.' 开始','预告',$date_time.' 开始',$date_time,$time_plus,$date_time]; } $v['sharp_modular_text'] = $arr[0]; $v['status_text'] = $arr[1]; $v['status_text2'] = $arr[2]; $v['count_down_time'] = $arr[3]; $v['end_time'] = $arr[4]; $v['start_time'] = $arr[5]; $data[$k] = $v; } return $data; } /** * 获取秒杀列表 */ public function GetSharpIndex( $tid = 0 , $page = 1 ) { $pagesize = 10; $pagesize = empty($pagesize) ? config('paginate.list_rows') : $pagesize; $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args())); $result = cache($cacheKey); if (true || empty($result)) { $paginate = array( 'page' => $page, ); $pages = Db::name('sharp_active_goods') ->alias('a') ->field('c.*,b.litpic,b.title,a.*,b.users_price') ->join('archives b','a.aid = b.aid') ->join('sharp_goods c','a.sharp_goods_id = c.sharp_goods_id') ->where('a.active_time_id',$tid) ->paginate($pagesize, false, $paginate); $result = $pages->toArray(); $aids = []; foreach ($result['data'] as $k => $v){ $result['data'][$k]['litpic'] = get_default_pic($v['litpic'],true); if (1 == $v['is_sku']){ $aids[] = $v['aid']; } } //多规格 if (!empty($aids)) { $sku = Db::name('product_spec_value') ->field('*,min(seckill_price) as seckill_price') ->where('aid', 'in', $aids) ->group('aid') ->getAllWithIndex('aid'); } //sales_actual // foreach ($result['data'] as $k => $v){ if (1 == $v['is_sku'] && !empty($sku[$v['aid']])){ $v['seckill_price'] = $sku[$v['aid']]['seckill_price']; } $v['progress'] = 0; if (0 < $v['sales_actual']){ $count_stock = $v['sales_actual']+$v['seckill_stock']+$v['virtual_sales']; $v['progress'] = intval(($v['sales_actual']+$v['virtual_sales'])/$count_stock*100); }else{ if (0 < $v['virtual_sales']){ $v['progress'] = intval($v['virtual_sales']/($v['virtual_sales']+$v['seckill_stock'])*100);; } } if (0 < $v['virtual_sales']){ $v['sales_actual'] = $v['sales_actual'] +$v['virtual_sales']; } $result['data'][$k] = $v; } cache($cacheKey, $result, null, 'GetSharpIndex'); } return $result; } /** * 获取物流动态信息 * @param $express_name * @param $express_code * @param $express_order * @return array|bool */ public function orderExpress($express_name, $express_code, $express_order, $timestamp = '') { $data = [ 'express_name' => $express_name, 'express_order' => $express_order ]; // 快递100 请求查询接口 $data['list'] = $this->orderExpressQuery($express_code, $express_order); if ($data['list'] === false) { $this->error('没有找到物流信息!'); return false; } return $data; } /** * 执行查询 * @param $express_code * @param $express_order * @return bool */ private function orderExpressQuery($express_code, $express_order) { // 缓存索引 $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args())); if ($data = Cache::get($cacheKey)) { return $data; } // 查询物流链接 empty($timestamp) && $timestamp = getTime(); $postData = [ 'postid' => $express_order, 'id' => 1, 'valicode' => '', 'temp' => $timestamp, 'type' => $express_code, 'phone' => '', 'token' => '', 'platform' => 'MWWW', 'coname' => 'indexall', ]; $expressUrl = "https://m.kuaidi100.com/query"; $response = httpRequest($expressUrl, 'POST', $postData); $express = json_decode($response, true); // 记录错误信息 if (!isset($express['message']) || $express['message'] != 'ok') { $msg = '查询失败'; $this->error($msg); return false; } // $expressUrl = "https://m.kuaidi100.com/app/query/?com=".$express_code."&nu=".$express_order."&callbackurl="; // $mobileExpressUrl = "https://m.kuaidi100.com/index_all.html?type=".$result['express_code']."&postid=".$result['express_order']."&callbackurl=".$ReturnUrl; // 记录缓存, 时效5分钟 Cache::set($cacheKey, $express['data'], 300); return $express['data']; } /** * 执行查询 * @param $express_code * @param $express_order * @return bool */ private function orderExpressQuery2($express_code, $express_order) { // 缓存索引 $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args())); if ($data = Cache::get($cacheKey)) { return $data; } $key = 'anFrVFyu8015'; // '快递100 授权KEY'; $customer = 'B972EB01B5B32404957BE09C8FE85A51'; // '快递100 Customer'; // 参数设置 $postData = [ 'customer' => $customer, 'param' => json_encode([ 'resultv2' => '1', 'com' => $express_code, 'num' => $express_order ]) ]; $postData['sign'] = strtoupper(md5($postData['param'] . $key . $postData['customer'])); // 请求快递100 api $url = 'http://poll.kuaidi100.com/poll/query.do'; $result = httpRequest($url, 'POST', $postData); $express = json_decode($result, true); // 记录错误信息 if (isset($express['returnCode']) || !isset($express['data'])) { $msg = isset($express['message']) ? $express['message'] : '查询失败'; $this->error($msg); return false; } // 记录缓存, 时效5分钟 Cache::set($cacheKey, $express['data'], 300); return $express['data']; } /** * 构建支付请求的参数 * @param $users * @param $order * @param $payType * @return array * @throws BaseException * @throws \think\exception\DbException */ public function onOrderPayment($users, $order, $payType = 20) { if ($payType == 20) { // 微信支付 return $this->onPaymentByWechat($users, $order); } return []; } /** * 构建微信支付请求 * @param $users * @param $order * @return array * @throws BaseException * @throws \think\exception\DbException */ protected function onPaymentByWechat($users, $order) { // 统一下单API if (empty($this->miniproInfo['mchid']) || empty($this->miniproInfo['apikey'])) { return [ 'code' => 0, 'msg' => '很抱歉,请在网站小程序后台,完善微信支付配置!', ]; } $openid = Db::name('weapp_diyminipro_mall_users')->where(['users_id' => $users['users_id']])->getField('openid'); $payment = $this->unifiedorder($order['order_code'], $openid, $order['order_amount']); return $payment; } /** * 统一下单API * @param $order_code * @param $openid * @param $totalFee * @return array * @throws BaseException */ public function unifiedorder($order_code, $openid, $totalFee) { // 当前时间 $time = getTime(); // 生成随机字符串 $nonceStr = md5($time . $openid); // API参数 $params = [ 'appid' => $this->miniproInfo['appid'], 'attach' => '微信小程序支付', 'body' => $order_code, 'mch_id' => $this->miniproInfo['mchid'], 'nonce_str' => $nonceStr, 'notify_url' => url('api/v1/Api/wxpay_notify', [], true, true, 1, 1), // 异步通知地址 'openid' => $openid, 'out_trade_no' => $order_code, 'spbill_create_ip' => clientIP(), 'total_fee' => $totalFee * 100, // 价格:单位分 'trade_type' => 'JSAPI', ]; // 生成签名 $params['sign'] = model('v1.User')->makeSign($params, $this->miniproInfo['apikey']); // 请求API $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; $result = httpRequest($url, 'POST', model('v1.User')->toXml($params)); $prepay = model('v1.User')->fromXml($result); // 请求失败 if ($prepay['return_code'] === 'FAIL') { return [ 'code' => 0, 'msg' => "微信支付api:{$prepay['return_msg']}", ]; } if ($prepay['result_code'] === 'FAIL') { return [ 'code' => 0, 'msg' => "微信支付api:{$prepay['err_code_des']}", ]; } // 生成 nonce_str 供前端使用 $paySign = $this->makePaySign($this->miniproInfo['appid'], $params['nonce_str'], $prepay['prepay_id'], $time); return [ 'prepay_id' => $prepay['prepay_id'], 'nonceStr' => $nonceStr, 'timeStamp' => (string)$time, 'paySign' => $paySign ]; } /** * 生成paySign * @param $nonceStr * @param $prepay_id * @param $timeStamp * @return string */ private function makePaySign($appid, $nonceStr, $prepay_id, $timeStamp) { $data = [ 'appId' => $appid, 'nonceStr' => $nonceStr, 'package' => 'prepay_id=' . $prepay_id, 'signType' => 'MD5', 'timeStamp' => $timeStamp, ]; // 签名步骤一:按字典序排序参数 ksort($data); $string = model('v1.User')->toUrlParams($data); // 签名步骤二:在string后加入KEY $string = $string . '&key=' . $this->miniproInfo['apikey']; // 签名步骤三:MD5加密 $string = md5($string); // 签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result; } /** * 获取我的优惠券 */ public function GetMyCouponList($users_id, $type = 0) { // 筛选条件 $filter = []; //0-未使用 1-已使用 2-已过期 $filter['a.use_status'] = $type; // 订单数据类型 switch ($type) { case '0': // 未使用 $filter['a.end_time'] = ['>=',getTime()]; break; case '1'; // 已使用 break; case '2'; // 已过期 unset($filter['a.use_status']); $filter['a.end_time'] = ['<',getTime()]; break; } $filter['a.users_id'] = $users_id; $filter['b.coupon_id'] = ['>',0]; $result = Db::name('shop_coupon_use') ->alias('a') ->join('shop_coupon b','a.coupon_id = b.coupon_id','left') ->where($filter) ->order('a.add_time desc') ->paginate(10, false, [ 'query' => request()->param() ]); !empty($result) && $result = $result->toArray(); foreach ($result['data'] as $k => $v ) { $v['coupon_form_name'] = '满减券'; $v['start_time'] = date('Y/m/d',$v['start_time']); $v['end_time'] = date('Y/m/d',$v['end_time']); switch ($v['coupon_type']) { case '1': // 未使用 $v['coupon_type_name'] = '全部商品'; break; case '2'; // 已使用 $v['coupon_type_name'] = '指定商品'; break; case '3'; // 已过期 $v['coupon_type_name'] = '指定分类'; break; } $result['data'][$k] = $v; } return $result; } /** * 领券中心 */ public function GetCouponCenter($users_id) { // 筛选条件 $filter = [ 'status' => 1 ]; $filter['start_date'] = ['<=',getTime()]; $filter['end_date'] = ['>=',getTime()]; $coupon_type = input('param.coupon_type/d'); if (!empty($coupon_type)) $filter['coupon_type'] = $coupon_type; $result = Db::name('shop_coupon') ->where($filter) ->order('sort_order asc,coupon_id desc') ->paginate(6, false, [ 'query' => request()->param() ]); if (!empty($result)) { $coupon_ids = []; $result = $result->toArray(); foreach ($result['data'] as $k => $v ) { $coupon_ids[] = $v['coupon_id']; $v['coupon_form_name'] = '满减券'; $v['start_date'] = date('Y/m/d',$v['start_date']); $v['end_date'] = date('Y/m/d',$v['end_date']); switch ($v['use_type']) { case '1': // 固定期限有效 $v['use_start_time'] = date('Y/m/d',$v['use_start_time']); $v['use_end_time'] = date('Y/m/d',$v['use_end_time']); $v['use_type_name'] = $v['use_start_time'].'-'.$v['use_end_time']; break; case '2'; // 领取当天开始有效 $v['use_type_name'] = '领取'.$v['valid_days'].'天内有效'; break; case '3'; // 领取次日开始有效 $v['use_type_name'] = '领取次日开始'.$v['valid_days'].'天内有效'; break; } $result['data'][$k] = $v; } $have_where['users_id'] = $users_id; $have_where['coupon_id'] = ['in',$coupon_ids]; $have_where['use_status'] = 0; $have = Db::name('shop_coupon_use')->where($have_where)->column('coupon_id'); if (!empty($have)){ foreach ($result['data'] as $k => $v ) { if (in_array($v['coupon_id'],$have)){ $result['data'][$k]['geted'] = 1;//当前还有已领取未使用的 } } } } return $result; } // 会员余额记录 public function getUsersMoneyDetails($users = [], $param = []) { $where = [ 'status' => ['IN', [2, 3]], 'users_id' => $param['users_id'], ]; $UsersMoney = Db::name('users_money')->where($where)->order('moneyid desc')->select(); // 获取金额明细类型 $pay_cause_type_arr = Config::get('global.pay_cause_type_arr'); // 获取金额明细状态 $pay_status_arr = Config::get('global.pay_status_arr'); foreach ($UsersMoney as $key => $value) { $value['status_name'] = $pay_status_arr[$value['status']]; $value['add_time'] = MyDate('Y-m-d H:i:s', $value['add_time']); $value['cause_type_name'] = $pay_cause_type_arr[$value['cause_type']]; $UsersMoney[$key] = $value; } $users['MoneyList'] = $UsersMoney; // 会员余额首页 $this->success('查询成功', null, $users); } // 会员余额充值 public function getUsersMoneyRecharge($param = []) { if (empty($param['usersMoney'])) $this->error('请输入充值金额'); // 记录类型,充值 $cause_type = 1; // 清理当前会员的未支付的充值记录 $where = [ 'status' => 1, 'cause_type' => $cause_type, 'users_id' => $param['users_id'], ]; Db::name('users_money')->where($where)->delete(); // 查询当前会员的余额 $where = [ 'users_id' => $param['users_id'] ]; $UsersMoney = Db::name('users')->where($where)->getField('users_money'); // 充值记录数据处理 $time = getTime(); // 订单号规则 $OrderNumber = date('Ymd') . $time . rand(10, 100); // 支付类型中文名称 $pay_cause_type_arr = Config::get('global.pay_cause_type_arr'); // 记录数据 $insert = [ 'users_id' => $param['users_id'], 'cause_type' => $cause_type, 'cause' => $pay_cause_type_arr[$cause_type], 'money' => $param['usersMoney'], 'users_money' => $UsersMoney + $param['usersMoney'], 'pay_method' => 'wechat', 'pay_details' => '', 'order_number' => $OrderNumber, 'status' => 1, 'add_time' => $time ]; $insertID = Db::name('users_money')->insertGetId($insert); if (!empty($insertID)) { $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid'); $Data = $this->GetWechatAppletsPay($openid, $OrderNumber, $param['usersMoney']); $ResultData = [ 'WeChatPay' => $Data, 'OrderData' => [ 'moneyid' => $insertID, 'order_number' => $OrderNumber ] ]; $this->success('正在支付', null, $ResultData); } else { $this->error('充值失败'); } } // 会员余额充值后续处理 public function getUsersMoneyRechargePay($param = []) { // 查询订单信息 $where = [ 'cause_type' => 1, 'users_id' => $param['users_id'], 'moneyid' => $param['moneyid'], 'order_number' => $param['order_number'], ]; $usersMoney = Db::name('users_money')->where($where)->find(); if (empty($usersMoney)) $this->error('订单错误,刷新重试'); if (1 !== intval($usersMoney['status'])) $this->error('订单已被处理,刷新重试'); // 查询会员openid $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid'); // 下单确认页数据处理 $WeChatPay = $this->GetWeChatPayDetails($openid, $param['order_number']); // 判断处理订单是否真实支付并处理订单 if (!empty($WeChatPay) && 'SUCCESS' == $WeChatPay['return_code'] && 'OK' == $WeChatPay['return_msg'] && 'SUCCESS' == $WeChatPay['trade_state']) { // 充值订单已支付,将订单更新为已支付 $update = [ 'status' => 2, 'pay_details' => serialize($WeChatPay), 'update_time' => getTime(), ]; $ResultID = Db::name('users_money')->where($where)->update($update); if (!empty($ResultID)) { // 增加会员余额 $update = [ 'users_money' => Db::raw('users_money+'.($usersMoney['money'])), ]; $ResultID = Db::name('users')->where('users_id', $param['users_id'])->update($update); if (!empty($ResultID)) { // 将充值订单更新为已完成 $update = [ 'status' => 3, 'update_time' => getTime(), ]; Db::name('users_money')->where($where)->update($update); //统计余额充值 eyou_statistics_data(5, floatval($usersMoney['money'])); // 返回结束 $this->success('支付完成'); } } $this->success('订单处理失败,请联系管理员'); } } // 查询会员支付信息详情 public function GetWeChatPayDetails($openid = 0, $orderCode = 0) { // 当前时间戳 $time = getTime(); // 当前时间戳 + openid 经 MD5加密 $nonceStr = md5($time . $openid); // 调用支付接口参数 $params = [ 'appid' => $this->miniproInfo['appid'], 'mch_id' => $this->miniproInfo['mchid'], 'nonce_str' => $nonceStr, 'out_trade_no' => $orderCode ]; // 生成参数签名 $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']); // 生成参数XML格式 $ParamsXml = $this->ParamsXml($params); // 调用接口返回数据 $url = 'https://api.mch.weixin.qq.com/pay/orderquery'; $result = httpRequest($url, 'POST', $ParamsXml); // 解析XML格式 $ResultData = $this->ResultXml($result); return $ResultData; } // 查询订单内的指定的某个商品,判断是否已申请售后或已评价商品 public function getOrderGoodsDetect($param = []) { // 查询商品 $where = [ 'users_id' => $param['users_id'], 'order_id' => $param['order_id'], 'details_id' => $param['details_id'], 'product_id' => $param['product_id'] ]; $field = 'details_id, order_id, users_id, product_id, apply_service, is_comment'; $orderGoods = Db::name("shop_order_details")->where($where)->field($field)->find(); if (empty($orderGoods)) $this->error('订单商品不存在'); $orderGoods['service_id'] = 0; // 检测商品是否可以进行下一步操作 if ('service' == $param['use']) { if (!empty($orderGoods['apply_service'])) { $where['status'] = ['NEQ', 8]; $orderGoods['service_id'] = Db::name('shop_order_service')->where($where)->getField('service_id'); } } else if ('comment' == $param['use']) { if (!empty($orderGoods['is_comment'])) { $url = strval('/pages/article/view?aid=' . $param['product_id']); $this->success('订单商品已完成评价', $url, false); } } // 返回信息 $this->success('检测完成', null, $orderGoods); } // 查询售后服务单列表 public function getOrderGoodsServiceList($param = []) { $where = [ 'users_id' => $param['users_id'], ]; if (!empty($param['serviceStatus']) && 1 == $param['serviceStatus']) { $where['status'] = ['IN', [1, 2, 4, 5]]; } else if (!empty($param['serviceStatus']) && 2 == $param['serviceStatus']) { $where['status'] = ['IN', [6, 7]]; } $field = 'service_id, service_type, users_id, product_name, product_img, status, add_time'; // 分页参数 $Query = request()->param(); // 查询订单数据 $result = Db::name('shop_order_service')->field($field)->where($where)->paginate(15, false, ['query' => $Query]); !empty($result) && $serviceData = $result->toArray(); if (!empty($serviceData['data'])) { $orderServiceType = Config::get('global.order_service_type'); $orderServiceStatus = Config::get('global.order_service_status'); foreach ($serviceData['data'] as $key => $value) { // 处理数据 $value['add_time'] = MyDate('Y-m-d H:i:s', $value['add_time']); $value['product_img'] = $this->get_default_pic($value['product_img'], true); $value['status_name'] = $orderServiceStatus[$value['status']]; $value['service_type_name'] = $orderServiceType[$value['service_type']]; // 重载数据 $serviceData['data'][$key] = $value; } } $this->success('查询成功', null, $serviceData); } // 查询申请售后的订单商品 public function getOrderGoodsService($param = []) { $serviceData = $serviceDataLog = $expressData = []; if (!empty($param['service_id'])) { // 如果存在则查询售后服务订单 $where = [ 'users_id' => $param['users_id'], 'service_id' => $param['service_id'], ]; $serviceData = Db::name('shop_order_service')->where($where)->find(); if (empty($serviceData)) $this->error('售后订单不存在'); $uploadImg = explode(',', $serviceData['upload_img']); foreach ($uploadImg as $key => $value) { if (!empty($value)) { $uploadImg[$key] = $this->get_default_pic($value, true); } else { unset($serviceImg[$key]); } } $serviceData['upload_img'] = $uploadImg; $serviceData['add_time'] = MyDate('Y-m-d H:i:s', $serviceData['add_time']); $serviceData['product_img'] = $this->get_default_pic($serviceData['product_img'], true); $serviceData['status_name'] = Config::get('global.order_service_status')[$serviceData['status']]; $serviceData['service_type_name'] = Config::get('global.order_service_type')[$serviceData['service_type']]; $serviceData['admin_delivery'] = !empty($serviceData['admin_delivery']) ? unserialize($serviceData['admin_delivery']) : ''; $serviceData['users_delivery'] = !empty($serviceData['users_delivery']) ? unserialize($serviceData['users_delivery']) : ''; // 查询售后订单流程记录 $where = [ 'service_id' => $param['service_id'], ]; $serviceDataLog = Db::name('shop_order_service_log')->order('log_id desc')->where($where)->select(); foreach ($serviceDataLog as $key => $value) { if (!empty($value['users_id'])) { $serviceDataLog[$key]['name'] = '会员'; } else if (!empty($value['admin_id'])) { $serviceDataLog[$key]['name'] = '商家'; } $serviceDataLog[$key]['add_time'] = MyDate('Y-m-d H:i:s', $value['add_time']); } // 物流数据表 $expressData = Db::name('shop_express')->select(); // 追加参数用于查询 $param['order_id'] = $serviceData['order_id']; $param['product_id'] = $serviceData['product_id']; $param['details_id'] = $serviceData['details_id']; } // 查询商品 $where = [ 'a.users_id' => $param['users_id'], 'a.order_id' => $param['order_id'], 'a.details_id' => $param['details_id'], 'a.product_id' => $param['product_id'] ]; $field = 'a.users_id, a.order_id, b.order_code, a.details_id, a.product_id, a.product_name, a.product_price, a.num as product_num, a.litpic, a.apply_service, b.pay_time, b.consignee, b.mobile, b.province, b.city, b.district, b.address'; $orderGoods = Db::name("shop_order_details")->alias('a')->join('__SHOP_ORDER__ b', 'a.order_id = b.order_id', 'LEFT')->where($where)->field($field)->find(); if (empty($orderGoods)) $this->error('订单商品不存在'); // 处理商品信息 $orderGoods['litpic'] = $this->get_default_pic($orderGoods['litpic'], true); $orderGoods['pay_time'] = MyDate('Y-m-d H:i:s', $orderGoods['pay_time']); $Province = $this->GetRegionName($orderGoods['province']); $City = $this->GetRegionName($orderGoods['city']); $District = $this->GetRegionName($orderGoods['district']); $orderGoods['address'] = $Province . ' ' . $City . ' ' . $District . ' ' . $orderGoods['address']; // 后台设置的商家收货地址 $orderGoods['admin_addr'] = getUsersConfigData('addr'); // 物流数据 $orderGoods['express'] = $expressData; // 售后服务订单 $orderGoods['service'] = $serviceData; $orderGoods['service_log'] = $serviceDataLog; $this->success('查询成功', null, $orderGoods); } // 添加申请售后的订单商品入库 public function addOrderGoodsService($param = []) { // 解析参数 $formData = htmlspecialchars_decode($param['formData']); $formData = json_decode(htmlspecialchars_decode($formData), true); // 查询是否已申请售后 $where = [ 'status' => ['NEQ', 8], 'users_id' => $param['users_id'], 'order_id' => $formData['order_id'], 'product_id' => $formData['product_id'], 'details_id' => $formData['details_id'] ]; $IsCount = Db::name('shop_order_service')->where($where)->count(); if (!empty($IsCount)) $this->error('订单商品已申请售后'); $time = getTime(); $addService = [ 'service_type' => !empty($formData['service_type']) ? intval($formData['service_type']) : 0, 'users_id' => intval($param['users_id']), 'order_id' => !empty($formData['order_id']) ? intval($formData['order_id']) : 0, 'order_code' => !empty($formData['order_code']) ? strval($formData['order_code']) : 0, 'details_id' => !empty($formData['details_id']) ? intval($formData['details_id']) : 0, 'product_id' => !empty($formData['product_id']) ? intval($formData['product_id']) : 0, 'product_name' => !empty($formData['product_name']) ? strval($formData['product_name']) : '', 'product_num' => !empty($formData['product_num']) ? intval($formData['product_num']) : 0, 'product_img' => !empty($formData['litpic']) ? strval($formData['litpic']) : '', 'content' => !empty($formData['content']) ? htmlspecialchars($formData['content']) : '', 'upload_img' => !empty($formData['uploaded'][0]) ? implode(',', $formData['uploaded']) : '', 'address' => strval($formData['address']), 'consignee' => !empty($formData['consignee']) ? $formData['consignee'] : '', 'mobile' => !empty($formData['mobile']) ? $formData['mobile'] : 0, 'refund_price' => !empty($formData['product_price']) ? $formData['product_price'] : 0, 'refund_code' => 'HH' . $time . rand(10,100), 'add_time' => $time, 'update_time' => $time, ]; if (2 == $addService['service_type'] && !empty($addService['refund_price'])) $addService['refund_code'] = 'TK' . $time . rand(10,100); $ResultID = Db::name('shop_order_service')->insertGetId($addService); // 申请售后后续操作 if (!empty($ResultID)) { // 更新订单明细表中对应商品为申请服务 $update = [ 'details_id' => $addService['details_id'], 'apply_service' => 1, 'update_time' => getTime() ]; Db::name('shop_order_details')->update($update); // 添加订单服务记录 $LogNote = 1 == $addService['service_type'] ? '会员提交换货申请,待管理员审核!' : '会员提交退货申请,待管理员审核!'; OrderServiceLog($ResultID, $addService['order_id'], $addService['users_id'], 0, $LogNote); // 申请成功返回 $this->success('已申请,待审核'); } else { $this->error('申请售后失败'); } } // 取消售后订单会员邮寄物流信息 public function cancelOrderGoodsService($param = []) { // 取消服务单 $where = [ 'users_id' => $param['users_id'], 'service_id' => $param['service_id'] ]; $update = [ 'status' => 8, 'update_time' => getTime(), ]; $ResultID = Db::name('shop_order_service')->where($where)->update($update); if (!empty($ResultID)) { // 更新订单明细表中对应商品为未申请服务 $where = [ 'users_id' => $param['users_id'], 'details_id' => $param['details_id'] ]; $update = [ 'apply_service' => 0, 'update_time' => getTime() ]; Db::name('shop_order_details')->where($where)->update($update); // 添加记录单 $param['status'] = 8; $this->addOrderServiceLog($param); $this->success('取消成功'); } else { $this->error('取消失败'); } } // 添加售后订单会员邮寄物流信息 public function addServiceUsersDelivery($param = []) { // 解析物流参数 $usersDelivery = htmlspecialchars_decode($param['usersDelivery']); $usersDelivery = json_decode(htmlspecialchars_decode($usersDelivery), true); // 更新处理 $where = [ 'users_id' => $param['users_id'], 'service_id' => $param['service_id'], ]; $update = [ 'status' => 4, 'users_delivery' => !empty($usersDelivery) ? serialize($usersDelivery) : '', 'update_time' => getTime(), ]; $ResultID = Db::name('shop_order_service')->where($where)->update($update); if (!empty($ResultID)) { // 添加记录单 $param['status'] = 4; $this->addOrderServiceLog($param); $this->success('提交物流成功'); } else { $this->error('提交物流失败'); } } // 记录商品退换货服务单信息 private function addOrderServiceLog($param = []) { if (empty($param)) return false; if (2 == $param['status']) { $LogNote = '商家通过申请,等待会员将货物寄回商家!'; } else if (3 == $param['status']) { $LogNote = '商家拒绝申请,请联系商家处理!'; } else if (4 == $param['status']) { $LogNote = '会员已将货物发出,等待商家收货!'; } else if (5 == $param['status']) { $LogNote = '商家已收到货物,待管理员进行退换货处理!'; } else if (6 == $param['status']) { $LogNote = '商家已将新货物重新发出,换货完成,服务结束!'; } else if (7 == $param['status']) { $LogNote = '商家已将金额、余额、积分退回,退款完成,服务结束!'; } else if (8 == $param['status']) { $LogNote = '服务单被取消,服务结束!'; } OrderServiceLog($param['service_id'], $param['order_id'], $param['users_id'], 0, $LogNote); } /************************** 限时折扣 开始 ****************************/ //获取单次显示折扣 public function getOneDiscount($param = []) { $avtive_id = !empty($param['activeid']) ? intval($param['activeid']) : 0; $where['status'] = 1; $where['is_del'] = 0; //如果没传活动id就取当前正在进行的 if (!empty($avtive_id)){ $where['active_id'] = $avtive_id; $active = Db::name('discount_active')->where($where)->find(); }else{ $where['start_date'] = ['<=',getTime()]; $where['end_date'] = ['>=',getTime()]; //获取已开始未结束的限时折扣 $active = Db::name('discount_active')->where($where)->find(); //如果没有就取即将开始的 if (empty($active)){ $active = Db::name('discount_active') ->where('status',1) ->where('is_del',0) ->where('start_date','>',getTime()) ->order('start_date asc') ->find(); } } $return = []; if (!empty($active)){ $return['active'] = $active; if ($active['start_date'] <= getTime()){ $return['active']['active_status'] = 10;//进行中 }else{ $return['active']['active_status'] = 20;//即将开始 } $param['active_id'] = $return['active']['active_id']; $return['goodsList'] = $this->getDiscountGoodsList($param); } return $return; } /** * 限时折扣:获取限时折扣商品列表 */ public function getDiscountGoodsList($param = []) { $limit = !empty($param['limit']) ? intval($param['limit']) : 6; $active_id = $param['active_id']; $data = Db::name('discount_active_goods') ->alias('a') ->field('c.*,b.litpic,b.title,a.*,b.users_price') ->join('archives b','a.aid = b.aid') ->join('discount_goods c','a.discount_goods_id = c.discount_gid') ->where('a.active_id',$active_id) ->limit($limit) ->getAllWithIndex('aid'); if (!empty($data)){ $aids = []; foreach ($data as $k => $v){ $data[$k]['litpic'] = get_default_pic($v['litpic'],true); if (1 == $v['is_sku']){ $aids[] = $v['aid']; } } //多规格 if (!empty($aids)){ $sku = Db::name('product_spec_value') ->field('*,min(discount_price) as discount_price') ->where('aid','in',$aids) ->group('aid') ->getAllWithIndex('aid'); } foreach ($data as $k => $v){ if (1 == $v['is_sku'] && !empty($sku[$v['aid']])){ $v['discount_price'] = $sku[$v['aid']]['discount_price']; } $v['progress'] = 0; if (0 < $v['sales_actual']){ $count_stock = $v['sales_actual']+$v['discount_stock']+$v['virtual_sales']; $v['progress'] = intval(($v['sales_actual']+$v['virtual_sales'])/$count_stock*100); }else{ if (0 < $v['virtual_sales']){ $v['progress'] = intval($v['virtual_sales']/($v['virtual_sales']+$v['discount_stock'])*100);; } } if (0 < $v['virtual_sales']){ $v['sales_actual'] = $v['sales_actual'] +$v['virtual_sales']; } $data[$k] = $v; } } return $data; } /** * 获取限时折扣列表 */ public function GetDiscountIndex($param = []) { $active_id = $param['active_id']; $page = !empty($param['page']) ? $param['page'] : 1; $pagesize = !empty($param['limit']) ? $param['limit'] : 20; $cacheKey = 'api-'.md5(__CLASS__.__FUNCTION__.json_encode(func_get_args())); $result = cache($cacheKey); if (true || empty($result)) { $paginate = array( 'page' => $page, ); $pages = Db::name('discount_active_goods') ->alias('a') ->field('c.*,b.litpic,b.title,a.*,b.users_price') ->join('archives b','a.aid = b.aid') ->join('discount_goods c','a.discount_goods_id = c.discount_gid') ->where('a.active_id',$active_id) ->paginate($pagesize, false, $paginate); $result = $pages->toArray(); $aids = []; foreach ($result['data'] as $k => $v){ $result['data'][$k]['litpic'] = get_default_pic($v['litpic'],true); if (1 == $v['is_sku']){ $aids[] = $v['aid']; } } //多规格 if (!empty($aids)) { $sku = Db::name('product_spec_value') ->field('*,min(discount_price) as discount_price') ->where('aid', 'in', $aids) ->group('aid') ->getAllWithIndex('aid'); } //sales_actual // foreach ($result['data'] as $k => $v){ if (1 == $v['is_sku'] && !empty($sku[$v['aid']])){ $v['discount_price'] = $sku[$v['aid']]['discount_price']; } $v['progress'] = 0; if (0 < $v['sales_actual']){ $count_stock = $v['sales_actual']+$v['discount_stock']+$v['virtual_sales']; $v['progress'] = intval(($v['sales_actual']+$v['virtual_sales'])/$count_stock*100); }else{ if (0 < $v['virtual_sales']){ $v['progress'] = intval($v['virtual_sales']/($v['virtual_sales']+$v['discount_stock'])*100);; } } if (0 < $v['virtual_sales']){ $v['sales_actual'] = $v['sales_actual'] + $v['virtual_sales']; } $result['data'][$k] = $v; } if(1 == $page){ $result['active'] = $this->GetDiscount($active_id); } cache($cacheKey, $result, null, 'GetDiscountIndex'); } return $result; } //获取限时折扣活动信息(不包括折扣商品信息) public function GetDiscount($active_id = 0){ $data = Db::name('discount_active')->where('active_id',$active_id)->find(); if ($data['start_date'] <= getTime()){ $data['active_status'] = 10;//进行中 }else{ $data['active_status'] = 20;//即将开始 } return $data; } /************************** 限时折扣 结束 ****************************/ /************************** 会员升级 开始 ****************************/ // 会员升级 public function upgradeUserLevel($param = []) { if (empty($param['type_id'])) $this->error('缺少升级类型'); $users_type_manage = Db::name('users_type_manage')->where('type_id',$param['type_id'])->find(); // 记录类型,消费 $cause_type = 0; // 清理当前会员的未支付的充值记录 $where = [ 'status' => 1, 'cause_type' => $cause_type, 'users_id' => $this->users_id, ]; Db::name('users_money')->where($where)->delete(); $times = getTime(); // 查询当前会员的余额 $where = [ 'users_id' => $this->users_id ]; $users = Db::name('users')->where($where)->find(); $UsersMoney = $users['users_money']; $level_name = Db::name('users_level')->where('level_id',$users['level'])->value('level_name'); // 充值记录数据处理 $time = getTime(); // 订单号规则 $OrderNumber = date('Ymd') . $time . rand(10, 100); $pay_detail = "会员当前级别为【{$level_name}】,使用微信支付【{$users_type_manage['type_name']}】,支付金额为{$users_type_manage['price']}"; // 记录数据 $insert = [ 'users_id' => $this->users_id, 'cause_type' => $cause_type, 'cause' => serialize($users_type_manage), 'money' => $users_type_manage['price'], 'users_money' => $UsersMoney - $users_type_manage['price'], 'pay_method' => 'wechat', 'pay_details' => serialize($pay_detail), 'order_number' => $OrderNumber, 'level_id' => $users_type_manage['level_id'], 'status' => 1, 'add_time' => $time ]; $insertID = Db::name('users_money')->insertGetId($insert); if (!empty($insertID)) { if ('wechat' == $param['pay_type']) { // 微信支付 $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid'); $notify_url = url('api/v1/Api/wxpay_notify_users', [], true, true, 1, 2); $Data = $this->GetWechatAppletsPay($openid, $OrderNumber, $users_type_manage['price'],$notify_url); $ResultData = [ 'WeChatPay' => $Data, 'OrderData' => [ 'moneyid' => $insertID, 'order_number' => $OrderNumber ] ]; $this->success('正在支付', null, $ResultData); } else if ('balance' == $param['pay_type']) { //先判断余额够不够 if ($users['users_money'] < $users_type_manage['price']){ $this->error('余额不足!'); } // 余额支付 $UpOrderData = [ 'status' => 2, 'pay_name' => 'balance', 'update_time' => getTime() ]; $ReturnID = Db::name('users_money')->where('order_number', $OrderNumber)->update($UpOrderData); if (!empty($ReturnID)) { $limit_arr = Config::get('global.admin_member_limit_arr'); $day = $limit_arr[$users_type_manage['limit_id']]['maturity_days']; $users_update['level_maturity_days'] = Db::Raw('level_maturity_days +'.$day); if (empty($users['level_maturity_days'])){ $users_update['open_level_time'] = getTime(); } $users_update['level'] = $users_type_manage['level_id']; $users_update['update_time'] = getTime(); $users_update['users_money'] = Db::Raw('users_money-'.$users_type_manage['price']); Db::name('users')->where('users_id', $param['users_id'])->update($users_update); $url = '/pages/user/index'; $this->success('支付完成', $url); } } } else { $this->error('会员升级失败'); } } // 会员升级 public function handleUpgradeUserLevel($param = []) { // 查询订单信息 $where = [ 'cause_type' => 0, 'users_id' => $this->users_id, 'order_number' => $param['order_number'], ]; $usersMoney = Db::name('users_money')->where($where)->find(); if (empty($usersMoney)) $this->error('订单错误,刷新重试'); if (1 !== intval($usersMoney['status'])) $this->error('订单已被处理,刷新重试'); // 查询会员openid $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid'); // 下单确认页数据处理 $WeChatPay = $this->GetWeChatPayDetails($openid, $param['order_number']); // 判断处理订单是否真实支付并处理订单 if (!empty($WeChatPay) && 'SUCCESS' == $WeChatPay['return_code'] && 'OK' == $WeChatPay['return_msg'] && 'SUCCESS' == $WeChatPay['trade_state']) { // 充值订单已支付,将订单更新为已支付 $update = [ 'status' => 2, 'update_time' => getTime(), ]; $ResultID = Db::name('users_money')->where($where)->update($update); if (!empty($ResultID)) { $usersMoney['cause'] = unserialize($usersMoney['cause']); $level_maturity_days = Db::name('users')->where('users_id', $param['users_id'])->value('level_maturity_days'); $limit_arr = Config::get('global.admin_member_limit_arr'); $day = $limit_arr[$usersMoney['cause']['limit_id']]['maturity_days']; $users_update['level_maturity_days'] = Db::Raw('level_maturity_days +'.$day); if (empty($level_maturity_days)){ $users_update['open_level_time'] = getTime(); } $users_update['level'] = $usersMoney['cause']['level_id']; $users_update['update_time'] = getTime(); Db::name('users')->where('users_id', $param['users_id'])->update($users_update); // 返回结束 $this->success('支付完成'); } $this->success('订单处理失败,请联系管理员'); } } // 微信小程序支付后续处理 public function WechatAppletsPayDealWithUsersMoney($PostData = [], $notify = false) { $OpenID = !empty($PostData['openid']) ? $PostData['openid'] : ''; $UsersID = !empty($PostData['users_id']) ? $PostData['users_id'] : ''; $order_number = $PostData['order_number']; if (!empty($moneyid) && !empty($order_number)) { $where = [ 'users_id' => $UsersID, 'order_number' => $order_number, ]; //查询订单状态 $order = Db::name('users_money')->where($where)->find(); if (empty($order)) { $this->error('无效订单!'); } else if (1 < $order['status']) { // 订单已支付 if ($notify === true) { // 异步 return [ 'code' => 1, 'msg' => 'ok', ]; } else { // 同步 $this->success('支付完成', '/pages/user/index'); } } // 当前时间戳 $time = getTime(); // 当前时间戳 + OpenID 经 MD5加密 $nonceStr = md5($time . $OpenID); // 调用支付接口参数 $params = [ 'appid' => $this->miniproInfo['appid'], 'mch_id' => $this->miniproInfo['mchid'], 'nonce_str' => $nonceStr, 'out_trade_no' => $order_number ]; // 生成参数签名 $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']); // 生成参数XML格式 $ParamsXml = $this->ParamsXml($params); // 调用接口返回数据 $url = 'https://api.mch.weixin.qq.com/pay/orderquery'; $result = $this->HttpsPost($url, $ParamsXml); // 解析XML格式 $ResultData = $this->ResultXml($result); // 订单是否存在 if (!empty($ResultData) && 'SUCCESS' == $ResultData['return_code'] && 'OK' == $ResultData['return_msg']) { // if ('NOTPAY' == $ResultData['trade_state'] && !empty($ResultData['trade_state_desc'])) { // // 订单未支付 // $this->error($ResultData['trade_state_desc']); // } if ('SUCCESS' == $ResultData['trade_state']) { // 订单已支付,处理订单流程 $OrderWhere = [ 'order_number' => $order_number, 'users_id' => $UsersID ]; $OrderData = [ 'status' => 2, 'update_time' => getTime() ]; $ResultID = Db::name('users_money')->where($OrderWhere)->update($OrderData); if (!empty($ResultID)) { $order['cause'] = unserialize($order['cause']); $level_maturity_days = Db::name('users')->where('users_id', $UsersID)->value('level_maturity_days'); $limit_arr = Config::get('global.admin_member_limit_arr'); $day = $limit_arr[$order['cause']['limit_id']]['maturity_days']; $users_update['level_maturity_days'] = Db::Raw('level_maturity_days +'.$day); if (empty($level_maturity_days)){ $users_update['open_level_time'] = getTime(); } $users_update['level'] = $order['cause']['level_id']; $users_update['update_time'] = getTime(); Db::name('users')->where('users_id', $UsersID)->update($users_update); // 订单支付完成 if ($notify === true) { // 异步 return [ 'code' => 1, 'msg' => 'ok', ]; } else { // 同步 $url = '/pages/user/index'; $this->success('支付完成', $url); } } } } } } /************************** 会员升级 结束 ****************************/ /************************** 视频购买 开始 ****************************/ // 视频购买 public function buyMedia($param = []) { if (empty($param['aid'])) $this->error('缺少必要参数'); // 清理当前会员的未支付的充值记录 $where = [ 'order_status' => 0, 'users_id' => $this->users_id, ]; Db::name('media_order')->where($where)->delete(); $users = Db::name('users') ->field('a.*,b.discount') ->alias('a') ->join('users_level b','a.level = b.level_id','left') ->where('a.users_id',$this->users_id) ->find(); $list = Db::name('archives')->where('aid',$param['aid'])->find(); $price = unifyPriceHandle($list['users_price'] * ($users['discount'] / 100)); // 生成订单并保存到数据库 $time = getTime(); $OrderData = [ 'order_code' => date('Y') . $time . rand(10,100), 'users_id' => $this->users_id, 'mobile' => !empty($users['mobile']) ?$users['mobile'] : '', 'order_status' => 0, 'order_amount' => $price, 'pay_time' => '', 'pay_name' => '', 'wechat_pay_type' => '', 'pay_details' => '', 'product_id' => $list['aid'], 'product_name' => $list['title'], 'product_litpic' => get_default_pic($list['litpic']), 'lang' => get_home_lang(), 'add_time' => $time, 'update_time' => $time ]; $insertID = Db::name('media_order')->insertGetId($OrderData); if (!empty($insertID)) { if ('wechat' == $param['pay_type']) { // 微信支付 $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid'); $notify_url = url('api/v1/Api/wxpay_notify_media', [], true, true, 1, 2); $Data = $this->GetWechatAppletsPay($openid, $OrderData['order_code'], $price,$notify_url); $ResultData = [ 'WeChatPay' => $Data, 'OrderData' => [ 'order_id' => $insertID, 'order_code' => $OrderData['order_code'] ] ]; $this->success('正在支付', null, $ResultData); } else if ('balance' == $param['pay_type']) { //先判断余额够不够 if ($users['users_money'] < $price){ $this->error('余额不足!'); } // 订单更新数据,更新为已付款 $pay_details['unified_id'] = $insertID; $pay_details['unified_number'] = $OrderData['order_code']; $pay_details['payment_type'] = '余额支付'; $pay_details['payment_amount'] = $price; $pay_details['transaction_type'] = 8; // 余额支付 $UpOrderData = [ 'order_status' => 1, 'pay_time' => getTime(), 'pay_name' => 'balance', 'pay_details' => serialize($pay_details), 'update_time' => getTime() ]; $ReturnID = Db::name('media_order')->where('order_code', $OrderData['order_code'])->update($UpOrderData); if (!empty($ReturnID)) { $Where = [ 'users_id' => $this->users_id ]; $UsersData = [ 'users_money' => Db::raw('users_money-'.$OrderData['order_amount']), 'update_time' => getTime() ]; Db::name('users')->where($Where)->update($UsersData); UsersMoneyRecording($OrderData['order_code'], $users, $OrderData['order_amount'], '视频购买', 3); $url = '/pages/user/index'; $this->success('支付完成', $url); } } } else { $this->error('会员升级失败'); } } // 会员升级 public function handleBuyMedia($param = []) { // 查询订单信息 $where = [ 'users_id' => $this->users_id, 'order_code' => $param['order_code'], ]; $order = Db::name('media_order')->where($where)->find(); if (empty($order)) $this->error('订单错误,刷新重试'); if (0 !== intval($order['status'])) $this->error('订单已被处理,刷新重试'); // 查询会员openid $openid = Db::name('wx_users')->where('users_id', $param['users_id'])->getField('openid'); // 下单确认页数据处理 $WeChatPay = $this->GetWeChatPayDetails($openid, $param['order_code']); // 判断处理订单是否真实支付并处理订单 if (!empty($WeChatPay) && 'SUCCESS' == $WeChatPay['return_code'] && 'OK' == $WeChatPay['return_msg'] && 'SUCCESS' == $WeChatPay['trade_state']) { // 视频订单已支付,将订单更新为已支付 // 订单更新数据,更新为已付款 $pay_details['unified_id'] = $order['order_id']; $pay_details['unified_number'] = $order['order_code']; $pay_details['payment_type'] = '微信支付'; $pay_details['payment_amount'] = $order['order_amount']; $pay_details['transaction_type'] = 8; // 余额支付 $UpOrderData = [ 'order_status' => 1, 'pay_time' => getTime(), 'pay_name' => 'wechat', 'wechat_pay_type' => 'WeChatScanCode', 'pay_details' => serialize($pay_details), 'update_time' => getTime() ]; $return = Db::name('media_order')->where('order_code', $param['order_code'])->update($UpOrderData); if (!empty($return)) { // 返回结束 $this->success('支付完成'); } $this->success('订单处理失败,请联系管理员'); } } // 微信小程序支付后续处理 public function WechatAppletsPayDealWithMedia($PostData = [], $notify = false) { $OpenID = !empty($PostData['openid']) ? $PostData['openid'] : ''; $UsersID = !empty($PostData['users_id']) ? $PostData['users_id'] : ''; $order_code = $PostData['order_code']; if (!empty($order_code)) { $where = [ 'users_id' => $UsersID, 'order_code' => $order_code, ]; //查询订单状态 $order = Db::name('media_order')->where($where)->find(); if (empty($order)) { $this->error('无效订单!'); } else if (0 < $order['status']) { // 订单已支付 if ($notify === true) { // 异步 return [ 'code' => 1, 'msg' => 'ok', ]; } else { // 同步 $this->success('支付完成', '/pages/user/index'); } } // 当前时间戳 $time = getTime(); // 当前时间戳 + OpenID 经 MD5加密 $nonceStr = md5($time . $OpenID); // 调用支付接口参数 $params = [ 'appid' => $this->miniproInfo['appid'], 'mch_id' => $this->miniproInfo['mchid'], 'nonce_str' => $nonceStr, 'out_trade_no' => $order_code ]; // 生成参数签名 $params['sign'] = $this->ParamsSign($params, $this->miniproInfo['apikey']); // 生成参数XML格式 $ParamsXml = $this->ParamsXml($params); // 调用接口返回数据 $url = 'https://api.mch.weixin.qq.com/pay/orderquery'; $result = $this->HttpsPost($url, $ParamsXml); // 解析XML格式 $ResultData = $this->ResultXml($result); // 订单是否存在 if (!empty($ResultData) && 'SUCCESS' == $ResultData['return_code'] && 'OK' == $ResultData['return_msg']) { // if ('NOTPAY' == $ResultData['trade_state'] && !empty($ResultData['trade_state_desc'])) { // // 订单未支付 // $this->error($ResultData['trade_state_desc']); // } if ('SUCCESS' == $ResultData['trade_state']) { // 订单已支付,处理订单流程 $OrderWhere = [ 'order_code' => $order_code, 'users_id' => $UsersID ]; // 订单更新数据,更新为已付款 $pay_details['unified_id'] = $order['order_id']; $pay_details['unified_number'] = $order['order_code']; $pay_details['payment_type'] = '微信支付'; $pay_details['payment_amount'] = $order['order_amount']; $pay_details['transaction_type'] = 8; // 余额支付 $UpOrderData = [ 'order_status' => 1, 'pay_time' => getTime(), 'pay_name' => 'wechat', 'wechat_pay_type' => 'WeChatScanCode', 'pay_details' => serialize($pay_details), 'update_time' => getTime() ]; $ResultID = Db::name('media_order')->where($OrderWhere)->update($UpOrderData); if (!empty($ResultID)) { // 订单支付完成 if ($notify === true) { // 异步 return [ 'code' => 1, 'msg' => 'ok', ]; } else { // 同步 $url = '/pages/user/index'; $this->success('支付完成', $url); } } } } } } /************************** 视频购买 结束 ****************************/ }