1); //小程序用户信息 static $openid; //小程序用户openid static $verifyToken = false;//是否验证过token protected $REQUEST_URL; //当前地址 protected $EMPTY_GOODS_IMG; //默认图片 /* @var array $allowAllAction 登录验证白名单 无需检测身份类型 */ protected $allowAllAction = array( 'Store/getStore_v1',//获取门店列表 'OrderEvaluate/userReleaseEvaluate',//评价 'Pay/placeOrder_v7',//下单 ); public function _initialize() { if (!self::$verifyToken) { $store_id = I('post.store_id'); //门店id $merchant_id = I('post.merchant_id'); //商户id $uid = I('post.uid'); //小程序用户id $openid = I('post.openid'); //小程序用户openid if (empty($merchant_id)) { $result['status'] = 0; $result['msg'] = '缺少必要参数merchant_id'; $this->ajaxReturn($result); } $RetailMerchantModel = D('RetailMerchant'); $merchantData = $RetailMerchantModel->getFindNormalMerchant($merchant_id); //判断商户是否正常 if ($merchantData['status'] == 0) { $result['status'] = 0; $result['msg'] = $merchantData['msg']; $this->ajaxReturn($result); } else { // 判断商户是否有小程序权限 $data = $merchantData['data']; if ($data[$RetailMerchantModel::SMALL_PROGRAM_STATE] != 2) { $result['status'] = 0; $result['msg'] = '商户暂无开启商城权限'; $this->ajaxReturn($result); } } $merchant = $merchantData['data']; $agentState = D('RetailAgent')->getFindNormalAgent($merchant[$RetailMerchantModel::AGENT_ID]); //判断代理商是否正常 if ($agentState['status'] != 1) { $result['status'] = 0; $result['msg'] = $agentState['msg']; $this->ajaxReturn($result); } if (!empty($store_id)) { //请求的接口中有store_id $RetailStoreModel = D('RetailStore'); $map = array( $RetailStoreModel::ID => $store_id, $RetailStoreModel::STATUS => 1, $RetailStoreModel::STORE_STATUS => 0, $RetailStoreModel::MERCHANT_ID => $merchant_id ); $store = $RetailStoreModel->getFind($map); //判断门店是否正常使用中 if (empty($store)) { $result['status'] = 0; $result['msg'] = '门店被禁用'; $this->ajaxReturn($result); } self::$store_id = $store_id; self::$store = $store; } if (is_numeric($uid)) { $SmallProgramUserModel = new RetailSmallProgramUserModel(); $map = array( $SmallProgramUserModel::ID => $uid, $SmallProgramUserModel::MERCHANT_ID => $merchant_id, $SmallProgramUserModel::OPENID => $openid, ); $user = $SmallProgramUserModel->getFind($map); if (empty($user)) { $result['status'] = 0; $result['msg'] = '您的请求有误'; $this->ajaxReturn($result); } self::$openid = $openid; $path = CONTROLLER_NAME . '/' . ACTION_NAME;//当前请求路径 if (!in_array($path, $this->allowAllAction)) { $keyItem = S('small_program_key_item_' . $user[$SmallProgramUserModel::ID]);//登录存储的数据 if (empty($keyItem)) { $result['status'] = -2; $result['msg'] = '您的登录超时,请删除小程序重试'; $this->ajaxReturn($result); } $keyItem = json_decode($keyItem, true); $post = I('post.'); if (!checkSign($post, $keyItem['key'])) { $result['status'] = 0; $result['msg'] = '请求发生错误,请删除小程序重试'; $this->ajaxReturn($result); } } $time = time(); $user_type = 1; //普通用户 if (!empty($user[$SmallProgramUserModel::VID])) { $user_type = 3; //常规会员 if ($user[$SmallProgramUserModel::USER_TYPE] == 2) { //plus会员 $user_type = 2; //plus会员 $PlusVipModel = D('RetailPlusVip'); $plus_vip_info = $PlusVipModel->getFind(array($PlusVipModel::ID => $user[$SmallProgramUserModel::PLUS_VIP_ID], $PlusVipModel::MERCHANT_ID => $merchant_id)); if ($plus_vip_info) { //正常 if ($plus_vip_info[$PlusVipModel::STATE] == 1) { //plus过期 if ($plus_vip_info[$PlusVipModel::END_TIME] < $time) { $PlusVipModel->updateOrder(array($PlusVipModel::ID => $user[$SmallProgramUserModel::PLUS_VIP_ID], $PlusVipModel::MERCHANT_ID => $merchant_id), array($PlusVipModel::STATE => 2)); $SmallProgramUserModel->updateOrder(array($SmallProgramUserModel::ID => $uid, $SmallProgramUserModel::MERCHANT_ID => $merchant_id), array($SmallProgramUserModel::USER_TYPE => 3)); $user[$SmallProgramUserModel::USER_TYPE] = 1; $VipModel = D('RetailVip'); $VipModel->updateOrder(array($VipModel::PLUS_ID => $plus_vip_info[$PlusVipModel::ID], $VipModel::MERCHANT_ID => $merchant_id), array($VipModel::PLUS_TYPE => 3, $VipModel::PLUS_STATE => 2)); $user_type = 3; //常规会员 } } else { $user_type = 3; //普通用户 } } else { $user_type = 3; //普通用户 } } } $user['user_type'] = $user_type; //用户类型 1普通用户 2plus会员 3常规会员 if (!empty($user['vid'])) { $_POST['vid'] = $user['vid']; } self::$uid = $uid; self::$user = $user; } self::$merchant_id = $merchant_id; self::$merchant = $merchant; $title = 'http'; if ($_SERVER['HTTPS'] == 'on') { $title .= 's'; } $this->REQUEST_URL = $title . '://' . $_SERVER['HTTP_HOST']; $GoodsDefaultImgModel = new GoodsDefaultImgModel(); $this->EMPTY_GOODS_IMG = $GoodsDefaultImgModel->getDefaultImg($store_id); self::$verifyToken = true; } } /** * 获取图片 * @param $img_id * @param string $img_url * @return string */ protected function getGoodsImage($img_id, $img_url = '') { $ImageGalleryModel = D('ImageGallery'); if (!empty($img_id)) { $img_url = $ImageGalleryModel->getFieldPath(array('id' => $img_id)); if (!$img_url) { $img_url = $this->EMPTY_GOODS_IMG; } } else { if (!empty($imgUrl) && $img_url != '/Uploads') { // 处理图片 $img_url = $this->REQUEST_URL . $img_url; } else { $img_url = $this->EMPTY_GOODS_IMG; } } return $img_url; } /** * 返回给前台 * @param $data */ protected function ajaxBack($data) { $data['user_type'] = self::$user['user_type']; $this->ajaxReturn($data); } protected function getVipInfo() { $VipModel = D('RetailVip'); $VipIntegralModel = D('RetailVipIntegral'); $SmallProgramUserModel = D('RetailSmallProgramUser'); $PlusVipModel = D('RetailPlusVip'); $user = self::$user; if ($user['user_type'] == 2 || $user['user_type'] == 3) { $map = array( $VipIntegralModel::MERCHANT_ID => self::$merchant_id, $VipIntegralModel::DISCOUNT => array('gt', 0) ); $vMap = array( $VipModel::ID => $user[$SmallProgramUserModel::VID], $VipModel::STATUS => 1 ); $vip = $VipModel->getFind($vMap); //PLUS共计优惠金额 $plus_data = $PlusVipModel->getOrderFind(array('vip_id' => $vip['id']), 'total_less_money,state,end_time'); if (!empty($vip)) { if ($user['user_type'] == 2) { //plus会员 $grade = $VipIntegralModel->getOrderFind($map, '*', $VipIntegralModel::DISCOUNT . ' asc'); $vipInfo['grade_name'] = 'PLUS会员'; } else { //常规会员 $map[$VipIntegralModel::MIN_INTEGRAL] = array('ELT', $vip[$VipModel::GRADE_INTEGRAL]); $grade = $VipIntegralModel->getOrderFind($map, '*', $VipIntegralModel::MIN_INTEGRAL . ' desc'); $vipInfo['grade_name'] = $grade[$VipIntegralModel::CARD_NAME]; } $next_grade = $VipIntegralModel->getVipNextGradeInfo(self::$merchant_id, $vip['grade_integral']); } else { $user['user_type'] = 1; $grade = array(); } } else { $grade = array(); } $vipInfo = false; if ($user['user_type'] != 1) { $vipInfo['user_type'] = $user['user_type']; $vipInfo['integral'] = $vip[$VipModel::INTEGRAL] ? $vip[$VipModel::INTEGRAL] : 0; $vipInfo['discount'] = ($grade[$VipIntegralModel::DISCOUNT] > 0 && $grade[$VipIntegralModel::DISCOUNT] < 1) ? $grade[$VipIntegralModel::DISCOUNT] : 1; $vipInfo['vid'] = $vip[$VipModel::ID] ? $vip[$VipModel::ID] : 0; $vipInfo['balance'] = $vip[$VipModel::BALANCE] ? $vip[$VipModel::BALANCE] : 0; $vipInfo['card_num'] = $vip[$VipModel::MOBILE_PHONE] ? $vip[$VipModel::MOBILE_PHONE] : $vip[$VipModel::CARD_KEY]; $vipInfo['nickname'] = $vip[$VipModel::NICK_NAME] ? $vip[$VipModel::NICK_NAME] : $user[$SmallProgramUserModel::NICKNAME]; $vipInfo['avatar'] = $vip[$VipModel::AVATAR] ? $vip[$VipModel::AVATAR] : $user[$SmallProgramUserModel::AVATAR]; $vipInfo['password'] = $vip[$VipModel::PASSWORD]; $vipInfo['add_time'] = $vip[$VipModel::ADD_TIME]; $vipInfo['plus_id'] = $vip[$VipModel::PLUS_ID]; $vipInfo['grade_integral'] = $vip[$VipModel::GRADE_INTEGRAL]; $vipInfo['next_grade_integral'] = empty($next_grade['min_integral']) ? $grade['min_integral'] : $next_grade['min_integral']; $vipInfo['total_less_money'] = empty($plus_data['total_less_money']) ? 0 : $plus_data['total_less_money']; $vipInfo['plus_end_time'] = date('Y-m-d', $plus_data['end_time']); $vipInfo['plus_state'] = $plus_data['state']; } return $vipInfo; } /** * 获取支付开启设置 * @return mixed */ protected function getStoreSet_v1() { //支付方式 $PaySetModel = D('RetailPaySet'); $map = array($PaySetModel::MERCHANT_ID => self::$merchant_id); $fields = array( $PaySetModel::XCX_PAY_STATE, $PaySetModel::BALANCE_STATE ); $pay_set = $PaySetModel->getFind($map, $fields); $pay['wxPay'] = 0; $pay['balancePay'] = 0; if ($pay_set[$PaySetModel::XCX_PAY_STATE] != 0) { $pay['wxPay'] = 1; //微信支付开启状态 } if ($pay_set[$PaySetModel::BALANCE_STATE] == 1) { $pay['balancePay'] = 1; //余额支付开启状态 } $pay['combinationPay'] = 1; //组合支付状态 $StoreModel = D('RetailStore'); $store = self::$store; $res['status'] = 1; if (empty($store[$StoreModel::BUSINESS]) || $store[$StoreModel::BUSINESS] == '-') { $store[$StoreModel::BUSINESS] = '00:00-23:59'; } else { $store[$StoreModel::BUSINESS] = $this->handleTime($store[$StoreModel::BUSINESS]); } if (empty($store[$StoreModel::BUSINESS_TIME]) || $store[$StoreModel::BUSINESS_TIME] == '-') { $store[$StoreModel::BUSINESS_TIME] = '00:00-23:59'; } else { $store[$StoreModel::BUSINESS_TIME] = $this->handleTime($store[$StoreModel::BUSINESS_TIME]); } $express_delivery = D('StoreConfig')->getFindField(array('store_id' => self::$store_id), 'delivery_template_status'); $set = array( 'pay' => $pay, 'starting_price' => $store[$StoreModel::STARTING_PRICE] > 0 ? $store[$StoreModel::STARTING_PRICE] : 0, //起送价 'self_pick' => $store[$StoreModel::SELF_PICK], //1不开启到店自提 0开启到店自提 'delivery' => $store[$StoreModel::WAY_OF_DELIVERY], //1不开启同城配送 0开启同城配送 'express_delivery' => $express_delivery == 2 ? 0 : 1, //1不开启快递发货 0开启快递发货 'business' => $store[$StoreModel::BUSINESS], //配送时间 'business_time' => $store[$StoreModel::BUSINESS_TIME], //营业时间 'service_radius' => $store[$StoreModel::SERVICE_RADIUS] > 0 ? $store[$StoreModel::SERVICE_RADIUS] : 0, //服务半径 'business_non_order' => $store[$StoreModel::BUSINESS_NON_ORDER], //非营业时间下单 1开启 2关闭 ); //默认配送时间 $time = time(); $business_date = date('m月d日 H:i', time()); $business = explode("-", $set['business']); $start_time = strtotime(date('Y-m-d', $time) . " " . $business[0] . ":00"); $end_time = strtotime(date('Y-m-d', $time) . " " . $business[1] . ":00"); if ($time >= $start_time && $time <= $end_time) { $res['business'] = $business_date; } //营业时间 $business_time = explode("-", $set['business_time']); $business_start_time = strtotime(date('Y-m-d', $time) . " " . $business_time[0] . ":00"); $business_end_time = strtotime(date('Y-m-d', $time) . " " . $business_time[1] . ":00"); if ($time >= $business_start_time && $time <= $business_end_time) { $res['business_time_choice'] = $business_date; } $res['business'] = $res['business'] ? $res['business'] : ""; $res['business_time_choice'] = $res['business_time_choice'] ? $res['business_time_choice'] : ""; $res['set'] = $set; return $res; } /** * 处理时间,把开始时间与结束时间相同的改为不同的 * @param $time * @return string */ protected function handleTime($time) { $arr = explode('-', $time); if ($arr[0] == $arr[1]) { if ($arr[0] == '00:00') { return '00:00-23:59'; } else { $temp = explode(':', $arr[1]); if ($temp[1] < 59) { $t = $temp[1] + 1; if ($t < 10) { $t = '0' . $t; } return $arr[0] . '-' . $temp[0] . ':' . $t; } else { if ($temp[0] < 23) { $t = $temp[0] + 1; if ($t < 10) { $t = '0' . $t; } return $arr[0] . '-' . $t . ':00'; } else { return '23:58-23:59'; } } } } else { return $time; } } /** * 获取默认收货地址 * @return mixed */ protected function getDefaultAddress_v1() { $AddressModel = D('RetailAddress'); $map = array( $AddressModel::UID => self::$uid, $AddressModel::STATE => 0, $AddressModel::STATUS => 1 ); $address_info = $AddressModel->getFind($map); if (!empty($address_info)) { $address = ''; if ($address_info[$AddressModel::PROVINCE]) { $address .= $address_info[$AddressModel::PROVINCE]; } if ($address_info[$AddressModel::CITY]) { $address .= $address_info[$AddressModel::CITY]; } if ($address_info[$AddressModel::AREA]) { $address .= $address_info[$AddressModel::AREA]; } $address .= $address_info[$AddressModel::ADDRESS]; if (!empty($address_info[$AddressModel::HOUSE_NUMBER])) { $address .= $address_info[$AddressModel::HOUSE_NUMBER]; } $address_info[$AddressModel::ADDRESS] = $address; } return $address_info; } /** * 获取同城配送费 * @param $address_id * @return mixed */ protected function getLngLatAndFee($address_id) { $AddressModel = D('RetailAddress'); $map = array( $AddressModel::UID => self::$uid, $AddressModel::STATE => 0, $AddressModel::ID => $address_id, ); $address = $AddressModel->getFind($map); if (empty($address)) { $result['status'] = 0; $result['msg'] = '您的请求有误1'; } $StoreModel = D('RetailStore'); $store = self::$store; $lat = $store[$StoreModel::LATITUDE]; $lng = $store[$StoreModel::LONGITUDE]; $radius = $store[$StoreModel::SERVICE_RADIUS]; //米 if ($radius == null || $radius == '' || $radius == 0) { $res['status'] = 0; $res['msg'] = '商家未设置配送范围'; $this->ajaxReturn($res); } $radius = $radius / 1000; $addressInfo = ''; if ($address[$AddressModel::PROVINCE]) { $addressInfo .= $address[$AddressModel::PROVINCE]; } if ($address[$AddressModel::CITY]) { $addressInfo .= $address[$AddressModel::CITY]; } if ($address[$AddressModel::AREA]) { $addressInfo .= $address[$AddressModel::AREA]; } $addressInfo .= $address[$AddressModel::ADDRESS]; if (!empty($address[$AddressModel::HOUSE_NUMBER])) { $addressInfo .= $address[$AddressModel::HOUSE_NUMBER]; } $res = getAddress($addressInfo); if ($res) { $distance = get_distance($res['lng'], $res['lat'], $lng, $lat); //除以1000变千米 // 首先检查电子围栏 $FenceModel = new \Common\Model\StoreDeliveryFenceModel(); $fences = $FenceModel->where(['store_id' => self::$store_id, 'is_active' => 1])->select(); if (!empty($fences)) { // 如果设置了电子围栏,优先使用电子围栏判断 $fenceHelper = new \SmallProgramApi\Helper\FenceHelper(); $fenceResult = $fenceHelper->checkPointInFences($res['lng'], $res['lat'], $fences); if (!$fenceResult['in_fence']) { $result['radius'] = 0; $result['status'] = 0; $result['msg'] = '不在配送范围内(电子围栏)'; $result['distance'] = $distance; $result['fence_check'] = true; $result['fence_name'] = ''; } else { // 在电子围栏内,计算配送费 $DistributionModel = D('RetailDistribution'); $map = array( $DistributionModel::START => array('elt', $distance), $DistributionModel::END => array('egt', $distance), $DistributionModel::STORE_ID => self::$store_id, $DistributionModel::STATUS => 1 //1开启 2关闭 ); $distribution_fee = $DistributionModel->getOrderFindField($map, $DistributionModel::FEE, $DistributionModel::START . ' asc'); if (!$distribution_fee) { $distribution_fee = 0; } $address[$AddressModel::ADDRESS] = $addressInfo; $result['status'] = 1; $result['msg'] = '在配送范围内(电子围栏)'; $result['fee'] = $distribution_fee; $result['distance'] = $distance; $result['address'] = $address; $result['fence_check'] = true; $result['fence_name'] = $fenceResult['fence_name']; } } else { // 没有设置电子围栏,使用传统的圆形范围判断 if ($distance > $radius) { $result['radius'] = 0; $result['status'] = 0; $result['msg'] = '不在配送范围内'; $result['distance'] = $distance; $result['fence_check'] = false; } else { $DistributionModel = D('RetailDistribution'); $map = array( $DistributionModel::START => array('elt', $distance), $DistributionModel::END => array('egt', $distance), $DistributionModel::STORE_ID => self::$store_id, $DistributionModel::STATUS => 1 //1开启 2关闭 ); $distribution_fee = $DistributionModel->getOrderFindField($map, $DistributionModel::FEE, $DistributionModel::START . ' asc'); if (!$distribution_fee) { $distribution_fee = 0; } $address[$AddressModel::ADDRESS] = $addressInfo; $result['status'] = 1; $result['msg'] = '在配送范围内'; $result['fee'] = $distribution_fee; $result['distance'] = $distance; $result['address'] = $address; $result['fence_check'] = false; } } } else { $result['status'] = 0; $result['msg'] = '收货地址找不到'; } return $result; } /** * 获取商品规格 * @param $goods_id * @param $store_id * @param $platform_type //商户平台类型 1默认系统 2微礼平台 * @return mixed */ protected function getGoodsSku($goods_id, $store_id = null, $platform_type = 1) { $store_id = $store_id ? $store_id : self::$store_id; $SkuModel = new RetailSkuGoodsModel(); $StoreXcxConfigModel = new RetailStoreXcxConfigModel(); $sMap = array( $StoreXcxConfigModel::STORE_ID => $store_id, ); $promotion_status = $StoreXcxConfigModel->getFindField($sMap, $StoreXcxConfigModel::PROMOTION_STATUS); if (!empty($promotion_status) && $promotion_status == 1) { //开启促销 $map = array( 's.' . $SkuModel::GOODS_ID => $goods_id, 's.' . $SkuModel::STATE => 0, 's.status' => 1, ); $fields = array( 's.' . $SkuModel::ID, 's.' . $SkuModel::SKU_ID_LIST, 's.' . $SkuModel::RETAIL_PRICE, 's.' . $SkuModel::ONLINE_PRICE, 's.' . $SkuModel::GOODS_IMG_ID, 's.' . $SkuModel::SKU_NUM, 's.' . $SkuModel::SHOP_MEM_PRICE, 's.' . $SkuModel::PLUS_PRICE, 'h.status as promotion_status', 'h.act_price', ); if ($platform_type == 2) { $fields[] = 's.third_goods_code'; } $goodsSku = $SkuModel->getHostSkuList($map, $fields); } else { $map = array( $SkuModel::GOODS_ID => $goods_id, $SkuModel::STATE => 0, 'status' => 1, ); $fields = array( $SkuModel::ID, $SkuModel::SKU_ID_LIST, $SkuModel::RETAIL_PRICE, $SkuModel::ONLINE_PRICE, $SkuModel::GOODS_IMG_ID, $SkuModel::SKU_NUM, $SkuModel::SHOP_MEM_PRICE, $SkuModel::PLUS_PRICE, "shop_mem_integral", "plus_mem_integral" ); if ($platform_type == 2) { $fields[] = 'third_goods_code'; } $goodsSku = $SkuModel->getSelect($map, $fields); } if (empty($goodsSku)) { $result['status'] = 2; $result['msg'] = '该商品未启用规格,请重试'; return $result; } $attrArr = array(); $SkuListModel = D('RetailSkuList'); $goods_num = 0; if ($platform_type == 2) { $code_arr = []; } foreach ($goodsSku as &$value) { $value['promotion_status'] = $value['promotion_status'] ? $value['promotion_status'] : 0; if (!$value[$SkuModel::ONLINE_PRICE] || floatval($value[$SkuModel::ONLINE_PRICE]) < 0.01) { $value[$SkuModel::ONLINE_PRICE] = $value[$SkuModel::RETAIL_PRICE]; } $attrArr = array_merge($attrArr, explode(',', $value['sku_id_list'])); $value['goods_img'] = $this->getGoodsImage($value[$SkuModel::GOODS_IMG_ID]); $map = array( $SkuListModel::ID => array('in', $value[$SkuModel::SKU_ID_LIST]) ); $name = $SkuListModel->getFindField($map, $SkuListModel::NAME, true); $value['name'] = implode(',', $name); if ($platform_type == 2) { $value['goods_num'] = 0; $code_arr[$value['id']] = $value['third_goods_code']; } else { $value['goods_num'] = A('Api/Inventory')->goods_num(1, $store_id, $goods_id, $value[$SkuModel::ID]); $redis_key = 'retail_goods_' . $goods_id . '_' . $value[$SkuModel::ID] . '_*'; $wait_pay_num = $this->getWaitNum($redis_key); $value['goods_num'] = round($value['goods_num'] - $wait_pay_num, 3); $goods_num += $value['goods_num']; } } if ($platform_type == 2 && !empty($code_arr)) { //第三方平台; $ThirdGoodsClass = new Goods(); $thirdResult = $ThirdGoodsClass->goodsNumQuery([ 'merchant_id' => self::$merchant_id, 'type' => 2, 'code_arr' => $code_arr, 'Customer_Codes' => self::$store['third_code'] ]); if ($thirdResult['status'] == 1 && !empty($thirdResult['data'])) { $goods_stock = $thirdResult['data']; foreach ($goodsSku as &$val) { if (!empty($goods_stock[$val['id']])) { $val['goods_num'] = $goods_stock[$val['id']]; $goods_num += $val['goods_num']; } } } } $sku_id_list = explode(',', $goodsSku[0][$SkuModel::SKU_ID_LIST]); $attr = array(); $SkuAttrModel = D('RetailSkuAttr'); foreach ($sku_id_list as $v) { $attr_id = $SkuListModel->getFindField(array($SkuListModel::ID => $v), $SkuListModel::ATTR_ID); $temp = $SkuAttrModel->getFind(array($SkuAttrModel::ID => $attr_id), $SkuAttrModel::ID . ',' . $SkuAttrModel::NAME); $map = array( $SkuListModel::ID => array('in', $attrArr), $SkuListModel::ATTR_ID => $attr_id ); $temp['list'] = $SkuListModel->getSelect($map, $SkuListModel::ID . ',' . $SkuListModel::NAME); $attr[] = $temp; } $data['skuDetailList'] = $goodsSku; //商品规格 $data['skuList'] = $attr; //规格分类列表 $data['goods_num'] = round($goods_num, 3); //规格分类列表 return $data; } /** * 获取redis数据库待支付商品数量 * @param $str string key 模糊搜索 * @return $num int 数量 */ protected function getWaitNum($str) { // 获取redis数据库记录 $num = 0; if (C('IS_SET_REDIS')) { $ApiRedis = new \Addons\Api\RedisController(); $wait_pay = $ApiRedis::$redis->mget($ApiRedis::$redis->keys($str)); // 判断是否有正在支付订单 if (!empty($wait_pay)) { // 处理数据 foreach ($wait_pay as &$val) { $num += json_decode($val, true)['num']; } } } return $num; } /** * 获取redis数据库待支付订单数量 * @param $str string key 模糊搜索 * @return $num int 数量 */ protected function getWaitPayOrderNum($str) { // 获取redis数据库记录 $ApiRedis = new \Addons\Api\RedisController(); $wait_pay_list = $ApiRedis::$redis->mget($ApiRedis::$redis->keys($str)); // 判断是否有正在支付订单 $billId = array(); if (!empty($wait_pay_list)) { foreach ($wait_pay_list as $value) { $data = json_decode($value, true); if (!in_array($data['bill_id'], $billId)) { $billId[] = $data['bill_id']; } } } if (!empty($billId)) { $map = array( 'id' => array('in', $billId), 'pay_state' => 0, 'store_id' => self::$store_id, ); $num = D('RetailBillOrder')->getCount($map); } else { $num = 0; } return $num; } /** * 获取redis数据库待支付订单数量 * @param $str string key 模糊搜索 * @return $num int 数量 */ protected function getWaitPayOrderNum_v1($str) { // 获取redis数据库记录 $ApiRedis = new \Addons\Api\RedisController(); $wait_pay_list = $ApiRedis::$redis->mget($ApiRedis::$redis->keys($str)); // 判断是否有正在支付订单 $billId = array(); if (!empty($wait_pay_list)) { foreach ($wait_pay_list as $value) { $data = json_decode($value, true); if (!in_array($data['bill_id'], $billId)) { $billId[] = $data['bill_id']; } } } if (!empty($billId)) { $map = array( 'id' => array('in', $billId), 'pay_state' => 0, ); $num = D('RetailBillOrder')->getCount($map); } else { $num = 0; } return $num; } /** * 判断当前时间是否可以下单 * @return bool */ protected function verifyPlaceOrder() { if (self::$store['business_non_order'] == 2) { if (empty(self::$store['business_time']) || self::$store['business_time'] == '-') { return true; } else { return $this->isCurrentTimeInBusinessHours(self::$store['business_time']); } } else { return true; } } /** * 判断当前时间是否在营业时间内(支持多时段和跨天时间段) * @param string $business_time 营业时间字符串,格式如:"08:00-12:00,14:00-23:00" 或 "22:00-02:00" * @return bool */ protected function isCurrentTimeInBusinessHours($business_time) { if (empty($business_time) || $business_time == '-') { return true; } $current_time = date('H:i'); $current_minutes = $this->timeToMinutes($current_time); // 分割多个时间段 $time_periods = explode(',', $business_time); foreach ($time_periods as $period) { $period = trim($period); if (empty($period)) { continue; } $time_range = explode('-', $period); if (count($time_range) != 2) { continue; } $start_time = trim($time_range[0]); $end_time = trim($time_range[1]); // 验证时间格式 if (!$this->isValidTimeFormat($start_time) || !$this->isValidTimeFormat($end_time)) { continue; } $start_minutes = $this->timeToMinutes($start_time); $end_minutes = $this->timeToMinutes($end_time); // 判断是否为跨天时间段 if ($start_minutes > $end_minutes) { // 跨天时间段:如 22:00-02:00 if ($current_minutes >= $start_minutes || $current_minutes <= $end_minutes) { return true; } } else { // 同一天时间段:如 08:00-18:00 if ($current_minutes >= $start_minutes && $current_minutes <= $end_minutes) { return true; } } } return false; } /** * 验证时间格式是否正确 * @param string $time 时间字符串,格式为 HH:MM * @return bool */ private function isValidTimeFormat($time) { return preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $time); } /** * 将时间字符串转换为分钟数 * @param string $time 时间字符串,格式为 HH:MM * @return int 分钟数 */ private function timeToMinutes($time) { list($hours, $minutes) = explode(':', $time); return intval($hours) * 60 + intval($minutes); } /** * 获取支付设置、门店设置 * @return mixed */ protected function getStoreSet_v2() { //商户支付设置 $PaySetModel = D('RetailPaySet'); $map = array( 'merchantid' => self::$merchant_id ); $fields = array( 'xcx_pay_state', 'balance' ); $pay_set = $PaySetModel->getFind($map, $fields); $payList = [0, 1, 1]; //0关闭 1开启 index含义 0微信支付 1余额支付 2组合支付 if ($pay_set['xcx_pay_state'] != 0) { $payList[0] = 1; //微信支付开启状态 } if ($pay_set['balance'] != 1) { $payList[1] = 0; //余额支付关闭状态 } if ($payList[0] != 1 || $payList[1] != 1) { $payList[2] = 0; //组合支付 } $StoreModel = D('RetailStore'); $store = self::$store; if ($store['business_time'] && $store['business_time'] != '-') { $store['new_business_time'] = explode(",", $store['business_time']); foreach ($store['new_business_time'] as &$val) { $val = explode("-", $val); } } else { $store['new_business_time'] = array(array('00:00', '23:59')); } $store['business_time'] = $store['new_business_time'][0][0] . '-' . $store['new_business_time'][0][1]; if ($store['business']) { $store['new_business'] = explode(",", $store['business']); foreach ($store['new_business'] as &$value) { $value = explode("-", $value); } } else { $store['new_business'] = array(array('00:00', '23:59')); } $store['business'] = $store['new_business'][0][0] . '-' . $store['new_business'][0][1]; //订单配送、自提的延时时间及是否自动生成时间 $StoreXcxConfigModel = new RetailStoreXcxConfigModel(); $conf = $StoreXcxConfigModel->getFind(['storeid' => self::$store_id], 'send_delayed_time,pickup_delayed_time,auto_set_time'); $plugClass = new Plug(); //订单获取祝福码,判断该门店是否,有,并且开启 $storePlugStatusPost = [ 'store_id' => self::$store_id, 'identification_arr' => ['blessing'], ]; $storePlugStatus = $plugClass->plugStoreStatus($storePlugStatusPost);//获取状态 $res = array( 'payList' => $payList, //支付设置 'starting_price' => $store[$StoreModel::STARTING_PRICE] > 0 ? $store[$StoreModel::STARTING_PRICE] : 0, //起送价 'delivery_set' => $this->getDeliverySet(), //门店配送设置 'business' => $store[$StoreModel::BUSINESS], //配送时间 'business_time' => $store[$StoreModel::BUSINESS_TIME], //营业时间 'service_radius' => $store[$StoreModel::SERVICE_RADIUS] > 0 ? $store[$StoreModel::SERVICE_RADIUS] : 0, //服务半径 'business_non_order' => $store[$StoreModel::BUSINESS_NON_ORDER], //非营业时间下单 1开启 2关闭 'new_business' => $store['new_business'], 'new_business_time' => $store['new_business_time'], 'blessing_status' => $storePlugStatus, 'send_delayed_time' => $conf['send_delayed_time'] ? $conf['send_delayed_time'] : 0, 'pickup_delayed_time' => $conf['pickup_delayed_time'] ? $conf['pickup_delayed_time'] : 0, 'auto_set_time' => $conf['auto_set_time'] == 1 ? 1 : 0, ); return $res; } /** * 获取门店配送设置 * @return array */ protected function getDeliverySet() { $StoreModel = D('RetailStore'); $store = self::$store; $delivery_set = array(0, 0, 0); //配送设置 0关闭 1开启 index含义 0自提 1同城配送 2快递发货 if ($store[$StoreModel::SELF_PICK] == 0) { $delivery_set[0] = 1; } if ($store[$StoreModel::WAY_OF_DELIVERY] == 0) { $delivery_set[1] = 1; } $express_delivery = D('StoreConfig')->getFindField(array('store_id' => self::$store_id), 'delivery_template_status'); if ($express_delivery == 2) { $delivery_set[2] = 1; } return $delivery_set; } /** * 处理商品与门店设置的配送方式 * @param string $set 商品配送方式设置 * @return array */ protected function handleDelivery($set = '1,2,3') { $temp_set = explode(',', $set); $data = array(); $delivery_set = $this->getDeliverySet(); //获取门店配送设置 foreach ($delivery_set as $key => $v) { $type = $key == 0 ? '自提' : ($key == 1 ? '配送' : '快递'); if (!in_array($key + 1, $temp_set)) { $data[] = array( 'data' => 0, 'name' => $type, ); } else { $data[] = array( 'data' => $v ? 1 : 0, 'name' => $type, ); } } return $data; } /** * 获取模板及设置的配送区域及信息 * @param $template_id * @return array|bool */ protected function handleDeliveryRule($template_id) { if (empty($template_id)) { return false; } $Template = new DeliveryTemplateModel(); $list = $Template->getTemplateDetailedData($template_id); //获取模板区域列表的费用及类型 $type = $list[0]['type']; //type 1免运费 2按件数 3按重量 4统一运费', $CityModel = D('Citys'); if (!empty($list)) { foreach ($list as &$value) { $areaCom = str_replace('#', '', $value['area_id']); $cityData = $CityModel->distributionAreaCityInfo($areaCom); $areaDetails = self::getAreaDetails($cityData); //组装城市信息 $value['area_name'] = $areaDetails; unset($value['area_id']); unset($value['type']); } switch ($type) { case '1': //1免运费 break; case '2': case '3': //2按件数 3按重量 $list = ascSortByFields($list, 'first_fee'); break; case '4': //4统一运费 $list = ascSortByFields($list, 'unified_fee'); break; } $type_name = array( '1' => '免运费', '2' => '按件数', '3' => '按重量', '4' => '统一运费', ); return array( 'type' => $type, 'type_name' => $type_name[$type], 'list' => $list, ); } else { return false; } } /** * 组装城市信息 * @param $cityData * @return string */ private function getAreaDetails($cityData) { $areaDetails = ''; foreach ($cityData as &$item) { if ($item['parentid'] == 0) { $areaDetails .= $item['city_name'] . " "; } else { $areaDetails .= $item['city_name'] . "、"; } } $areaDetails = rtrim($areaDetails, '、'); $areaDetails = rtrim($areaDetails, ' '); return $areaDetails; } }