diff --git a/application/ebapi/common.php b/application/ebapi/common.php new file mode 100644 index 00000000..7be5f1cc --- /dev/null +++ b/application/ebapi/common.php @@ -0,0 +1,41 @@ + +// +---------------------------------------------------------------------- + +/** + * 设置浏览信息 + * @param $uid + * @param int $product_id + * @param int $cate + * @param string $type + * @param string $content + * @param int $min + */ +function setView($uid,$product_id=0,$cate=0,$type='',$content='',$min=20){ + $Db=think\Db::name('store_visit'); + $view=$Db->where(['uid'=>$uid,'product_id'=>$product_id])->field('count,add_time,id')->find(); + if($view && $type!='search'){ + $time=time(); + if(($view['add_time']+$min)<$time){ + $Db->where(['id'=>$view['id']])->update(['count'=>$view['count']+1,'add_time'=>time()]); + } + }else{ + $cate = explode(',',$cate)[0]; + $Db->insert([ + 'add_time'=>time(), + 'count'=>1, + 'product_id'=>$product_id, + 'cate_id'=>$cate, + 'type'=>$type, + 'uid'=>$uid, + 'content'=>$content + ]); + } +} \ No newline at end of file diff --git a/application/ebapi/config.php b/application/ebapi/config.php new file mode 100644 index 00000000..25481679 --- /dev/null +++ b/application/ebapi/config.php @@ -0,0 +1,38 @@ + +// +---------------------------------------------------------------------- + + +return [ + 'session' => [ + // SESSION 前缀 + 'prefix' => 'ebapi', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + ], + 'exception_handle' => \app\ebapi\controller\ApiException::class, + + // +---------------------------------------------------------------------- + // | 缓存设置 + // +---------------------------------------------------------------------- + + 'cache' => [ + // 驱动方式 + 'type' => 'File', + // 缓存保存目录 + 'path' => CACHE_PATH, + // 缓存前缀 + 'prefix' => 'ebapi', + // 缓存有效期 0表示永久缓存 + 'expire' => 1400, + ], +]; diff --git a/application/ebapi/controller/ApiException.php b/application/ebapi/controller/ApiException.php new file mode 100644 index 00000000..b237a8ca --- /dev/null +++ b/application/ebapi/controller/ApiException.php @@ -0,0 +1,38 @@ +getError(),[], $e->getCode()); + //数据库错误 + if($e instanceof PDOException) return JsonService::fail($e->getMessage(),[],$e->getCode()); + //Db错误 + if($e instanceof DbException) return JsonService::fail($e->getMessage(),[],$e->getCode()); + //HTTP相应错误 + if($e instanceof HttpException) return JsonService::fail($e->getMessage(),[],$e->getCode()); + //其他错误异常 + if($e instanceof ErrorException) return JsonService::fail($e->getMessage(),[],$e->getCode()); + //默认错误提示 + $baseExcep=new BaseException(); + return JsonService::fail($baseExcep->msg,[],$baseExcep->code); + } +} \ No newline at end of file diff --git a/application/ebapi/controller/ArticleApi.php b/application/ebapi/controller/ArticleApi.php new file mode 100644 index 00000000..3b3d5d54 --- /dev/null +++ b/application/ebapi/controller/ArticleApi.php @@ -0,0 +1,73 @@ +toArray(); + else $cateInfo = []; + array_unshift($cateInfo,['id'=>0,'title'=>'热门']); + return $this->successful($cateInfo); + } + /** + * TODO 文章列表 + * @param int $cid + * @param int $first + * @param int $limit + */ + public function get_cid_article($cid = 0,$first = 0,$limit = 8){ + $list = ArticleModel::cidByArticleList($cid,$first,$limit,"id,title,image_input,visit,from_unixtime(add_time,'%Y-%m-%d %H:%i') as add_time,synopsis,url")?:[]; + return $this->successful($list); + } + + /** + * TODO 获取热门文章 + * @return json + */ + public function get_article_hot() + { + return $this->successful(ArticleModel::getArticleListHot("id,title,image_input,visit,from_unixtime(add_time,'%Y-%m-%d %H:%i') as add_time,synopsis,url")); + } + + /** + * TODO 获取热门banner文章 + * @return json + */ + public function get_article_banner() + { + return $this->successful(ArticleModel::getArticleListBanner("id,title,image_input,visit,from_unixtime(add_time,'%Y-%m-%d %H:%i') as add_time,synopsis,url")); + } + + /** + * TODO 获取文章详情 + * @param int $id + * @return json + */ + public function visit($id = 0) + { + $content = ArticleModel::getArticleOne($id); + if(!$content || !$content["status"]) return $this->fail('此文章已经不存在!'); + $content["visit"] = $content["visit"] + 1; + $content["cart_name"] = ArticleCategory::getArticleCategoryField($content['cid']); + $content['add_time'] = date('Y-m-d H:i:s',$content['add_time']); + ArticleModel::edit(['visit'=>$content["visit"]],$id);//增加浏览次数 + return $this->successful($content); + } +} \ No newline at end of file diff --git a/application/ebapi/controller/AuthApi.php b/application/ebapi/controller/AuthApi.php new file mode 100644 index 00000000..b4ba3e66 --- /dev/null +++ b/application/ebapi/controller/AuthApi.php @@ -0,0 +1,397 @@ +userInfo['uid'])); + } + + + /* + * 获取订单支付状态 + * @param string ordre_id 订单id + * @return json + * */ + public function get_order_pay_info($order_id = '') + { + if ($order_id == '') return JsonService::fail('缺少参数'); + return JsonService::successful(StoreOrder::tidyOrder(StoreOrder::where('order_id', $order_id)->find())); + } + /** + * 订单页面 + * @param Request $request + * @return \think\response\Json + */ + public function confirm_order(Request $request) + { + $data = UtilService::postMore(['cartId'], $request); + $cartId = $data['cartId']; + if (!is_string($cartId) || !$cartId) return JsonService::fail('请提交购买的商品'); + $cartGroup = StoreCart::getUserProductCartList($this->userInfo['uid'], $cartId, 1); + if (count($cartGroup['invalid'])) return JsonService::fail($cartGroup['invalid'][0]['productInfo']['store_name'] . '已失效!'); + if (!$cartGroup['valid']) return JsonService::fail('请提交购买的商品'); + $cartInfo = $cartGroup['valid']; + $priceGroup = StoreOrder::getOrderPriceGroup($cartInfo); + $other = [ + 'offlinePostage' => SystemConfigService::get('offline_postage'), + 'integralRatio' => SystemConfigService::get('integral_ratio') + ]; + $usableCoupon = StoreCouponUser::beUsableCoupon($this->userInfo['uid'], $priceGroup['totalPrice']); + $cartIdA = explode(',', $cartId); + if (count($cartIdA) > 1) $seckill_id = 0; + else { + $seckillinfo = StoreCart::where('id', $cartId)->find(); + if ((int)$seckillinfo['seckill_id'] > 0) $seckill_id = $seckillinfo['seckill_id']; + else $seckill_id = 0; + } + $data['usableCoupon'] = $usableCoupon; + $data['seckill_id'] = $seckill_id; + $data['cartInfo'] = $cartInfo; + $data['priceGroup'] = $priceGroup; + $data['orderKey'] = StoreOrder::cacheOrderInfo($this->userInfo['uid'], $cartInfo, $priceGroup, $other); + $data['offlinePostage'] = $other['offlinePostage']; + $vipId=UserLevel::getUserLevel($this->uid); + $this->userInfo['vip']=$vipId !==false ? true : false; + if($this->userInfo['vip']){ + $this->userInfo['vip_id']=$vipId; + $this->userInfo['discount']=UserLevel::getUserLevelInfo($vipId,'discount'); + } + $data['userInfo']=$this->userInfo; + $data['integralRatio'] = $other['integralRatio']; + return JsonService::successful($data); + } + + /* + * 获取小程序订单列表统计数据 + * + * */ + public function get_order_data() + { + return JsonService::successful(StoreOrder::getOrderData($this->uid)); + } + /** + * 过度查$uniqueId + * @param string $productId + * @param int $cartNum + * @param string $uniqueId + * @return \think\response\Json + */ + public function unique() + { + $productId = $_GET['productId']; + if (!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $uniqueId = StoreProductAttrValue::where('product_id', $productId)->value('unique'); + $data = $this->set_cart($productId, $cartNum = 1, $uniqueId); + if ($data == true) { + return JsonService::successful('ok'); + } + } + /** + * 加入到购物车 + * @param string $productId + * @param int $cartNum + * @param string $uniqueId + * @return \think\response\Json + */ + public function set_cart($productId = '', $cartNum = 1, $uniqueId = '') + { + if (!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreCart::setCart($this->userInfo['uid'], $productId, $cartNum, $uniqueId, 'product'); + if (!$res) return JsonService::fail(StoreCart::getErrorInfo()); + else return JsonService::successful('ok', ['cartId' => $res->id]); + } + + /** + * 拼团 秒杀 砍价 加入到购物车 + * @param string $productId + * @param int $cartNum + * @param string $uniqueId + * @param int $combinationId + * @param int $secKillId + * @return \think\response\Json + */ + public function now_buy($productId = '', $cartNum = 1, $uniqueId = '', $combinationId = 0, $secKillId = 0, $bargainId = 0) + { + if (!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + if ($bargainId && StoreBargainUserHelp::getSurplusPrice($bargainId, $this->userInfo['uid'])) return JsonService::fail('请先砍价'); + $res = StoreCart::setCart($this->userInfo['uid'], $productId, $cartNum, $uniqueId, 'product', 1, $combinationId, $secKillId, $bargainId); + if (!$res) return JsonService::fail(StoreCart::getErrorInfo()); + else return JsonService::successful('ok', ['cartId' => $res->id]); + } + /** + * 获取购物车数量 + * @return \think\response\Json + */ + public function get_cart_num() + { + return JsonService::successful('ok', StoreCart::getUserCartNum($this->userInfo['uid'], 'product')); + } + + /** + * 修改购物车产品数量 + * @param string $cartId + * @param string $cartNum + * @return \think\response\Json + */ + public function change_cart_num($cartId = '', $cartNum = '') + { + if (!$cartId || !$cartNum || !is_numeric($cartId) || !is_numeric($cartNum)) return JsonService::fail('参数错误!'); + $res = StoreCart::changeUserCartNum($cartId, $cartNum, $this->userInfo['uid']); + if ($res) return JsonService::successful(); + else return JsonService::fail(StoreCart::getErrorInfo('修改失败')); + } + + /** + * 删除购物车产品 + * @param string $ids + * @return \think\response\Json + */ + public function remove_cart($ids = '') + { + if (!$ids) return JsonService::fail('参数错误!'); + if(StoreCart::removeUserCart($this->userInfo['uid'], $ids)) + return JsonService::successful(); + else + return JsonService::fail('清除失败!'); + } + /** + * 创建订单 + * @param string $key + * @return \think\response\Json + */ + public function create_order($key = '') + { + if (!$key) return JsonService::fail('参数错误!'); + if (StoreOrder::be(['order_id|unique' => $key, 'uid' => $this->userInfo['uid'], 'is_del' => 0])) + return JsonService::status('extend_order', '订单已生成', ['orderId' => $key, 'key' => $key]); + list($addressId, $couponId, $payType, $useIntegral, $mark, $combinationId, $pinkId, $seckill_id, $formId, $bargainId) = UtilService::postMore([ + 'addressId', 'couponId', 'payType', 'useIntegral', 'mark', ['combinationId', 0], ['pinkId', 0], ['seckill_id', 0], ['formId', ''], ['bargainId', ''] + ], Request::instance(), true); + $payType = strtolower($payType); + if ($bargainId) StoreBargainUser::setBargainUserStatus($bargainId, $this->userInfo['uid']); //修改砍价状态 + if ($pinkId) if (StorePink::getIsPinkUid($pinkId, $this->userInfo['uid'])) return JsonService::status('ORDER_EXIST', '订单生成失败,你已经在该团内不能再参加了', ['orderId' => StoreOrder::getStoreIdPink($pinkId, $this->userInfo['uid'])]); + if ($pinkId) if (StoreOrder::getIsOrderPink($pinkId, $this->userInfo['uid'])) return JsonService::status('ORDER_EXIST', '订单生成失败,你已经参加该团了,请先支付订单', ['orderId' => StoreOrder::getStoreIdPink($pinkId, $this->userInfo['uid'])]); + $order = StoreOrder::cacheKeyCreateOrder($this->userInfo['uid'], $key, $addressId, $payType, $useIntegral, $couponId, $mark, $combinationId, $pinkId, $seckill_id, $bargainId); + $orderId = $order['order_id']; + $info = compact('orderId', 'key'); + if ($orderId) { + switch ($payType) { + case "weixin": + $orderInfo = StoreOrder::where('order_id', $orderId)->find(); + if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!'); + if ($orderInfo['paid']) exception('支付已支付!'); + //如果支付金额为0 + if (bcsub((float)$orderInfo['pay_price'], 0, 2) <= 0) { + //创建订单jspay支付 + if (StoreOrder::jsPayPrice($orderId, $this->userInfo['uid'], $formId)) + return JsonService::status('success', '微信支付成功', $info); + else + return JsonService::status('pay_error', StoreOrder::getErrorInfo()); + } else { + RoutineFormId::SetFormId($formId, $this->uid); + try { + $jsConfig = StoreOrder::jsPay($orderId); //创建订单jspay + if(isset($jsConfig['package']) && $jsConfig['package']){ + $package=str_replace('prepay_id=','',$jsConfig['package']); + for($i=0;$i<3;$i++){ + RoutineFormId::SetFormId($package, $this->uid); + } + } + } catch (\Exception $e) { + return JsonService::status('pay_error', $e->getMessage(), $info); + } + $info['jsConfig'] = $jsConfig; + return JsonService::status('wechat_pay', '订单创建成功', $info); + } + break; + case 'yue': + if (StoreOrder::yuePay($orderId, $this->userInfo['uid'], $formId)) + return JsonService::status('success', '余额支付成功', $info); + else { + $errorinfo = StoreOrder::getErrorInfo(); + if (is_array($errorinfo)) + return JsonService::status($errorinfo['status'], $errorinfo['msg'], $info); + else + return JsonService::status('pay_error', $errorinfo); + } + break; + case 'offline': + RoutineFormId::SetFormId($formId, $this->uid); + // RoutineTemplate::sendOrderSuccess($formId,$orderId);//发送模板消息 + return JsonService::status('success', '订单创建成功', $info); + break; + } + } else return JsonService::fail(StoreOrder::getErrorInfo('订单生成失败!')); + } + + /* + * 再来一单 + * + * */ + public function again_order($uni = ''){ + if(!$uni) return JsonService::fail('参数错误!'); + $order = StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni); + if(!$order) return JsonService::fail('订单不存在!'); + $order = StoreOrder::tidyOrder($order,true); + $res = array(); + foreach ($order['cartInfo'] as $v) { + if($v['combination_id']) return JsonService::fail('拼团产品不能再来一单,请在拼团产品内自行下单!'); + else if($v['bargain_id']) return JsonService::fail('砍价产品不能再来一单,请在砍价产品内自行下单!'); + else if($v['seckill_id']) return JsonService::fail('秒杀产品不能再来一单,请在砍价产品内自行下单!'); + else $res[] = StoreCart::setCart($this->userInfo['uid'], $v['product_id'], $v['cart_num'], isset($v['productInfo']['attrInfo']['unique']) ? $v['productInfo']['attrInfo']['unique'] : '', 'product', 0, 0); + } + $cateId = []; + foreach ($res as $v){ + if(!$v) return JsonService::fail('再来一单失败,请重新下单!'); + $cateId[] = $v['id']; + } + return JsonService::successful('ok',implode(',',$cateId)); + } + + //TODO 支付订单 + /** + * 支付订单 + * @param string $uni + * @return \think\response\Json + */ + public function pay_order($uni = '', $paytype = 'weixin') + { + if (!$uni) return JsonService::fail('参数错误!'); + $order = StoreOrder::getUserOrderDetail($this->userInfo['uid'], $uni); + if (!$order) return JsonService::fail('订单不存在!'); + if ($order['paid']) return JsonService::fail('该订单已支付!'); + if ($order['pink_id']) if (StorePink::isPinkStatus($order['pink_id'])) return JsonService::fail('该订单已失效!'); + $order['pay_type'] = $paytype; //重新支付选择支付方式 + switch ($order['pay_type']) { + case 'weixin': + try { + $jsConfig = StoreOrder::jsPay($order); //订单列表发起支付 + if(isset($jsConfig['package']) && $jsConfig['package']){ + $package=str_replace('prepay_id=','',$jsConfig['package']); + for($i=0;$i<3;$i++){ + RoutineFormId::SetFormId($package, $this->uid); + } + } + } catch (\Exception $e) { + return JsonService::fail($e->getMessage()); + } + return JsonService::status('wechat_pay', ['jsConfig' => $jsConfig, 'order_id' => $order['order_id']]); + break; + case 'yue': + if ($res = StoreOrder::yuePay($order['order_id'], $this->userInfo['uid'])) + return JsonService::successful('余额支付成功'); + else { + $error = StoreOrder::getErrorInfo(); + return JsonService::fail(is_array($error) && isset($error['msg']) ? $error['msg'] : $error); + } + break; + case 'offline': + StoreOrder::createOrderTemplate($order); + return JsonService::successful('订单创建成功'); + break; + } + } + + /* + * 未支付的订单取消订单回退积分,回退优惠券,回退库存 + * @param string $order_id 订单id + * */ + public function cancel_order($order_id = '') + { + if (StoreOrder::cancelOrder($order_id)) + return JsonService::successful('取消订单成功'); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + + /** + * 申请退款 + * @param string $uni + * @param string $text + * @return \think\response\Json + */ + public function apply_order_refund(Request $request) + { + $data = UtilService::postMore([ + ['text', ''], + ['refund_reason_wap_img', ''], + ['refund_reason_wap_explain', ''], + ['uni', ''] + ], $request); + $uni = $data['uni']; + unset($data['uni']); + if ($data['refund_reason_wap_img']) $data['refund_reason_wap_img'] = explode(',', $data['refund_reason_wap_img']); + if (!$uni || $data['text'] == '') return JsonService::fail('参数错误!'); + $res = StoreOrder::orderApplyRefund($uni, $this->userInfo['uid'], $data['text'], $data['refund_reason_wap_explain'], $data['refund_reason_wap_img']); + if ($res) + return JsonService::successful(); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + + + /** + * 再来一单 + * @param string $uni + */ + public function order_details($uni = '') + { + + if (!$uni) return JsonService::fail('参数错误!'); + $order = StoreOrder::getUserOrderDetail($this->userInfo['uid'], $uni); + if (!$order) return JsonService::fail('订单不存在!'); + $order = StoreOrder::tidyOrder($order, true); + $res = array(); + foreach ($order['cartInfo'] as $v) { + if ($v['combination_id']) return JsonService::fail('拼团产品不能再来一单,请在拼团产品内自行下单!'); + else $res[] = StoreCart::setCart($this->userInfo['uid'], $v['product_id'], $v['cart_num'], isset($v['productInfo']['attrInfo']['unique']) ? $v['productInfo']['attrInfo']['unique'] : '', 'product', 0, 0); + } + $cateId = []; + foreach ($res as $v) { + if (!$v) return JsonService::fail('再来一单失败,请重新下单!'); + $cateId[] = $v['id']; + } + return JsonService::successful('ok', implode(',', $cateId)); + } + /** + * 购物车库存修改 + * @param int $cartId + * @param int $cartNum + */ + public function set_buy_cart_num($cartId = 0, $cartNum = 0) + { + if (!$cartId) return JsonService::fail('参数错误'); + $res = StoreCart::edit(['cart_num' => $cartNum], $cartId); + if ($res) return JsonService::successful(); + else return JsonService::fail('修改失败'); + } +} diff --git a/application/ebapi/controller/AuthController.php b/application/ebapi/controller/AuthController.php new file mode 100644 index 00000000..37d2f37d --- /dev/null +++ b/application/ebapi/controller/AuthController.php @@ -0,0 +1,18 @@ +userInfo=$this->checkTokenGetUserInfo(); + $this->uid=isset($this->userInfo['uid']) ? $this->userInfo['uid'] : 0; + } +} \ No newline at end of file diff --git a/application/ebapi/controller/Basic.php b/application/ebapi/controller/Basic.php new file mode 100644 index 00000000..1044202b --- /dev/null +++ b/application/ebapi/controller/Basic.php @@ -0,0 +1,170 @@ +Debug=Config::get('app_debug'); + $this->runApimiddlewareGroups(); + } + + /* + * 验证token 正确返回userinfo 失败终止程序运行 + * */ + protected function checkTokenGetUserInfo() + { + //生产模式非微信内部浏览器禁止访问 + if(!UtilService::isWechatBrowser() && $this->Debug===false) return $this->fail('非法访问'); + //获取白名单跳过token验证 + $check =$this->checkAuth(); + //获取token + $token =$this->getRequestToken(); + if(!$token && $check===false) $this->fail('请传入token验证您的身份信息'); + //验证token + $Tokencheck=TokenService::checkToken($token,$check); + if($Tokencheck===true){ + return ['uid'=>0]; + }else if(is_array($Tokencheck)){ + list($uid)=$Tokencheck; + $userInfo = User::get($uid); + }else $this->fail('没有获取到用户信息,请传入token验证您的身份信息',[],402); + if((!$userInfo || !isset($userInfo)) && $check===false) $this->fail('用户信息获取失败,没有这样的用户!',[],402); + if(isset($userInfo)){ + if(!$userInfo->status) $this->fail('您已被禁止登录',[],401); + HookService::listen('init',$userInfo,null,false,UserBehavior::class); + return $userInfo->toArray(); + }else return ['uid'=>0]; + } + + /* + * 没有开启路由时运行行为 开启路由请用路由加载行为 + * + * */ + protected function runApimiddlewareGroups() + { + $hash=$this->request->routeInfo(); + if(!Config::get('url_route_on') || !isset($hash['rule'][1])) + { + foreach ((array)$this->ApimiddlewareGroups as $behavior){ + $result=Hook::exec($behavior); + if(!is_null($result)) return $this->fail($result); + } + } + } + + public function _empty($name) + { + $this->fail('您访问的页面不存在:'.$name); + } + /* + * 获取请求token + * @return string + * */ + protected function getRequestToken() + { + //非生产模式允许把token放在url上传输请求 + if($this->Debug){ + $TOKEN=$this->request->header('token'); + }else{ + $TOKEN =$this->request->get('token',''); + if($TOKEN==='') $TOKEN=$this->request->param('token',''); + if($TOKEN==='') $TOKEN=$this->request->header('token'); + } + return $TOKEN; + } + /* + * 正确操作返回json + * @param string | array $msg 提示语或者数据 + * @param array $data 数据 + * @param int $status + * @return json + * */ + protected function successful($msg='ok',$data=[],$status=200) + { + return JsonService::successful($msg,$data,$status); + } + /* + * 错误操作返回json + * @param string | array $msg 提示语或者数据 + * @param array $data 数据 + * @param int $status + * @return json + * */ + protected function fail($msg='error',$data=[],$status=400) + { + return JsonService::fail($msg,$data,$status); + } + /* + * 组装路由 + * @param string $action 方法 + * @param string $controller 控制器 + * @param string $module 模块 + * @return string + * */ + protected function getAuthName($action,$controller,$module) + { + return strtolower($module.'/'.$controller.'/'.$action); + } + + /* + * 获取当前的控制器名,模块名,方法名,类名并返回 + * @param string $controller 控制器 + * @param string $module 模块 + * @return string + * */ + protected function getCurrentController($controller,$module) + { + return 'app\\'.$module.'\\controller\\'.str_replace('.','\\',$controller); + } + + /* + * 校验器 效验白名单方法跳过token验证 + * @param string $action 方法名 + * @param string $controller 控制器名 + * @param string $module 模块名 + * @return boolean + * */ + protected function checkAuth($action = null,$controller = null,$module = null) + { + //获取当前控制器,模型,方法 + if($module === null) $module = $this->request->module(); + if($controller === null) $controller = $this->request->controller(); + if($action === null) $action = $this->request->action(); + //获取当前访问类名全称 + $className=$this->getCurrentController($controller,$module); + if(method_exists($className,'whiteList')){ + try{ + //执行白名单方法获取白名单 + $white=$className::whiteList(); + if(!is_array($white)) return false; + foreach ($white as $actionWhite){ + //比较白名单和当前访问方法 + if($this->getAuthName($actionWhite,$controller,$module)==$this->getAuthName($action,$controller,$module)) + return true; + } + }catch (\Exception $e){} + } + return false; + } + +} \ No newline at end of file diff --git a/application/ebapi/controller/CouponsApi.php b/application/ebapi/controller/CouponsApi.php new file mode 100644 index 00000000..2b29d682 --- /dev/null +++ b/application/ebapi/controller/CouponsApi.php @@ -0,0 +1,96 @@ +userInfo['uid']); + break; + case 1: + $list=StoreCouponUser::getUserValidCoupon($this->userInfo['uid']); + break; + case 2: + $list=StoreCouponUser::getUserAlreadyUsedCoupon($this->userInfo['uid']); + break; + default: + $list=StoreCouponUser::getUserBeOverdueCoupon($this->userInfo['uid']); + break; + } + foreach ($list as &$v){ + $v['add_time'] = date('Y/m/d',$v['add_time']); + $v['end_time'] = date('Y/m/d',$v['end_time']); + } + return JsonService::successful($list); + } + /** + * 获取用户优惠券 + * @return \think\response\Json + */ + public function get_use_coupon(){ + + return JsonService::successful('',StoreCouponUser::getUserAllCoupon($this->userInfo['uid'])); + } + + /** + * 获取可以使用的优惠券 + * @param int $totalPrice + * @return \think\response\Json + */ + public function get_use_coupon_order($totalPrice = 0) + { + return JsonService::successful(StoreCouponUser::beUsableCouponList($this->userInfo['uid'],$totalPrice)); + } + + + /** + * 领取优惠券 + * @param string $couponId + * @return \think\response\Json + */ + public function user_get_coupon($couponId = '') + { + if(!$couponId || !is_numeric($couponId)) return JsonService::fail('参数错误!'); + if(StoreCouponIssue::issueUserCoupon($couponId,$this->userInfo['uid'])){ + return JsonService::successful('领取成功'); + }else{ + return JsonService::fail(StoreCouponIssue::getErrorInfo('领取失败!')); + } + } + + /** + * 获取一条优惠券 + * @param int $couponId + * @return \think\response\Json + */ + public function get_coupon_rope($couponId = 0){ + if(!$couponId) return JsonService::fail('参数错误'); + $couponUser = StoreCouponUser::validAddressWhere()->where('id',$couponId)->where('uid',$this->userInfo['uid'])->find(); + return JsonService::successful($couponUser); + } + /** + * 获取 可以领取的优惠券 + * @param int $limit + * @return \think\response\Json + */ + public function get_issue_coupon_list($limit = 2,$page=0) + { + return JsonService::successful(StoreCouponIssue::getIssueCouponList($this->uid,$limit,$page)); + } +} \ No newline at end of file diff --git a/application/ebapi/controller/Login.php b/application/ebapi/controller/Login.php new file mode 100644 index 00000000..a4b83254 --- /dev/null +++ b/application/ebapi/controller/Login.php @@ -0,0 +1,97 @@ +decryptCode($data['session_key'], $data['iv'], $data['encryptedData']); + }catch (\Exception $e){ + if($e->getCode()=='-41003') return JsonService::status('410','获取会话密匙失败'); + } + if(!isset($userInfo['openId'])) return JsonService::fail('openid获取失败'); + if(!isset($userInfo['unionId'])) $userInfo['unionId'] = ''; + $userInfo['session_key'] = $data['session_key']; + $userInfo['spid'] = $data['spid']; + $userInfo['code'] = $data['code']; + $dataOauthInfo = WechatUser::routineOauth($userInfo); + $userInfo['uid'] = $dataOauthInfo['uid']; + $userInfo['page'] = $dataOauthInfo['page']; + $userInfo['token'] = TokenService::getToken($userInfo['uid'],$userInfo['openId']); + if($userInfo['token']===false) return JsonService::fail('获取用户访问token失败!'); + $userInfo['status'] = WechatUser::isUserStatus($userInfo['uid']); + return JsonService::successful($userInfo); + } + + /** + * 根据前台传code 获取 openid 和 session_key //会话密匙 + * @param string $code + * @return array|mixed + */ + public function setCode(Request $request){ + list($code) = UtilService::postMore([['code', '']], $request, true);//获取前台传的code + if ($code == '') return JsonService::fail(''); + try{ + $userInfo = MiniProgramService::getUserInfo($code); + }catch (\Exception $e){ + return JsonService::fail('获取session_key失败,请检查您的配置!',['line'=>$e->getLine(),'message'=>$e->getMessage()]); + } + $cache_key = md5(time().$code); + if (isset($userInfo['session_key'])){ + Cache::set('eb_api_code_'.$cache_key, $userInfo['session_key'], 86400); + return JsonService::successful(['cache_key'=>$cache_key]); + }else + return JsonService::fail('获取会话密匙失败'); + } + + /** + * 解密数据 + * @param string $code + * @return array|mixed + */ + public function decryptCode($session = '', $iv = '', $encryptData = '') + { + if (!$session) return JsonService::fail('session参数错误'); + if (!$iv) return JsonService::fail('iv参数错误'); + if (!$encryptData) return JsonService::fail('encryptData参数错误'); + return MiniProgramService::encryptor($session, $iv, $encryptData); + } + +} \ No newline at end of file diff --git a/application/ebapi/controller/Notify.php b/application/ebapi/controller/Notify.php new file mode 100644 index 00000000..b884beef --- /dev/null +++ b/application/ebapi/controller/Notify.php @@ -0,0 +1,23 @@ +GroupDataService::getData('routine_my_menus')]); + } + /* + * 获取授权登录log + * */ + public function get_logo_url() + { + $routine_logo=SystemConfigService::get('routine_logo'); + return JsonService::successful(['logo_url'=>str_replace('\\','/',$routine_logo)]); + } + /** + * TODO 获取首页推荐不同类型产品的轮播图和产品 + * @param int $type + */ + public function get_index_groom_list($type = 1){ + $info['banner'] = []; + $info['list'] = []; + if($type == 1){//TODO 精品推荐 + $info['banner'] = GroupDataService::getData('routine_home_bast_banner')?:[];//TODO 首页精品推荐图片 + $info['list'] = StoreProduct::getBestProduct('id,image,store_name,cate_id,price,ot_price,IFNULL(sales,0) + IFNULL(ficti,0) as sales,unit_name,sort');//TODO 精品推荐个数 + }else if($type == 2){//TODO 热门榜单 + $info['banner'] = GroupDataService::getData('routine_home_hot_banner')?:[];//TODO 热门榜单 猜你喜欢推荐图片 + $info['list'] = StoreProduct::getHotProduct('id,image,store_name,cate_id,price,ot_price,unit_name,sort,IFNULL(sales,0) + IFNULL(ficti,0) as sales',0,$this->uid);//TODO 热门榜单 猜你喜欢 + }else if($type == 3){//TODO 首发新品 + $info['banner'] = GroupDataService::getData('routine_home_new_banner')?:[];//TODO 首发新品推荐图片 + $info['list'] = StoreProduct::getNewProduct('id,image,store_name,cate_id,price,ot_price,unit_name,sort,IFNULL(sales,0) + IFNULL(ficti,0) as sales',0,$this->uid);//TODO 首发新品 + }else if($type == 4){//TODO 促销单品 + $info['banner'] = GroupDataService::getData('routine_home_benefit_banner')?:[];//TODO 促销单品推荐图片 + $info['list'] = StoreProduct::getBenefitProduct('id,image,store_name,cate_id,price,ot_price,stock,unit_name,sort');//TODO 促销单品 + } + return JsonService::successful($info); + } + + /** + * 首页 + */ + public function index(){ + $banner = GroupDataService::getData('routine_home_banner')?:[];//TODO 首页banner图 + $menus = GroupDataService::getData('routine_home_menus')?:[];//TODO 首页按钮 + $roll = GroupDataService::getData('routine_home_roll_news')?:[];//TODO 首页滚动新闻 + $activity = GroupDataService::getData('routine_home_activity',3)?:[];//TODO 首页活动区域图片 + $info['fastInfo'] = SystemConfigService::get('fast_info');//TODO 快速选择简介 + $info['bastInfo'] = SystemConfigService::get('bast_info');//TODO 精品推荐简介 + $info['firstInfo'] = SystemConfigService::get('first_info');//TODO 首发新品简介 + $info['salesInfo'] = SystemConfigService::get('sales_info');//TODO 促销单品简介 + $logoUrl = SystemConfigService::get('routine_index_logo');//TODO 促销单品简介 + if(strstr($logoUrl,'http')===false) $logoUrl=SystemConfigService::get('site_url').$logoUrl; + $logoUrl=str_replace('\\','/',$logoUrl); + $fastNumber = (int)SystemConfigService::get('fast_number');//TODO 快速选择分类个数 + $bastNumber = (int)SystemConfigService::get('bast_number');//TODO 精品推荐个数 + $firstNumber = (int)SystemConfigService::get('first_number');//TODO 首发新品个数 + $info['fastList'] = StoreCategory::byIndexList($fastNumber);//TODO 快速选择分类个数 + $info['bastList'] = StoreProduct::getBestProduct('id,image,store_name,cate_id,price,ot_price,IFNULL(sales,0) + IFNULL(ficti,0) as sales,unit_name,sort',$bastNumber,$this->uid);//TODO 精品推荐个数 + $info['firstList'] = StoreProduct::getNewProduct('id,image,store_name,cate_id,price,unit_name,sort',$firstNumber);//TODO 首发新品个数 + $info['bastBanner'] = GroupDataService::getData('routine_home_bast_banner')?:[];//TODO 首页精品推荐图片 + $benefit = StoreProduct::getBenefitProduct('id,image,store_name,cate_id,price,ot_price,stock,unit_name,sort',3);//TODO 首页促销单品 + $lovely =[];//TODO 首发新品顶部图 + $likeInfo = StoreProduct::getHotProduct('id,image,store_name,cate_id,price,unit_name,sort',3);//TODO 热门榜单 猜你喜欢 + $couponList=StoreCouponIssue::getIssueCouponList($this->uid,3); + return $this->successful(compact('banner','menus','roll','info','activity','lovely','benefit','likeInfo','logoUrl','couponList')); + } + + /** + * 猜你喜欢 加载 + * @param Request $request + */ + public function get_hot_product(){ + $data = UtilService::getMore([['offset',0],['limit',0]],$this->request); + $hot = StoreProduct::getHotProductLoading('id,image,store_name,cate_id,price,unit_name,sort',$data['offset'],$data['limit']);//猜你喜欢 + return $this->successful($hot); + } + + /* + * 根据经纬度获取当前地理位置 + * */ + public function getlocation($latitude='',$longitude=''){ + $location=HttpService::getRequest('https://apis.map.qq.com/ws/geocoder/v1/', + ['location'=>$latitude.','.$longitude,'key'=>'U65BZ-F2IHX-CGZ4I-73I7L-M6FZF-TEFCH']); + $location=$location ? json_decode($location,true) : []; + if($location && isset($location['result']['address'])){ + try{ + $address=$location['result']['address_component']['street']; + return $this->successful(['address'=>$address]); + }catch (\Exception $e){ + return $this->fail('获取位置信息失败!'); + } + }else{ + return $this->fail('获取位置信息失败!'); + } + } + + /* + * 根据key来取系统的值 + * */ + public function get_system_config_value($name=''){ + if($name=='') return JsonService::fail('缺少参数'); + $name=str_replace(SystemConfigService::$ProtectedKey,'',$name); + if(strstr($name,',')!==false){ + return $this->successful(SystemConfigService::more($name)); + }else{ + $value=SystemConfigService::get($name); + $value=is_array($value) ? $value[0] : $value; + return $this->successful([$name=>$value]); + } + } + + /* + * 获取系统 + * */ + public function get_system_group_data_value($name='',$multi=0){ + if($name=='') return $this->successful([$name=>[]]); + if($multi==1){ + $name=json_decode($name,true); + $value=[]; + foreach ($name as $item){ + $value[$item]=GroupDataService::getData($item)?:[]; + } + return $this->successful($value); + }else{ + $value= GroupDataService::getData($name)?:[]; + return $this->successful([$name=>$value]); + } + } + /* + * 删除指定资源 + * + * */ + public function delete_image(){ + $post=UtilService::postMore([ + ['pic',''], + ]); + if($post['pic']=='') return $this->fail('缺少删除资源'); + $type=['php','js','css','html','ttf','otf']; + $post['pic']=substr($post['pic'],1); + $ext=substr($post['pic'],-3); + if(in_array($ext,$type)) return $this->fail('非法操作'); + if(strstr($post['pic'],'uploads')===false) return $this->fail('非法操作'); + try{ + if(file_exists($post['pic'])) unlink($post['pic']); + if(strstr($post['pic'],'s_')!==false){ + $pic=str_replace(['s_'],'',$post['pic']); + if(file_exists($pic)) unlink($pic); + } + return $this->successful('删除成功'); + }catch (\Exception $e){ + return $this->fail('刪除失败',['line'=>$e->getLine(),'message'=>$e->getMessage()]); + } + } + + /** + * 上传图片 + * @param string $filename + * @return \think\response\Json + */ + public function upload($dir='') + { + $data = UtilService::postMore([ + ['filename',''], + ],$this->request); + if(Cache::has('start_uploads_'.$this->uid) && Cache::get('start_uploads_'.$this->uid) >= 100) return $this->fail('非法操作'); + $res = UploadService::image($data['filename'],$dir ? $dir: 'store/comment'); + if($res->status == 200){ + if(Cache::has('start_uploads_'.$this->uid)) + $start_uploads=(int)Cache::get('start_uploads_'.$this->uid); + else + $start_uploads=0; + $start_uploads++; + Cache::set('start_uploads_'.$this->uid,$start_uploads,86400); + return $this->successful('图片上传成功!', ['name' => $res->fileInfo->getSaveName(), 'url' => UploadService::pathToUrl($res->dir)]); + }else + return $this->fail($res->error); + } + + /** + * 获取退款理由 + */ + public function get_refund_reason(){ + $reason = SystemConfigService::get('stor_reason')?:[];//退款理由 + $reason = str_replace("\r\n","\n",$reason);//防止不兼容 + $reason = explode("\n",$reason); + return $this->successful($reason); + } + + /** + * 获取提现银行 + */ + public function get_user_extract_bank(){ + $extractBank = SystemConfigService::get('user_extract_bank')?:[];//提现银行 + $extractBank = str_replace("\r\n","\n",$extractBank);//防止不兼容 + $data['extractBank'] = explode("\n",$extractBank); + $data['minPrice'] = SystemConfigService::get('user_extract_min_price');//提现最低金额 + return $this->successful($data); + } + + /** + * 收集发送模板信息的formID + * @param string $formId + */ + public function get_form_id($formId = ''){ + if($formId==''){ + list($formIds)=UtilService::postMore([ + ['formIds',[]] + ],$this->request,true); + foreach ($formIds as $formId){ + RoutineFormId::SetFormId($formId,$this->uid); + } + }else + RoutineFormId::SetFormId($formId,$this->uid); + return $this->successful(''); + } + + /** + * 刷新数据缓存 + */ + public function refresh_cache(){ + `php think optimize:schema`; + `php think optimize:autoload`; + `php think optimize:route`; + `php think optimize:config`; + } + + /* + * 清除系统全部缓存 + * @return + * */ + public function clear_cache() + { + \think\Cache::clear(); + } + + /* + * 获取会员等级 + * */ + public function get_level_list() + { + return JsonService::successful(SystemUserLevel::getLevelList($this->uid)); + } + + /* + * 获取某个等级的任务 + * @param int $level_id 等级id + * @return json + * */ + public function get_task($level_id=''){ + return JsonService::successful(SystemUserTask::getTashList($level_id,$this->uid)); + } + + /* + * 检测用户是否可以成为会员 + * */ + public function set_level_complete() + { + return JsonService::successful(UserLevel::setLevelComplete($this->uid)); + } + + /* + * 记录用户分享次数 + * */ + public function set_user_share() + { + return JsonService::successful(UserBill::setUserShare($this->uid)); + } + +} \ No newline at end of file diff --git a/application/ebapi/controller/SeckillApi.php b/application/ebapi/controller/SeckillApi.php new file mode 100644 index 00000000..f727ebef --- /dev/null +++ b/application/ebapi/controller/SeckillApi.php @@ -0,0 +1,99 @@ +&$value){ + $currentHour = date('H'); + $activityEndHour = bcadd((int)$value['time'],(int)$value['continued'],0); + if($activityEndHour > 24){ + $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'].':00' : '0'.(int)$value['time'].':00'; + $value['state'] = '即将开始'; + $value['status'] = 2; + $value['stop'] = bcadd(strtotime(date('Y-m-d')),bcmul($activityEndHour,3600,0)); + }else{ + if($currentHour >= (int)$value['time'] && $currentHour < $activityEndHour){ + $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'].':00' : '0'.(int)$value['time'].':00'; + $value['state'] = '抢购中'; + $value['stop'] = bcadd(strtotime(date('Y-m-d')),bcmul($activityEndHour,3600,0)); + $value['status'] = 1; + if(!$seckillTimeIndex) $seckillTimeIndex = $key; + }else if($currentHour < (int)$value['time']){ + $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'].':00' : '0'.(int)$value['time'].':00'; + $value['state'] = '即将开始'; + $value['status'] = 2; + $value['stop'] = bcadd(strtotime(date('Y-m-d')),bcmul($activityEndHour,3600,0)); + }else if($currentHour >= $activityEndHour){ + $value['time'] = strlen((int)$value['time']) == 2 ? (int)$value['time'].':00' : '0'.(int)$value['time'].':00'; + $value['state'] = '已结束'; + $value['status'] = 0; + $value['stop'] = bcadd(strtotime(date('Y-m-d')),bcmul($activityEndHour,3600,0)); + } + } + } + } + $data['lovely'] = isset($lovely[0]) ? $lovely[0] : ''; + $data['seckillTime'] = $seckillTime; + $data['seckillTimeIndex'] = $seckillTimeIndex; + return JsonService::successful($data); + } + + public function seckill_list(){ + $data = UtilService::postMore([['time',0],['offset',0],['limit',20]]); + if(!$data['time']) return JsonService::fail('参数错误'); + $timeInfo = GroupDataService::getDataNumber($data['time']); + $activityEndHour = bcadd((int)$timeInfo['time'],(int)$timeInfo['continued'],0); + $startTime = bcadd(strtotime(date('Y-m-d')),bcmul($timeInfo['time'],3600,0)); + $stopTime = bcadd(strtotime(date('Y-m-d')),bcmul($activityEndHour,3600,0)); + $seckillInfo = StoreSeckill::seckillList($startTime,$stopTime,$data['offset'],$data['limit']); + if(count($seckillInfo)){ + foreach ($seckillInfo as $key=>&$item){ + $percent = (int)bcmul(bcdiv($item['sales'],bcadd($item['stock'],$item['sales'],0),2),100,0); + $item['percent'] = $percent ? $percent : 10; + } + } + return JsonService::successful($seckillInfo); + } + /** + * 秒杀详情页 + * @param Request $request + * @return \think\response\Json + */ + public function seckill_detail(){ + $data = UtilService::postMore(['id']); + $id = $data['id']; + if(!$id || !($storeInfo = StoreSeckill::getValidProduct($id))) return JsonService::fail('商品不存在或已下架!'); + $storeInfo['userLike'] = StoreProductRelation::isProductRelation($storeInfo['product_id'],$this->userInfo['uid'],'like','product_seckill'); + $storeInfo['like_num'] = StoreProductRelation::productRelationNum($storeInfo['product_id'],'like','product_seckill'); + $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($storeInfo['product_id'],$this->userInfo['uid'],'collect','product_seckill'); + $storeInfo['uid'] = $this->userInfo['uid']; + $data['storeInfo'] = $storeInfo; + setView($this->userInfo['uid'],$id,$storeInfo['product_id'],'viwe'); + $data['reply'] = StoreProductReply::getRecProductReply($storeInfo['product_id']); + $data['replyCount'] = StoreProductReply::productValidWhere()->where('product_id',$storeInfo['id'])->count(); + return JsonService::successful($data); + } +} \ No newline at end of file diff --git a/application/ebapi/controller/StoreApi.php b/application/ebapi/controller/StoreApi.php new file mode 100644 index 00000000..b2470580 --- /dev/null +++ b/application/ebapi/controller/StoreApi.php @@ -0,0 +1,373 @@ +uid)); + } + /** + * 分类页面 + * @param Request $request + * @return \think\response\Json + */ + public function store1(Request $request) + { + $data = UtilService::postMore([['keyword',''],['cid',''],['sid','']],$request); + $keyword = addslashes($data['keyword']); + $cid = intval($data['cid']); + $sid = intval($data['sid']); + $category = null; + if($sid) $category = StoreCategory::get($sid); + if($cid && !$category) $category = StoreCategory::get($cid); + $data['keyword'] = $keyword; + $data['cid'] = $cid; + $data['sid'] = $sid; + return JsonService::successful($data); + } + /** + * 一级分类 + * @return \think\response\Json + */ + public function get_pid_cate(){ + $data = StoreCategory::pidByCategory(0,'id,cate_name');//一级分类 + if(Cache::has('one_pid_cate_list')) + return JsonService::successful(Cache::get('one_pid_cate_list')); + else{ + Cache::set('one_pid_cate_list',$data); + return JsonService::successful($data); + } + } + /** + * 二级分类 + * @param Request $request + * @return \think\response\Json + */ + public function get_id_cate(Request $request){ + $data = UtilService::postMore([['id',0]],$request); + $dataCateA = []; + $dataCateA[0]['id'] = $data['id']; + $dataCateA[0]['cate_name'] = '全部商品'; + $dataCateA[0]['pid'] = 0; + $dataCateE = StoreCategory::pidBySidList($data['id']);//根据一级分类获取二级分类 + if($dataCateE) $dataCateE = $dataCateE->toArray(); + $dataCate = []; + $dataCate = array_merge_recursive($dataCateA,$dataCateE); + return JsonService::successful($dataCate); + } + /** + * 分类页面产品 + * @param string $keyword + * @param int $cId + * @param int $sId + * @param string $priceOrder + * @param string $salesOrder + * @param int $news + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_product_list() + { + $data = UtilService::getMore([ + ['sid',0], + ['cid',0], + ['keyword',''], + ['priceOrder',''], + ['salesOrder',''], + ['news',0], + ['page',0], + ['limit',0] + ],$this->request); + return JsonService::successful(StoreProduct::getProductList($data,$this->uid)); + } + + /** + * 商品详情页 + * @param Request $request + */ + public function details($id=0){ + if(!$id || !($storeInfo = StoreProduct::getValidProduct($id))) return JsonService::fail('商品不存在或已下架'); + $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($id,$this->userInfo['uid'],'collect'); + list($productAttr,$productValue) = StoreProductAttr::getProductAttrDetail($id); + setView($this->userInfo['uid'],$id,$storeInfo['cate_id'],'viwe'); + $data['storeInfo'] = StoreProduct::setLevelPrice($storeInfo,$this->uid,true); + $data['similarity'] = StoreProduct::cateIdBySimilarityProduct($storeInfo['cate_id'],'id,store_name,image,price,sales,ficti',4); + $data['productAttr'] = $productAttr; + $data['productValue'] = $productValue; + $data['priceName']=StoreProduct::getPacketPrice($storeInfo,$productValue); + $data['reply'] = StoreProductReply::getRecProductReply($storeInfo['id']); + $data['replyCount'] = StoreProductReply::productValidWhere()->where('product_id',$storeInfo['id'])->count(); + if($data['replyCount']){ + $goodReply=StoreProductReply::productValidWhere()->where('product_id',$storeInfo['id'])->where('product_score',5)->count(); + $data['replyChance']=bcdiv($goodReply,$data['replyCount'],2); + $data['replyChance']=bcmul($data['replyChance'],100,3); + }else $data['replyChance']=0; + $data['mer_id'] = StoreProduct::where('id',$storeInfo['id'])->value('mer_id'); + return JsonService::successful($data); + } + + /* + * 获取产品是否收藏 + * + * */ + public function get_product_collect($product_id=0) + { + return JsonService::successful(['userCollect'=>StoreProductRelation::isProductRelation($product_id,$this->userInfo['uid'],'collect')]); + } + /** + * 获取产品评论 + * @param int $productId + * @return \think\response\Json + */ + public function get_product_reply($productId = 0){ + if(!$productId) return JsonService::fail('参数错误'); + $replyCount = StoreProductReply::productValidWhere()->where('product_id',$productId)->count(); + $reply = StoreProductReply::getRecProductReply($productId); + return JsonService::successful(['replyCount'=>$replyCount,'reply'=>$reply]); + } + + /** + * 添加点赞 + * @param string $productId + * @param string $category + * @return \think\response\Json + */ + public function like_product($productId = '',$category = 'product'){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreProductRelation::productRelation($productId,$this->userInfo['uid'],'like',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful(); + } + + /** + * 取消点赞 + * @param string $productId + * @param string $category + * @return \think\response\Json + */ + public function unlike_product($productId = '',$category = 'product'){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreProductRelation::unProductRelation($productId,$this->userInfo['uid'],'like',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful(); + } + + /** + * 添加收藏 + * @param $productId + * @param string $category + * @return \think\response\Json + */ + public function collect_product($productId,$category = 'product'){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreProductRelation::productRelation($productId,$this->userInfo['uid'],'collect',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful(); + } + + /** + * 批量收藏 + * @param string $productId + * @param string $category + * @return \think\response\Json + */ + public function collect_product_all($productId = '',$category = 'product'){ + if($productId == '') return JsonService::fail('参数错误'); + $productIdS = explode(',',$productId); + $res = StoreProductRelation::productRelationAll($productIdS,$this->userInfo['uid'],'collect',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful('收藏成功'); + } + + /** + * 取消收藏 + * @param $productId + * @param string $category + * @return \think\response\Json + */ + public function uncollect_product($productId,$category = 'product'){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreProductRelation::unProductRelation($productId,$this->userInfo['uid'],'collect',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful(); + } + + /** + * 获取收藏产品 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_user_collect_product($page = 0,$limit = 8) + { + return JsonService::successful(StoreProductRelation::getUserCollectProduct($this->uid,$page,$limit)); + } + /** + * 获取收藏产品删除 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_user_collect_product_del($pid=0) + { + if($pid){ + $list = StoreProductRelation::where('uid',$this->userInfo['uid'])->where('product_id',$pid)->delete(); + return JsonService::successful($list); + }else + return JsonService::fail('缺少参数'); + } + + /** + * 获取订单内的某个产品信息 + * @param string $uni + * @param string $productId + * @return \think\response\Json + */ + public function get_order_product($unique = ''){ + if(!$unique || !StoreOrderCartInfo::be(['unique'=>$unique]) || !($cartInfo = StoreOrderCartInfo::where('unique',$unique)->find())) return JsonService::fail('评价产品不存在!'); + return JsonService::successful($cartInfo); + } + + /** + * 获取一级和二级分类 + * @return \think\response\Json + */ + public function get_product_category() + { + return JsonService::successful(StoreCategory::getProductCategory()); + } + + /** + * 获取产品评论 + * @param string $productId + * @param int $first + * @param int $limit + * @param int $type + * @return \think\response\Json + */ + public function product_reply_list($productId = '',$page = 0,$limit = 8, $type = 0) + { + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误!'); + $list = StoreProductReply::getProductReplyList($productId,(int)$type,$page,$limit); + return JsonService::successful($list); + } + + /* + * 获取评论数量和评论好评度 + * @param int $productId + * @return \think\response\Json + * */ + public function product_reply_count($productId = '') + { + if(!$productId) return JsonService::fail('缺少参数'); + return JsonService::successful(StoreProductReply::productReplyCount($productId)); + } + + /** + * 获取商品属性数据 + * @param string $productId + * @return \think\response\Json + */ + public function product_attr_detail($productId = '') + { + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误!'); + list($productAttr,$productValue) = StoreProductAttr::getProductAttrDetail($productId); + return JsonService::successful(compact('productAttr','productValue')); + + } + + /* + * 获取产品海报 + * @param int $id 产品id + * */ + public function poster($id = 0){ +// if(!$id) return JsonService::fail('参数错误'); +// $productInfo = StoreProduct::getValidProduct($id,'store_name,id,price,image,code_path'); +// if(empty($productInfo)) return JsonService::fail('参数错误'); +// if(strlen($productInfo['code_path'])< 10) { +// $path = 'public'.DS.'uploads'.DS.'codepath'.DS.'product'; +// $codePath = $path.DS.$productInfo['id'].'.jpg'; +// if(!file_exists($codePath)){ +// if(!is_dir($path)) mkdir($path,0777,true); +// $res = file_put_contents($codePath,RoutineCode::getPages('pages/goods_details/index?id='.$productInfo['id'])); +// } +// $res = StoreProduct::edit(['code_path'=>$codePath],$id); +// if($res) $productInfo['code_path'] = $codePath; +// else return JsonService::fail('没有查看权限'); +// } +// $posterPath = createPoster($productInfo); +// return JsonService::successful($posterPath); + } + + /** + * 产品海报二维码 + * @param int $id + */ + public function product_promotion_code($id = 0){ + if(!$id) return JsonService::fail('参数错误ID不存在'); + $count = StoreProduct::validWhere()->count(); + if(!$count) return JsonService::fail('参数错误'); + $path = makePathToUrl('routine/product/',4); + if($path == '') return JsonService::fail('生成上传目录失败,请检查权限!'); + $codePath = $path.$id.'_'.$this->userInfo['uid'].'_product.jpg'; + $domain = SystemConfigService::get('site_url').'/'; + if(!file_exists($codePath)){ + if(!is_dir($path)) mkdir($path,0777,true); + $data='id='.$id; + if($this->userInfo['is_promoter'] || SystemConfigService::get('store_brokerage_statu')==2) $data.='&pid='.$this->uid; + $res = RoutineCode::getPageCode('pages/goods_details/index',$data,280); + if($res) file_put_contents($codePath,$res); + else return JsonService::fail('二维码生成失败'); + } + return JsonService::successful($domain.$codePath); + } + + /** + * 热门搜索 + */ + public function get_routine_hot_search(){ + $routineHotSearch = GroupDataService::getData('routine_hot_search') ? :[]; + return JsonService::successful($routineHotSearch); + } +} \ No newline at end of file diff --git a/application/ebapi/controller/UserApi.php b/application/ebapi/controller/UserApi.php new file mode 100644 index 00000000..1ca0aa14 --- /dev/null +++ b/application/ebapi/controller/UserApi.php @@ -0,0 +1,810 @@ +uid,$page,$limit)); + } + /* + * 获取用户签到记录列表 + * + * */ + public function get_sign_list($page=1,$limit=10) + { + return JsonService::successful(UserSign::getSignList($this->uid,$page,$limit)); + } + /* + * 获取当前登录的用户信息 + * */ + public function get_my_user_info() + { + list($isSgin,$isIntegral,$isall)=UtilService::getMore([ + ['isSgin',0], + ['isIntegral',0], + ['isall',0], + ],$this->request,true); + //是否统计签到 + if($isSgin || $isall){ + $this->userInfo['sum_sgin_day']=UserSign::getSignSumDay($this->uid); + $this->userInfo['is_day_sgin']=UserSign::getToDayIsSign($this->uid); + $this->userInfo['is_YesterDay_sgin']=UserSign::getYesterDayIsSign($this->uid); + if(!$this->userInfo['is_day_sgin'] && !$this->userInfo['is_YesterDay_sgin']){ + $this->userInfo['sign_num']=0; + } + } + //是否统计积分使用情况 + if($isIntegral || $isall){ + $this->userInfo['sum_integral']=(int)UserBill::getRecordCount($this->uid,'integral','sign,system_add,gain'); + $this->userInfo['deduction_integral']=(int)UserBill::getRecordCount($this->uid,'integral','deduction') ? : 0; + $this->userInfo['today_integral']=(int)UserBill::getRecordCount($this->uid,'integral','sign,system_add,gain','today'); + } + unset($this->userInfo['pwd']); + $this->userInfo['integral']=(int)$this->userInfo['integral']; + if(!$this->userInfo['is_promoter']){ + $this->userInfo['is_promoter']=(int)SystemConfigService::get('store_brokerage_statu') == 2 ? true : false; + } + return JsonService::successful($this->userInfo); + } + /** + * 获取用户信息 + * @param int $userId 用户uid + * @return \think\response\Json + */ + public function get_user_info_uid($userId = 0){ + if(!$userId) return JsonService::fail('参数错误'); + $res = User::getUserInfo($userId); + if($res) return JsonService::successful($res); + else return JsonService::fail(User::getErrorInfo()); + } + /** + * 个人中心 + * @return \think\response\Json + */ + public function my(){ + $this->userInfo['couponCount'] = StoreCouponUser::getUserValidCouponCount($this->userInfo['uid']); + $this->userInfo['like'] = StoreProductRelation::getUserIdCollect($this->userInfo['uid']);; + $this->userInfo['orderStatusNum'] = StoreOrder::getOrderStatusNum($this->userInfo['uid']); + $this->userInfo['notice'] = UserNotice::getNotice($this->userInfo['uid']); + $this->userInfo['brokerage'] = UserBill::getBrokerage($this->uid);//获取总佣金 + $this->userInfo['recharge'] = UserBill::getRecharge($this->uid);//累计充值 + $this->userInfo['orderStatusSum'] = StoreOrder::getOrderStatusSum($this->uid);//累计消费 + $this->userInfo['extractTotalPrice'] = UserExtract::userExtractTotalPrice($this->uid);//累计提现 + if($this->userInfo['brokerage'] > $this->userInfo['extractTotalPrice']) { + $this->userInfo['brokerage']=bcsub($this->userInfo['brokerage'],$this->userInfo['extractTotalPrice'],2);//减去已提现金额 + $extract_price=UserExtract::userExtractTotalPrice($this->uid,0); + $this->userInfo['brokerage']=$extract_price < $this->userInfo['brokerage'] ? bcsub($this->userInfo['brokerage'],$extract_price,2) : 0;//减去审核中的提现金额 + }else{ + $this->userInfo['brokerage']=0; + } + $this->userInfo['extractPrice'] = (float)bcsub($this->userInfo['brokerage'],$this->userInfo['extractTotalPrice'],2) > 0 ? : 0;//可提现 + $this->userInfo['statu'] = (int)SystemConfigService::get('store_brokerage_statu'); + $vipId=UserLevel::getUserLevel($this->uid); + $this->userInfo['vip']=$vipId !==false ? true : false; + if($this->userInfo['vip']){ + $this->userInfo['vip_id']=$vipId; + $this->userInfo['vip_icon']=UserLevel::getUserLevelInfo($vipId,'icon'); + $this->userInfo['vip_name']=UserLevel::getUserLevelInfo($vipId,'name'); + } + unset($this->userInfo['pwd']); + return JsonService::successful($this->userInfo); + } + + /** + * 用户签到 + * @return \think\response\Json + */ + public function user_sign() + { + $signed = UserSign::getToDayIsSign($this->userInfo['uid']); + if($signed) return JsonService::fail('已签到'); + if(false !== $integral = UserSign::sign($this->uid)) + return JsonService::successful('签到获得'.floatval($integral).'积分',['integral'=>$integral]); + else + return JsonService::fail(UserSign::getErrorInfo('签到失败')); + } + + /** + * 获取一条用户地址 + * @param string $addressId 地址id + * @return \think\response\Json + */ + public function get_user_address($addressId = ''){ + $addressInfo = []; + if($addressId && is_numeric($addressId) && UserAddress::be(['is_del'=>0,'id'=>$addressId,'uid'=>$this->userInfo['uid']])){ + $addressInfo = UserAddress::find($addressId); + } + return JsonService::successful($addressInfo); + } + + /** + * 获取默认地址 + * @return \think\response\Json + */ + public function user_default_address() + { + $defaultAddress = UserAddress::getUserDefaultAddress($this->userInfo['uid'],'id,real_name,phone,province,city,district,detail,is_default'); + if($defaultAddress) return JsonService::successful('ok',$defaultAddress); + else return JsonService::successful('empty',[]); + } + + /** + * 删除地址 + * @param string $addressId 地址id + * @return \think\response\Json + */ + public function remove_user_address($addressId = '') + { + if(!$addressId || !is_numeric($addressId)) return JsonService::fail('参数错误!'); + if(!UserAddress::be(['is_del'=>0,'id'=>$addressId,'uid'=>$this->userInfo['uid']])) + return JsonService::fail('地址不存在!'); + if(UserAddress::edit(['is_del'=>'1'],$addressId,'id')) + return JsonService::successful(); + else + return JsonService::fail('删除地址失败!'); + } + + /** + * 个人中心 获取订单列表 + * @param string $type + * @param int $first + * @param int $limit + * @param string $search + * @return \think\response\Json + */ + public function get_user_order_list() + { + list($type,$page,$limit,$search)=UtilService::getMore([ + ['type',''], + ['page',''], + ['limit',''], + ['search',''], + ],$this->request,true); + return JsonService::successful(StoreOrder::getUserOrderSearchList($this->uid,$type,$page,$limit,$search)); + } + + /** + * 个人中心 订单详情页 + * @param string $order_id + * @return \think\response\Json + */ + public function get_order($uni = ''){ + if($uni == '') return JsonService::fail('参数错误'); + $order = StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni); + $order = $order->toArray(); + $order['add_time_y'] = date('Y-m-d',$order['add_time']); + $order['add_time_h'] = date('H:i:s',$order['add_time']); + if(!$order) return JsonService::fail('订单不存在'); + return JsonService::successful(StoreOrder::tidyOrder($order,true,true)); + } + + /** + * 个人中心 删除订单 + * @param string $uni + * @return \think\response\Json + */ + public function user_remove_order($uni = '') + { + if(!$uni) return JsonService::fail('参数错误!'); + $res = StoreOrder::removeOrder($uni,$this->userInfo['uid']); + if($res) + return JsonService::successful(); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + + /** + * 获取用户手机号码 + * @param Request $request + * @return \think\response\Json + */ + public function bind_mobile(Request $request){ + list($iv,$cache_key,$encryptedData) = UtilService::postMore([ + ['iv',''], + ['cache_key',''], + ['encryptedData',''], + ],$request,true); + $iv = urldecode(urlencode($iv)); + try{ + if(!Cache::has('eb_api_code_'.$cache_key)) return JsonService::fail('获取手机号失败'); + $session_key=Cache::get('eb_api_code_'.$cache_key); + $userInfo = \app\core\util\MiniProgramService::encryptor($session_key,$iv,$encryptedData); + if(!empty($userInfo['purePhoneNumber'])){ + if(User::edit(['phone'=>$userInfo['purePhoneNumber']],$this->userInfo['uid'])) + return JsonService::successful('绑定成功',['phone'=>$userInfo['purePhoneNumber']]); + else + return JsonService::fail('绑定失败'); + }else + return JsonService::fail('获取手机号失败'); + }catch (\Exception $e){ + return JsonService::fail('error',$e->getMessage()); + } + } + /** + * 个人中心 用户确认收货 + * @param string $uni + * @return \think\response\Json + */ + public function user_take_order($uni = '') + { + if(!$uni) return JsonService::fail('参数错误!'); + + $res = StoreOrder::takeOrder($uni,$this->userInfo['uid']); + if($res) + return JsonService::successful(); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + + /** + * 个人中心 充值 + * @param int $price + * @return \think\response\Json + */ + public function user_wechat_recharge($price = 0) + { + if(!$price || $price <=0) return JsonService::fail('参数错误'); + $storeMinRecharge = SystemConfigService::get('store_user_min_recharge'); + if($price < $storeMinRecharge) return JsonService::fail('充值金额不能低于'.$storeMinRecharge); + $rechargeOrder = UserRecharge::addRecharge($this->userInfo['uid'],$price); + if(!$rechargeOrder) return JsonService::fail('充值订单生成失败!'); + try{ + return JsonService::successful(UserRecharge::jsPay($rechargeOrder)); + }catch (\Exception $e){ + return JsonService::fail($e->getMessage()); + } + } + + /** + * 个人中心 余额使用记录 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function user_balance_list($first = 0,$limit = 8) + { + return JsonService::successful(UserBill::userBillList($this->uid,$first,$limit,'now_money')); + } + + /** + * 个人中心 积分使用记录 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function user_integral_list($page = 0,$limit = 8) + { + return JsonService::successful(UserBill::userBillList($this->uid,$page,$limit)); + + } + + /** + * 个人中心 获取一级推荐人 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_spread_list($first = 0,$limit = 20) + { + return JsonService::successful(User::getSpreadList($this->uid,$first,$limit)); + } + + /** + * 个人中心 获取二级推荐人 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_spread_list_two($two_uid=0,$first = 0,$limit = 20) + { + return JsonService::successful(User::getSpreadList($two_uid,$first,$limit)); + } + + /** + * 获取用户所有地址 + * @return \think\response\Json + */ + public function user_address_list($page=1,$limit=8) + { + $list = UserAddress::getUserValidAddressList($this->userInfo['uid'],$page,$limit,'id,real_name,phone,province,city,district,detail,is_default'); + return JsonService::successful($list); + } + + /** + * 修改用户通知为已查看 + * @param $nid + * @return \think\response\Json + */ + public function see_notice($nid) + { + UserNotice::seeNotice($this->userInfo['uid'],$nid); + return JsonService::successful(); + } + /* + * 用户提现申请 + * @param array + * @return \think\response\Json + * */ + public function user_extract() + { + $data=UtilService::postMore([ + ['alipay_code',''], + ['extract_type',''], + ['money',0], + ['name',''], + ['bankname',''], + ['cardnum',''], + ],$this->request); + if(UserExtract::userExtract($this->userInfo,$data)) + return JsonService::successful('申请提现成功!'); + else + return JsonService::fail(UserExtract::getErrorInfo('提现失败')); + } + /** + * 用户下级的订单 + * @param int $first + * @param int $limit + * @return json + */ + public function subordinateOrderlist($first = 0, $limit = 8) + { + list($xUid,$status)=UtilService::postMore([ + ['uid',''], + ['status',''], + ],$this->request,true); + switch ($status){ + case 0: + $type=''; + break; + case 1: + $type=4; + break; + case 2: + $type=3; + break; + default: + return JsonService::fail(); + } + return JsonService::successful(StoreOrder::getSubordinateOrderlist($xUid,$this->uid,$type,$first,$limit)); + } + + /** + * 个人中心 用户下级的订单 + * @param int $first + * @param int $limit + * @return json + */ + public function subordinateOrderlistmoney() + { + $request = Request::instance(); + $lists=$request->param(); + $status = $lists['status']; + $type = ''; + if($status == 1) $type = 4; + elseif($status == 2) $type = 3; + $arr = User::where('spread_uid',$this->userInfo['uid'])->column('uid'); + $list = StoreOrder::getUserOrderCount(implode(',',$arr),$type); + $price = []; +// if(!empty($list)) foreach ($list as $k=>$v) $price[]=$v['pay_price']; + if(!empty($list)) foreach ($list as $k=>$v) $price[]=$v; + $cont = count($list); + $sum = array_sum($price); + return JsonService::successful(['cont'=>$cont,'sum'=>$sum]); + } + + /* + * 用户提现记录列表 + * @param int $first 截取行数 + * @param int $limit 展示条数 + * @return json + */ + public function extract($first = 0,$limit = 8) + { + return JsonService::successful(UserExtract::extractList($this->uid,$first,$limit)); + } + + /** + * 个人中心 订单 评价订单 + * @param string $unique + * @return \think\response\Json + */ + public function user_comment_product($unique = '') + { + if(!$unique) return JsonService::fail('参数错误!'); + $cartInfo = StoreOrderCartInfo::where('unique',$unique)->find(); + $uid = $this->userInfo['uid']; + if(!$cartInfo || $uid != $cartInfo['cart_info']['uid']) return JsonService::fail('评价产品不存在!'); + if(StoreProductReply::be(['oid'=>$cartInfo['oid'],'unique'=>$unique])) + return JsonService::fail('该产品已评价!'); + $group = UtilService::postMore([ + ['comment',''],['pics',[]],['product_score',5],['service_score',5] + ],Request::instance()); + $group['comment'] = htmlspecialchars(trim($group['comment'])); + if($group['product_score'] < 1) return JsonService::fail('请为产品评分'); + else if($group['service_score'] < 1) return JsonService::fail('请为商家服务评分'); + if($cartInfo['cart_info']['combination_id']) $productId = $cartInfo['cart_info']['product_id']; + else if($cartInfo['cart_info']['seckill_id']) $productId = $cartInfo['cart_info']['product_id']; + else if($cartInfo['cart_info']['bargain_id']) $productId = $cartInfo['cart_info']['product_id']; + else $productId = $cartInfo['product_id']; + $group = array_merge($group,[ + 'uid'=>$uid, + 'oid'=>$cartInfo['oid'], + 'unique'=>$unique, + 'product_id'=>$productId, + 'reply_type'=>'product' + ]); + StoreProductReply::beginTrans(); + $res = StoreProductReply::reply($group,'product'); + if(!$res) { + StoreProductReply::rollbackTrans(); + return JsonService::fail('评价失败!'); + } + try{ +// HookService::listen('store_product_order_reply',$group,$cartInfo,false,StoreProductBehavior::class); + StoreOrder::checkOrderOver($cartInfo['oid']); + }catch (\Exception $e){ + StoreProductReply::rollbackTrans(); + return JsonService::fail($e->getMessage()); + } + StoreProductReply::commitTrans(); + return JsonService::successful(); + } + + /* + * 个人中心 查物流 + * @param int $uid 用户id + * @param string $uni 订单id或者订单唯一键 + * @return json + */ + public function express($uni = '') + { + if(!$uni || !($order = StoreOrder::getUserOrderDetail($this->uid,$uni))) return JsonService::fail('查询订单不存在!'); + if($order['delivery_type'] != 'express' || !$order['delivery_id']) return JsonService::fail('该订单不存在快递单号!'); + $cacheName = $uni.$order['delivery_id']; + CacheService::rm($cacheName); + $result = CacheService::get($cacheName,null); + if($result === NULL){ + $result = Express::query($order['delivery_id']); + if(is_array($result) && + isset($result['result']) && + isset($result['result']['deliverystatus']) && + $result['result']['deliverystatus'] >= 3) + $cacheTime = 0; + else + $cacheTime = 1800; + CacheService::set($cacheName,$result,$cacheTime); + } + return JsonService::successful([ 'order'=>StoreOrder::tidyOrder($order,true), 'express'=>$result ? $result : []]); + } + + /** + * 修改收货地址 + * @return \think\response\Json + */ + public function edit_user_address() + { + $request = Request::instance(); + if(!$request->isPost()) return JsonService::fail('参数错误!'); + $addressInfo = UtilService::postMore([ + ['address',[]], + ['is_default',false], + ['real_name',''], + ['post_code',''], + ['phone',''], + ['detail',''], + ['id',0] + ],$request); + $addressInfo['province'] = $addressInfo['address']['province']; + $addressInfo['city'] = $addressInfo['address']['city']; + $addressInfo['district'] = $addressInfo['address']['district']; + $addressInfo['is_default'] = $addressInfo['is_default'] == true ? 1 : 0; + $addressInfo['uid'] = $this->userInfo['uid']; + unset($addressInfo['address']); + + if($addressInfo['id'] && UserAddress::be(['id'=>$addressInfo['id'],'uid'=>$this->userInfo['uid'],'is_del'=>0])){ + $id = $addressInfo['id']; + unset($addressInfo['id']); + if(UserAddress::edit($addressInfo,$id,'id')){ + if($addressInfo['is_default']) + UserAddress::setDefaultAddress($id,$this->userInfo['uid']); + return JsonService::successful(); + }else + return JsonService::fail('编辑收货地址失败!'); + }else{ + if($address = UserAddress::set($addressInfo)){ + if($addressInfo['is_default']) + UserAddress::setDefaultAddress($address->id,$this->userInfo['uid']); + return JsonService::successful(['id'=>$address->id]); + }else + return JsonService::fail('添加收货地址失败!'); + } + } + + /** + * 用户通知 + * @param int $page + * @param int $limit + * @return \think\response\Json + */ + public function get_notice_list($page = 0, $limit = 8) + { + $list = UserNotice::getNoticeList($this->userInfo['uid'],$page,$limit); + return JsonService::successful($list); + } + + /* + * 昨日推广佣金 + * @return json + */ + public function yesterday_commission() + { + return JsonService::successful(UserBill::yesterdayCommissionSum($this->uid)); + } + + /* + * 累计已提金额 + * @return json + */ + public function extractsum() + { + return JsonService::successful(UserExtract::extractSum($this->uid)); + } + + /** + * 绑定推荐人 + * @param Request $request + * @return \think\response\Json + */ + public function spread_uid(Request $request){ + $data = UtilService::postMore(['spread_uid',0],$request); + if($data['spread_uid']){ + if(!$this->userInfo['spread_uid']){ + $res = User::edit(['spread_uid'=>$data['spread_uid']],$this->userInfo['uid']); + if($res) return JsonService::successful('绑定成功'); + else return JsonService::successful('绑定失败'); + }else return JsonService::fail('已存在被推荐人'); + }else return JsonService::fail('没有推荐人'); + } + + /** + * 设置为默认地址 + * @param string $addressId + * @return \think\response\Json + */ + public function set_user_default_address($addressId = '') + { + if(!$addressId || !is_numeric($addressId)) return JsonService::fail('参数错误!'); + if(!UserAddress::be(['is_del'=>0,'id'=>$addressId,'uid'=>$this->userInfo['uid']])) + return JsonService::fail('地址不存在!'); + $res = UserAddress::setDefaultAddress($addressId,$this->userInfo['uid']); + if(!$res) + return JsonService::fail('地址不存在!'); + else + return JsonService::successful(); + } + + /** + * 获取分销二维码 + * @return \think\response\Json + */ + public function get_code(){ + header('content-type:image/jpg'); + if(!$this->userInfo['uid']) return JsonService::fail('授权失败,请重新授权'); + $path = makePathToUrl('routine/code'); + if($path == '') + return JsonService::fail('生成上传目录失败,请检查权限!'); + $picname = $path.'/'.$this->userInfo['uid'].'.jpg'; + $domain = SystemConfigService::get('site_url').'/'; + $domainTop = substr($domain,0,5); + if($domainTop != 'https') $domain = 'https:'.substr($domain,5,strlen($domain)); + if(file_exists($picname)) return JsonService::successful($domain.$picname); + else{ + $res = RoutineCode::getCode($this->userInfo['uid'],$picname); + if($res) file_put_contents($picname,$res); + else return JsonService::fail('二维码生成失败'); + } + return JsonService::successful($domain.$picname); + } + + /* + * 修改用户信息 + * */ + public function edit_user($formid=''){ + list($avatar,$nickname)=UtilService::postMore([ + ['avatar',''], + ['nickname',''], + ],$this->request,true); + RoutineFormId::SetFormId($formid,$this->uid); + if(User::editUser($avatar,$nickname,$this->uid)) + return JsonService::successful('修改成功'); + else + return JsonService::fail(''); + } + + /* + * 查找用户消费充值记录 + * + * */ + public function get_user_bill_list($page=1,$limit=8,$type=0) + { + return JsonService::successful(UserBill::getUserBillList($this->uid,$page,$limit,$type)); + } + + /* + * 获取活动是否存在 + * */ + public function get_activity() + { + $data['is_bargin']=StoreBargain::validBargain() ? true : false; + $data['is_pink']=StoreCombination::getPinkIsOpen() ? true : false; + $data['is_seckill']=StoreSeckill::getSeckillCount() ? true : false; + return JsonService::successful($data); + } + + /** + * TODO 获取记录总和 + * @param int $type + */ + public function get_record_list_count($type = 3) + { + $count = 0; + if($type == 3) $count = UserBill::getRecordCount($this->uid, 'now_money', 'brokerage'); + else if($type == 4) $count = UserExtract::userExtractTotalPrice($this->uid);//累计提现 + $count = $count ? $count : 0; + JsonService::successful('',$count); + } + + /** + * TODO 获取订单返佣记录 + * @param int $first + * @param int $limit + * @param string $category + * @param string $type + */ + public function get_record_order_list($page = 0,$limit = 8,$category = 'now_money', $type = 'brokerage'){ + $data['list'] = []; + $data['count'] = 0; + $data['list'] = UserBill::getRecordList($this->uid,$page,$limit,$category,$type); + $count = UserBill::getRecordOrderCount($this->uid, $category, $type); + $data['count'] = $count ? $count : 0; + if(!count($data['list'])) return JsonService::successful([]); + foreach ($data['list'] as $key=>&$value){ + $value['child'] = UserBill::getRecordOrderListDraw($this->uid, $value['time'],$category, $type); + $value['count'] = count($value['child']); + } + return JsonService::successful($data); + } + + /** + * TODO 获取推广人列表 + * @param int $first + * @param int $limit + * @param int $type + * @param int $keyword + * @param string $order + */ + public function user_spread_new_list($page = 0,$limit = 8,$grade = 0,$keyword = 0,$sort = ''){ + if(!$keyword) $keyword = ''; + $data['list'] = User::getUserSpreadGrade($this->userInfo['uid'],$grade,$sort,$keyword,$page,$limit); + $data['total'] = User::getSpreadCount($this->uid); + $data['totalLevel'] = User::getSpreadLevelCount($this->uid); + return JsonService::successful($data); + } + + /** + * 分销二维码海报生成 + */ + public function user_spread_banner_list(){ + header('content-type:image/jpg'); + try{ + $routineSpreadBanner = GroupDataService::getData('routine_spread_banner'); + if(!count($routineSpreadBanner)) return JsonService::fail('暂无海报'); + $pathCode = makePathToUrl('routine/spread/code',3); + if($pathCode == '') return JsonService::fail('生成上传目录失败,请检查权限!'); + $picName = $pathCode.DS.$this->userInfo['uid'].'.jpg'; + $picName = trim(str_replace(DS, '/',$picName,$loop)); + $res = RoutineCode::getShareCode($this->uid, 'spread', '', $picName); + if($res) file_put_contents($picName,$res); + else return JsonService::fail('二维码生成失败'); + $res = true; + $url = SystemConfigService::get('site_url').'/'; + $domainTop = substr($url,0,5); + if($domainTop != 'https') $url = 'https:'.substr($url,5,strlen($url)); + $pathCode = makePathToUrl('routine/spread/poster',3); + $filelink=[ + 'Bold'=>'public/static/font/SourceHanSansCN-Bold.otf', + 'Normal'=>'public/static/font/SourceHanSansCN-Normal.otf', + ]; + if(!file_exists($filelink['Bold'])) return JsonService::fail('缺少字体文件Bold'); + if(!file_exists($filelink['Normal'])) return JsonService::fail('缺少字体文件Normal'); + foreach ($routineSpreadBanner as $key=>&$item){ + $config = array( + 'image'=>array( + array( + 'url'=>ROOT_PATH.$picName, //二维码资源 + 'stream'=>0, + 'left'=>114, + 'top'=>790, + 'right'=>0, + 'bottom'=>0, + 'width'=>120, + 'height'=>120, + 'opacity'=>100 + ) + ), + 'text'=>array( + array( + 'text'=>$this->userInfo['nickname'], + 'left'=>250, + 'top'=>840, + 'fontPath'=>ROOT_PATH.$filelink['Bold'], //字体文件 + 'fontSize'=>16, //字号 + 'fontColor'=>'40,40,40', //字体颜色 + 'angle'=>0, + ), + array( + 'text'=>'邀请您加入'.SystemConfigService::get('site_name'), + 'left'=>250, + 'top'=>880, + 'fontPath'=>ROOT_PATH.$filelink['Normal'], //字体文件 + 'fontSize'=>16, //字号 + 'fontColor'=>'40,40,40', //字体颜色 + 'angle'=>0, + ) + ), + 'background'=>$item['pic'] + ); + $filename = ROOT_PATH.$pathCode.'/'.$item['id'].'_'.$this->uid.'.png'; + $res = $res && UtilService::setSharePoster($config,$filename); + if($res) $item['poster'] = $url.$pathCode.'/'.$item['id'].'_'.$this->uid.'.png'; + } + if($res) return JsonService::successful($routineSpreadBanner); + else return JsonService::fail('生成图片失败'); + }catch (\Exception $e){ + return JsonService::fail('生成图片时,系统错误',['line'=>$e->getLine(),'message'=>$e->getMessage()]); + } + } + +} \ No newline at end of file diff --git a/application/ebapi/model/article/Article.php b/application/ebapi/model/article/Article.php new file mode 100644 index 00000000..d3210ef5 --- /dev/null +++ b/application/ebapi/model/article/Article.php @@ -0,0 +1,88 @@ +where('hide',0)->where('id',$id)->order('id desc')->find(); + if($list){ + $list = $list->toArray(); + $list["content"] = Db::name('articleContent')->where('nid',$id)->value('content'); + return $list; + } + else return []; + } + + /** + * 获取某个分类底下的文章 + * @param $cid + * @param $first + * @param $limit + * @param string $field + * @return mixed + */ + public static function cidByArticleList($cid, $first, $limit, $field = 'id,title,image_input,visit,add_time,synopsis,url') + { + $model=new self(); + if ($cid) $model->where("`cid` LIKE '$cid,%' OR `cid` LIKE '%,$cid,%' OR `cid` LIKE '%,$cid' OR `cid`=$cid "); + $model = $model->field($field); + $model = $model->where('status', 1); + $model = $model->where('hide', 0); + $model = $model->order('sort DESC,add_time DESC'); + if($limit) $model = $model->limit($first, $limit); + return $model->select(); + } + + /** + * 获取热门文章 + * @param string $field + * @return mixed + */ + public static function getArticleListHot($field = 'id,title,image_input,visit,add_time,synopsis,url'){ + $model = new self(); + $model = $model->field($field); + $model = $model->where('status', 1); + $model = $model->where('hide', 0); + $model = $model->where('is_hot', 1); + $model = $model->order('sort DESC,add_time DESC'); + return $model->select(); + } + + /** + * 获取轮播文章 + * @param string $field + * @return mixed + */ + public static function getArticleListBanner($field = 'id,title,image_input,visit,add_time,synopsis,url'){ + $model = new self(); + $model = $model->field($field); + $model = $model->where('status', 1); + $model = $model->where('hide', 0); + $model = $model->where('is_banner', 1); + $model = $model->order('sort DESC,add_time DESC'); + return $model->select(); + } +} diff --git a/application/ebapi/model/article/ArticleCategory.php b/application/ebapi/model/article/ArticleCategory.php new file mode 100644 index 00000000..8d309802 --- /dev/null +++ b/application/ebapi/model/article/ArticleCategory.php @@ -0,0 +1,39 @@ +where('is_del',0)->where('status',1)->where('pid',0)->order('sort DESC')->field('id,title')->select(); + } + + /** + * TODO 获取分类字段 + * @param $id $id 编号 + * @param string $field $field 字段 + * @return mixed|string + */ + public static function getArticleCategoryField($id,$field = 'title'){ + if(!$id) return ''; + return self::where('id',$id)->value($field); + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreCart.php b/application/ebapi/model/store/StoreCart.php new file mode 100644 index 00000000..f89dabdc --- /dev/null +++ b/application/ebapi/model/store/StoreCart.php @@ -0,0 +1,255 @@ + + * @day: 2017/12/18 + */ + +namespace app\ebapi\model\store; + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCart extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function setCart($uid,$product_id,$cart_num = 1,$product_attr_unique = '',$type='product',$is_new = 0,$combination_id=0,$seckill_id = 0,$bargain_id = 0) + { + if($cart_num < 1) $cart_num = 1; + if($seckill_id){ + $StoreSeckillinfo = StoreSeckill::getValidProduct($seckill_id); + if(!$StoreSeckillinfo) + return self::setErrorInfo('该产品已下架或删除'); + $userbuycount = StoreOrder::where(['uid'=>$uid,'paid'=>1,'seckill_id'=>$seckill_id])->count(); + if($StoreSeckillinfo['num'] <= $userbuycount || $StoreSeckillinfo['num'] < $cart_num) + return self::setErrorInfo('每人限购'.$StoreSeckillinfo['num'].'件'); + if(StoreSeckill::getProductStock($seckill_id) < $cart_num) + return self::setErrorInfo('该产品库存不足'.$cart_num); + $where = ['type'=>$type,'uid'=>$uid,'product_id'=>$product_id,'product_attr_unique'=>$product_attr_unique,'is_new'=>$is_new,'is_pay'=>0,'is_del'=>0,'seckill_id'=>$seckill_id]; + if($cart = self::where($where)->find()){ + $cart->cart_num = $cart_num; + $cart->add_time = time(); + $cart->save(); + return $cart; + }else{ + return self::set(compact('uid','product_id','cart_num','product_attr_unique','is_new','type','seckill_id')); + } + }elseif($bargain_id){ + if(!StoreBargain::validBargain($bargain_id)) + return self::setErrorInfo('该产品已下架或删除'); + if(StoreBargain::getBargainStock($bargain_id) < $cart_num) + return self::setErrorInfo('该产品库存不足'.$cart_num); + $where = ['type'=>$type,'uid'=>$uid,'product_id'=>$product_id,'product_attr_unique'=>$product_attr_unique,'is_new'=>$is_new,'is_pay'=>0,'is_del'=>0,'bargain_id'=>$bargain_id]; + if($cart = self::where($where)->find()){ + $cart->cart_num = $cart_num; + $cart->add_time = time(); + $cart->save(); + return $cart; + }else{ + return self::set(compact('uid','product_id','cart_num','product_attr_unique','is_new','type','bargain_id')); + } + }elseif($combination_id){//拼团 + if(!StoreCombination::getCombinationStock($combination_id,$cart_num)) + return self::setErrorInfo('该产品库存不足'.$cart_num); + if(!StoreCombination::isValidCombination($combination_id)) + return self::setErrorInfo('该产品已下架或删除'); + }else{ + if(!StoreProduct::isValidProduct($product_id)) + return self::setErrorInfo('该产品已下架或删除'); + if(!StoreProductAttr::issetProductUnique($product_id,$product_attr_unique)) + return self::setErrorInfo('请选择有效的产品属性'); + if(StoreProduct::getProductStock($product_id,$product_attr_unique) < $cart_num) + return self::setErrorInfo('该产品库存不足'.$cart_num); + } + $where = ['type'=>$type,'uid'=>$uid,'product_id'=>$product_id,'product_attr_unique'=>$product_attr_unique,'is_new'=>$is_new,'is_pay'=>0,'is_del'=>0,'combination_id'=>$combination_id]; + if($cart = self::where($where)->find()){ + $cart->cart_num = $cart_num; + $cart->add_time = time(); + $cart->save(); + return $cart; + }else{ + return self::set(compact('uid','product_id','cart_num','product_attr_unique','is_new','type','combination_id')); + } + + } + + public static function removeUserCart($uid,$ids) + { + return self::where('uid',$uid)->where('id','IN',$ids)->update(['is_del'=>1]); + } + + public static function getUserCartNum($uid,$type) + { + return self::where('uid',$uid)->where('type',$type)->where('is_pay',0)->where('is_del',0)->where('is_new',0)->count(); + } + + /** + * TODO 修改购物车库存 + * @param $cartId + * @param $cartNum + * @param $uid + * @return StoreCart|bool + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function changeUserCartNum($cartId,$cartNum,$uid) + { + $count = self::where('uid',$uid)->where('id',$cartId)->count(); + if(!$count) return self::setErrorInfo('参数错误'); + $cartInfo = self::where('uid',$uid)->where('id',$cartId)->field('product_id,combination_id,seckill_id,bargain_id,product_attr_unique')->find()->toArray(); + $stock = 0; + if($cartInfo['bargain_id']){ + //TODO 获取砍价产品的库存 + $stock = 0; + }else if($cartInfo['seckill_id']){ + //TODO 获取秒杀产品的库存 + $stock = 0; + }else if($cartInfo['combination_id']){ + //TODO 获取拼团产品的库存 + $stock = 0; + }else if($cartInfo['product_id']){ + //TODO 获取普通产品的库存 + $stock = StoreProduct::getProductStock($cartInfo['product_id'],$cartInfo['product_attr_unique']); + } + if(!$stock) return self::setErrorInfo('暂无库存'); + if(!$cartNum) return self::setErrorInfo('库存错误'); + if($stock < $cartNum) return self::setErrorInfo('库存不足'.$cartNum); + return self::where('uid',$uid)->where('id',$cartId)->update(['cart_num'=>$cartNum]); + } + + public static function getUserProductCartList($uid,$cartIds='',$status=0) + { + $productInfoField = 'id,image,slider_image,price,ot_price,vip_price,postage,mer_id,give_integral,cate_id,sales,stock,store_name,store_info,unit_name,is_show,is_del,is_postage,cost'; + $seckillInfoField = 'id,image,price,ot_price,postage,give_integral,sales,stock,title as store_name,unit_name,is_show,is_del,is_postage,cost'; + $bargainInfoField = 'id,image,min_price as price,price as ot_price,postage,give_integral,sales,stock,title as store_name,unit_name,status as is_show,is_del,is_postage,cost'; + $combinationInfoField = 'id,image,price,postage,sales,stock,title as store_name,is_show,is_del,is_postage,cost'; + $model = new self(); + $valid = $invalid = []; + $model = $model->where('uid',$uid)->where('type','product')->where('is_pay',0) + ->where('is_del',0); + if(!$status) $model->where('is_new',0); + if($cartIds) $model->where('id','IN',$cartIds); + $list = $model->select()->toArray(); + if(!count($list)) return compact('valid','invalid'); + foreach ($list as $k=>$cart){ + if($cart['seckill_id']){ + $product = StoreSeckill::field($seckillInfoField) + ->find($cart['seckill_id'])->toArray(); + }elseif($cart['bargain_id']){ + $product = StoreBargain::field($bargainInfoField) + ->find($cart['bargain_id'])->toArray(); + }elseif($cart['combination_id']){ + $product = StoreCombination::field($combinationInfoField) + ->find($cart['combination_id'])->toArray(); + }else{ + $product = StoreProduct::field($productInfoField) + ->find($cart['product_id'])->toArray(); + } + $cart['productInfo'] = $product; + //商品不存在 + if(!$product){ + $model->where('id',$cart['id'])->update(['is_del'=>1]); + //商品删除或无库存 + }else if(!$product['is_show'] || $product['is_del'] || !$product['stock']){ + $invalid[] = $cart; + //商品属性不对应 + }else if(!StoreProductAttr::issetProductUnique($cart['product_id'],$cart['product_attr_unique']) && !$cart['combination_id'] && !$cart['seckill_id']&& !$cart['bargain_id']){ + $invalid[] = $cart; + //正常商品 + }else{ + if($cart['product_attr_unique']){ + $attrInfo = StoreProductAttr::uniqueByAttrInfo($cart['product_attr_unique']); + //商品没有对应的属性 + if(!$attrInfo || !$attrInfo['stock']) + $invalid[] = $cart; + else{ + $cart['productInfo']['attrInfo'] = $attrInfo; + $cart['truePrice'] = (float)StoreProduct::setLevelPrice($attrInfo['price'],$uid,true); + $cart['vip_truePrice'] = (float)StoreProduct::setLevelPrice($attrInfo['price'],$uid); + $cart['trueStock'] = $attrInfo['stock']; + $cart['costPrice'] = $attrInfo['cost']; + $cart['productInfo']['image'] = empty($attrInfo['image']) ? $cart['productInfo']['image'] : $attrInfo['image']; + $valid[] = $cart; + } + }else{ + $cart['truePrice'] = (float)StoreProduct::setLevelPrice($cart['productInfo']['price'],$uid,true); + $cart['vip_truePrice'] = (float)StoreProduct::setLevelPrice($cart['productInfo']['price'],$uid); + $cart['trueStock'] = $cart['productInfo']['stock']; + $cart['costPrice'] = $cart['productInfo']['cost']; + $valid[] = $cart; + } + } + } + + foreach ($valid as $k=>$cart){ + if($cart['trueStock'] < $cart['cart_num']){ + $cart['cart_num'] = $cart['trueStock']; + $model->where('id',$cart['id'])->update(['cart_num'=>$cart['cart_num']]); + $valid[$k] = $cart; + } + } + + return compact('valid','invalid'); + } + + /** + * 拼团 + * @param $uid + * @param string $cartIds + * @return array + */ + public static function getUserCombinationProductCartList($uid,$cartIds='') + { + $productInfoField = 'id,image,slider_image,price,cost,ot_price,vip_price,postage,mer_id,give_integral,cate_id,sales,stock,store_name,unit_name,is_show,is_del,is_postage'; + $model = new self(); + $valid = $invalid = []; + $model = $model->where('uid',$uid)->where('type','product')->where('is_pay',0) + ->where('is_del',0); + if($cartIds) $model->where('id','IN',$cartIds); + $list = $model->select()->toArray(); + if(!count($list)) return compact('valid','invalid'); + foreach ($list as $k=>$cart){ + $product = StoreProduct::field($productInfoField) + ->find($cart['product_id'])->toArray(); + $cart['productInfo'] = $product; + //商品不存在 + if(!$product){ + $model->where('id',$cart['id'])->update(['is_del'=>1]); + //商品删除或无库存 + }else if(!$product['is_show'] || $product['is_del'] || !$product['stock']){ + $invalid[] = $cart; + //商品属性不对应 +// }else if(!StoreProductAttr::issetProductUnique($cart['product_id'],$cart['product_attr_unique'])){ +// $invalid[] = $cart; + //正常商品 + }else{ + $cart['truePrice'] = (float)StoreCombination::where('id',$cart['combination_id'])->value('price'); + $cart['costPrice'] = (float)StoreCombination::where('id',$cart['combination_id'])->value('cost'); + $cart['trueStock'] = StoreCombination::where('id',$cart['combination_id'])->value('stock'); + $valid[] = $cart; + } + } + + foreach ($valid as $k=>$cart){ + if($cart['trueStock'] < $cart['cart_num']){ + $cart['cart_num'] = $cart['trueStock']; + $model->where('id',$cart['id'])->update(['cart_num'=>$cart['cart_num']]); + $valid[$k] = $cart; + } + } + + return compact('valid','invalid'); + } + + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreCategory.php b/application/ebapi/model/store/StoreCategory.php new file mode 100644 index 00000000..4f975bb5 --- /dev/null +++ b/application/ebapi/model/store/StoreCategory.php @@ -0,0 +1,65 @@ + + * @day: 2017/12/12 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use think\Cache; + +class StoreCategory extends ModelBasic +{ + public static function pidByCategory($pid,$field = '*',$limit = 0) + { + $model = self::where('pid',$pid)->where('is_show',1)->order('sort desc,id desc')->field($field); + if($limit) $model->limit($limit); + return $model->select(); + } + + public static function pidBySidList($pid) + { + return self::where('pid',$pid)->field('id,cate_name,pid')->select(); + } + + public static function cateIdByPid($cateId) + { + return self::where('id',$cateId)->value('pid'); + } + + /* + * 获取一级和二级分类 + * @return array + * */ + public static function getProductCategory($expire=800) + { + if(Cache::has('parent_category')){ + return Cache::get('parent_category'); + }else { + $parentCategory = self::pidByCategory(0, 'id,cate_name')->toArray(); + foreach ($parentCategory as $k => $category) { + $category['child'] = self::pidByCategory($category['id'], 'id,cate_name,pic')->toArray(); + $parentCategory[$k] = $category; + } + Cache::set('parent_category',$parentCategory,$expire); + return $parentCategory; + } + } + + /** + * TODO 获取首页展示的二级分类 排序默认降序 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function byIndexList($limit = 4,$field = 'id,cate_name,pid,pic'){ + return self::where('pid','>',0)->where('is_show',1)->field($field)->order('sort DESC')->limit($limit)->select(); + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreCoupon.php b/application/ebapi/model/store/StoreCoupon.php new file mode 100644 index 00000000..638fb810 --- /dev/null +++ b/application/ebapi/model/store/StoreCoupon.php @@ -0,0 +1,17 @@ + + * @day: 2018/01/22 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCoupon extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreCouponIssue.php b/application/ebapi/model/store/StoreCouponIssue.php new file mode 100644 index 00000000..9abd82e7 --- /dev/null +++ b/application/ebapi/model/store/StoreCouponIssue.php @@ -0,0 +1,78 @@ + + * @day: 2018/01/18 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponIssue extends ModelBasic +{ + use ModelTrait; + + public static function getIssueCouponList($uid,$limit,$page=0) + { + $model = self::validWhere('A')->join('__STORE_COUPON__ B','A.cid = B.id') + ->field('A.*,B.coupon_price,B.use_min_price')->order('B.sort DESC,A.id DESC'); + if($page) $list=$model->page((int)$page,(int)$limit)->select()->toArray()?:[]; + else $list=$model->limit($limit)->select()->toArray()?:[]; + foreach ($list as &$v){ + $v['is_use'] = StoreCouponIssueUser::be(['uid'=>$uid,'issue_coupon_id'=>$v['id']]); + if(!$v['is_use']){ + $v['is_use']=$v['remain_count'] <= 0 && !$v['is_permanent'] ? 2 : $v['is_use']; + } + $v['add_time']=date('Y/m/d',$v['add_time']); + $v['end_time']=$v['end_time'] ? date('Y/m/d',$v['end_time']) : date('Y/m/d',time()+86400); + $v['coupon_price']=(int)$v['coupon_price']; + } + return $list; + } + /** + * @param string $prefix + * @return $this + */ + public static function validWhere($prefix = '') + { + $model = new self; + if($prefix){ + $model->alias($prefix); + $prefix .= '.'; + } + $newTime = time(); + return $model->where("{$prefix}status",1) + ->where(function($query) use($newTime,$prefix){ + $query->where(function($query) use($newTime,$prefix){ + $query->where("{$prefix}start_time",'<',$newTime)->where("{$prefix}end_time",'>',$newTime); + })->whereOr(function ($query) use($prefix){ + $query->where("{$prefix}start_time",0)->where("{$prefix}end_time",0); + }); + })->where("{$prefix}is_del",0); + } + + + public static function issueUserCoupon($id,$uid) + { + $issueCouponInfo = self::validWhere()->where('id',$id)->find(); + if(!$issueCouponInfo) return self::setErrorInfo('领取的优惠劵已领完或已过期!'); + if(StoreCouponIssueUser::be(['uid'=>$uid,'issue_coupon_id'=>$id])) + return self::setErrorInfo('已领取过该优惠劵!'); + if($issueCouponInfo['remain_count'] <= 0 && !$issueCouponInfo['is_permanent']) return self::setErrorInfo('抱歉优惠卷已经领取完了!'); + self::beginTrans(); + $res1 = false != StoreCouponUser::addUserCoupon($uid,$issueCouponInfo['cid']); + $res2 = false != StoreCouponIssueUser::addUserIssue($uid,$id); + $res3 = true; + if($issueCouponInfo['total_count'] > 0){ + $issueCouponInfo['remain_count'] -= 1; + $res3 = false !== $issueCouponInfo->save(); + } + $res = $res1 && $res2 && $res3; + self::checkTrans($res); + return $res; + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreCouponIssueUser.php b/application/ebapi/model/store/StoreCouponIssueUser.php new file mode 100644 index 00000000..4e787b4e --- /dev/null +++ b/application/ebapi/model/store/StoreCouponIssueUser.php @@ -0,0 +1,22 @@ + + * @day: 2018/01/22 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponIssueUser extends ModelBasic +{ + use ModelTrait; + public static function addUserIssue($uid,$issue_coupon_id) + { + $add_time = time(); + return self::set(compact('uid','issue_coupon_id','add_time')); + } +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreCouponUser.php b/application/ebapi/model/store/StoreCouponUser.php new file mode 100644 index 00000000..ce28d9b3 --- /dev/null +++ b/application/ebapi/model/store/StoreCouponUser.php @@ -0,0 +1,152 @@ + + * @day: 2017/12/20 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponUser extends ModelBasic +{ + use ModelTrait; + /** + * 获取用户优惠券(全部) + * @return \think\response\Json + */ + public static function getUserAllCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + /** + * 获取用户优惠券(未使用) + * @return \think\response\Json + */ + public static function getUserValidCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->where('status',0)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + /** + * 获取用户优惠券(已使用) + * @return \think\response\Json + */ + public static function getUserAlreadyUsedCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->where('status',1)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + /** + * 获取用户优惠券(已过期) + * @return \think\response\Json + */ + public static function getUserBeOverdueCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->where('status',2)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + public static function beUsableCoupon($uid,$price) + { + return self::where('uid',$uid)->where('is_fail',0)->where('status',0)->where('use_min_price','<=',$price)->find(); + } + + /** + * 获取用户可以使用的优惠券 + * @param $uid + * @param $price + * @return false|\PDOStatement|string|\think\Collection + */ + public static function beUsableCouponList($uid,$price=0){ + $list=self::where('uid',$uid)->where('is_fail',0)->where('status',0)->where('use_min_price','<=',$price)->select(); + $list=count($list) ? $list->toArray() : []; + foreach ($list as &$item){ + $item['add_time']=date('Y/m/d',$item['add_time']); + $item['end_time']=date('Y/m/d',$item['end_time']); + } + return $list; + } + + public static function validAddressWhere($model=null,$prefix = '') + { + self::checkInvalidCoupon(); + if($prefix) $prefix .='.'; + $model = self::getSelfModel($model); + return $model->where("{$prefix}is_fail",0)->where("{$prefix}status",0); + } + + public static function checkInvalidCoupon() + { + self::where('end_time','<',time())->where('status',0)->update(['status'=>2]); + } + + public static function tidyCouponList($couponList) + { + $time = time(); + foreach ($couponList as $k=>$coupon){ + $coupon['_add_time'] = date('Y/m/d',$coupon['add_time']); + $coupon['_end_time'] = date('Y/m/d',$coupon['end_time']); + $coupon['use_min_price'] = number_format($coupon['use_min_price'],2); + $coupon['coupon_price'] = number_format($coupon['coupon_price'],2); + if($coupon['is_fail']){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已失效'; + }else if ($coupon['status'] == 1){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已使用'; + }else if ($coupon['status'] == 2){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已过期'; + }else if($coupon['add_time'] > $time || $coupon['end_time'] < $time){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已过期'; + }else{ + if($coupon['add_time']+ 3600*24 > $time){ + $coupon['_type'] = 2; + $coupon['_msg'] = '可使用'; + }else{ + $coupon['_type'] = 1; + $coupon['_msg'] = '可使用'; + } + } + $couponList[$k] = $coupon; + } + return $couponList; + } + + public static function getUserValidCouponCount($uid) + { + self::checkInvalidCoupon(); + return self::where('uid',$uid)->where('status',0)->order('is_fail ASC,status ASC,add_time DESC')->count(); + } + + public static function useCoupon($id) + { + return self::where('id',$id)->update(['status'=>1,'use_time'=>time()]); + } + + public static function addUserCoupon($uid,$cid,$type = 'get') + { + $couponInfo = StoreCoupon::find($cid); + if(!$couponInfo) return self::setErrorInfo('优惠劵不存在!'); + $data = []; + $data['cid'] = $couponInfo['id']; + $data['uid'] = $uid; + $data['coupon_title'] = $couponInfo['title']; + $data['coupon_price'] = $couponInfo['coupon_price']; + $data['use_min_price'] = $couponInfo['use_min_price']; + $data['add_time'] = time(); + $data['end_time'] = $data['add_time']+$couponInfo['coupon_time']*86400; + $data['type'] = $type; + return self::set($data); + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreOrder.php b/application/ebapi/model/store/StoreOrder.php new file mode 100644 index 00000000..da67ff05 --- /dev/null +++ b/application/ebapi/model/store/StoreOrder.php @@ -0,0 +1,944 @@ + + * @day: 2017/12/20 + */ + +namespace app\ebapi\model\store; + +use app\core\model\routine\RoutineTemplate; +use app\ebapi\model\user\User; +use app\ebapi\model\user\UserAddress; +use app\core\model\user\UserBill; +use app\ebapi\model\user\WechatUser; +use basic\ModelBasic; +use app\core\behavior\OrderBehavior; +use app\core\behavior\GoodsBehavior; +use app\core\behavior\UserBehavior; +use app\core\behavior\PaymentBehavior; +use service\HookService; +use app\core\util\MiniProgramService; +use app\core\util\SystemConfigService; +use think\Cache; +use traits\ModelTrait; + +class StoreOrder extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected static $payType = ['weixin'=>'微信支付','yue'=>'余额支付','offline'=>'线下支付']; + + protected static $deliveryType = ['send'=>'商家配送','express'=>'快递配送']; + + protected function setAddTimeAttr() + { + return time(); + } + + protected function setCartIdAttr($value) + { + return is_array($value) ? json_encode($value) : $value; + } + + protected function getCartIdAttr($value) + { + return json_decode($value,true); + } + + /**获取订单组信息 + * @param $cartInfo + * @return array + */ + public static function getOrderPriceGroup($cartInfo) + { + $storePostage = floatval(SystemConfigService::get('store_postage'))?:0;//邮费基础价 + $storeFreePostage = floatval(SystemConfigService::get('store_free_postage'))?:0;//满额包邮 + $totalPrice = self::getOrderSumPrice($cartInfo,'truePrice');//获取订单总金额 + $costPrice = self::getOrderSumPrice($cartInfo,'costPrice');//获取订单成本价 + $vipPrice = self::getOrderSumPrice($cartInfo,'vip_truePrice');//获取订单会员优惠金额 + //如果满额包邮等于0 + if(!$storeFreePostage) { + $storePostage = 0; + }else{ + foreach ($cartInfo as $cart){ + if(!$cart['productInfo']['is_postage'])//若果产品不包邮 + $storePostage = bcadd($storePostage,$cart['productInfo']['postage'],2); + + } + if($storeFreePostage <= $totalPrice) $storePostage = 0;//如果总价大于等于满额包邮 邮费等于0 + } +// $totalPrice = bcadd($totalPrice,$storePostage,2); + return compact('storePostage','storeFreePostage','totalPrice','costPrice','vipPrice'); + } + + /**获取某个字段总金额 + * @param $cartInfo + * @param $key 键名 + * @return int|string + */ + public static function getOrderSumPrice($cartInfo,$key='truePrice') + { + $SumPrice = 0; + foreach ($cartInfo as $cart){ + $SumPrice = bcadd($SumPrice,bcmul($cart['cart_num'],$cart[$key],2),2); + } + return $SumPrice; + } + + + /** + * 拼团 + * @param $cartInfo + * @return array + */ + public static function getCombinationOrderPriceGroup($cartInfo) + { + $storePostage = floatval(SystemConfigService::get('store_postage'))?:0; + $storeFreePostage = floatval(SystemConfigService::get('store_free_postage'))?:0; + $totalPrice = self::getCombinationOrderTotalPrice($cartInfo); + $costPrice = self::getCombinationOrderTotalPrice($cartInfo); + if(!$storeFreePostage) { + $storePostage = 0; + }else{ + foreach ($cartInfo as $cart){ + if(!StoreCombination::where('id',$cart['combination_id'])->value('is_postage')) + $storePostage = bcadd($storePostage,StoreCombination::where('id',$cart['combination_id'])->value('postage'),2); + } + if($storeFreePostage <= $totalPrice) $storePostage = 0; + } + return compact('storePostage','storeFreePostage','totalPrice','costPrice'); + } + + /** + * 拼团价格 + * @param $cartInfo + * @return float + */ + public static function getCombinationOrderTotalPrice($cartInfo) + { + $totalPrice = 0; + foreach ($cartInfo as $cart){ + if($cart['combination_id']){ + $totalPrice = bcadd($totalPrice,bcmul($cart['cart_num'],StoreCombination::where('id',$cart['combination_id'])->value('price'),2),2); + } + } + return (float)$totalPrice; + } + + public static function cacheOrderInfo($uid,$cartInfo,$priceGroup,$other = [],$cacheTime = 600) + { + $key = md5(time()); + Cache::set('user_order_'.$uid.$key,compact('cartInfo','priceGroup','other'),$cacheTime); + return $key; + } + + public static function getCacheOrderInfo($uid,$key) + { + $cacheName = 'user_order_'.$uid.$key; + if(!Cache::has($cacheName)) return null; + return Cache::get($cacheName); + } + + public static function clearCacheOrderInfo($uid,$key) + { + Cache::clear('user_order_'.$uid.$key); + } + + /**生成订单 + * @param $uid + * @param $key + * @param $addressId + * @param $payType + * @param bool $useIntegral + * @param int $couponId + * @param string $mark + * @param int $combinationId + * @param int $pinkId + * @param int $seckill_id + * @param int $bargain_id + * @return bool|object + */ + public static function cacheKeyCreateOrder($uid,$key,$addressId,$payType,$useIntegral = false,$couponId = 0,$mark = '',$combinationId = 0,$pinkId = 0,$seckill_id=0,$bargain_id=0) + { + if(!array_key_exists($payType,self::$payType)) return self::setErrorInfo('选择支付方式有误!'); + if(self::be(['unique'=>$key,'uid'=>$uid])) return self::setErrorInfo('请勿重复提交订单'); + $userInfo = User::getUserInfo($uid); + if(!$userInfo) return self::setErrorInfo('用户不存在!'); + $cartGroup = self::getCacheOrderInfo($uid,$key); + if(!$cartGroup) return self::setErrorInfo('订单已过期,请刷新当前页面!'); + $cartInfo = $cartGroup['cartInfo']; + $priceGroup = $cartGroup['priceGroup']; + $other = $cartGroup['other']; + $payPrice = (float)$priceGroup['totalPrice']; + $payPostage = $priceGroup['storePostage']; + if(!$addressId) return self::setErrorInfo('请选择收货地址!'); + if(!UserAddress::be(['uid'=>$uid,'id'=>$addressId,'is_del'=>0]) || !($addressInfo = UserAddress::find($addressId))) + return self::setErrorInfo('地址选择有误!'); + + //使用优惠劵 + $res1 = true; + if($couponId){ + $couponInfo = StoreCouponUser::validAddressWhere()->where('id',$couponId)->where('uid',$uid)->find(); + if(!$couponInfo) return self::setErrorInfo('选择的优惠劵无效!'); + if($couponInfo['use_min_price'] > $payPrice) + return self::setErrorInfo('不满足优惠劵的使用条件!'); + $payPrice = (float)bcsub($payPrice,$couponInfo['coupon_price'],2); + $res1 = StoreCouponUser::useCoupon($couponId); + $couponPrice = $couponInfo['coupon_price']; + }else{ + $couponId = 0; + $couponPrice = 0; + } + if(!$res1) return self::setErrorInfo('使用优惠劵失败!'); + + //是否包邮 + if((isset($other['offlinePostage']) && $other['offlinePostage'] && $payType == 'offline')) $payPostage = 0; + $payPrice = (float)bcadd($payPrice,$payPostage,2); + + //积分抵扣 + $res2 = true; + if($useIntegral && $userInfo['integral'] > 0){ + $deductionPrice = (float)bcmul($userInfo['integral'],$other['integralRatio'],2); + if($deductionPrice < $payPrice){ + $payPrice = bcsub($payPrice,$deductionPrice,2); + $usedIntegral = $userInfo['integral']; + $res2 = false !== User::edit(['integral'=>0],$userInfo['uid'],'uid'); + }else{ + $deductionPrice = $payPrice; + $usedIntegral = (float)bcdiv($payPrice,$other['integralRatio'],2); + $res2 = false !== User::bcDec($userInfo['uid'],'integral',$usedIntegral,'uid'); + $payPrice = 0; + } + $res2 = $res2 && false != UserBill::expend('积分抵扣',$uid,'integral','deduction',$usedIntegral,$key,$userInfo['integral'],'购买商品使用'.floatval($usedIntegral).'积分抵扣'.floatval($deductionPrice).'元'); + }else{ + $deductionPrice = 0; + $usedIntegral = 0; + } + if(!$res2) return self::setErrorInfo('使用积分抵扣失败!'); + + $cartIds = []; + $totalNum = 0; + $gainIntegral = 0; + foreach ($cartInfo as $cart){ + $cartIds[] = $cart['id']; + $totalNum += $cart['cart_num']; + $gainIntegral = bcadd($gainIntegral,isset($cart['productInfo']['give_integral']) ? $cart['productInfo']['give_integral'] : 0,2); + } + $orderInfo = [ + 'uid'=>$uid, + 'order_id'=>self::getNewOrderId(), + 'real_name'=>$addressInfo['real_name'], + 'user_phone'=>$addressInfo['phone'], + 'user_address'=>$addressInfo['province'].' '.$addressInfo['city'].' '.$addressInfo['district'].' '.$addressInfo['detail'], + 'cart_id'=>$cartIds, + 'total_num'=>$totalNum, + 'total_price'=>$priceGroup['totalPrice'], + 'total_postage'=>$priceGroup['storePostage'], + 'coupon_id'=>$couponId, + 'coupon_price'=>$couponPrice, + 'pay_price'=>$payPrice, + 'pay_postage'=>$payPostage, + 'deduction_price'=>$deductionPrice, + 'paid'=>0, + 'pay_type'=>$payType, + 'use_integral'=>$usedIntegral, + 'gain_integral'=>$gainIntegral, + 'mark'=>htmlspecialchars($mark), + 'combination_id'=>$combinationId, + 'pink_id'=>$pinkId, + 'seckill_id'=>$seckill_id, + 'bargain_id'=>$bargain_id, + 'cost'=>$priceGroup['costPrice'], + 'is_channel'=>1, + 'unique'=>$key + ]; + $order = self::set($orderInfo); + if(!$order)return self::setErrorInfo('订单生成失败!'); + $res5 = true; + //保存购物车商品信息 + $res4 = false !== StoreOrderCartInfo::setCartInfo($order['id'],$cartInfo); + //购物车状态修改 + $res6 = false !== StoreCart::where('id','IN',$cartIds)->update(['is_pay'=>1]); + if(!$res4 || !$res5 || !$res6) return self::setErrorInfo('订单生成失败!'); + try{ + HookService::listen('store_product_order_create',$order,compact('cartInfo','addressId'),false,GoodsBehavior::class); + }catch (\Exception $e){ + return self::setErrorInfo($e->getMessage()); + } + self::clearCacheOrderInfo($uid,$key); + self::commitTrans(); + StoreOrderStatus::status($order['id'],'cache_key_create_order','订单生成'); + return $order; + } + + /* + * 回退积分 + * @param array $order 订单信息 + * @return boolean + * */ + public static function RegressionIntegral($order) + { + if($order['paid'] || $order['status']==-2 || $order['is_del']) return false; + if($order['use_integral'] < 0) return true; + if((int)$order['status']!=-2 && (int)$order['refund_status']!=2 && $order['back_integral'] >= $order['use_integral']) + return self::setErrorInfo('已退积分或该状态无法回退积分'); + $res=User::bcInc($order['uid'],'integral',$order['use_integral']); + if(!$res) return self::setErrorInfo('回退积分增加失败'); + UserBill::income('积分回退',$order['uid'],'integral','deduction',$order['use_integral'],$order['unique'],User::where('uid',$order['uid'])->value('integral'),'购买商品失败,回退积分'.floatval($order['use_integral'])); + return self::where('order_id',$order['order_id'])->update(['back_integral'=>$order['use_integral']]); + } + + /* + * 回退库存和销量 + * @param array $order 订单信息 + * @return boolean + * */ + public static function RegressionStock($order) + { + if($order['paid'] || $order['status']==-2 || $order['is_del']) return false; + $combinationId=$order['combination_id']; + $seckill_id=$order['seckill_id']; + $bargain_id=$order['bargain_id']; + $res5=true; + $cartInfo=StoreOrderCartInfo::where('cart_id','in',$order['cart_id'])->select(); + foreach ($cartInfo as $cart) + { + //增库存减销量 + if($combinationId) $res5 = $res5 && StoreCombination::incCombinationStock($cart['cart_info']['cart_num'],$combinationId); + else if($seckill_id) $res5 = $res5 && StoreSeckill::incSeckillStock($cart['cart_info']['cart_num'],$seckill_id); + else if($bargain_id) $res5 = $res5 && StoreBargain::incBargainStock($cart['cart_info']['cart_num'],$bargain_id); + else $res5 = $res5 && StoreProduct::incProductStock($cart['cart_info']['cart_num'],$cart['cart_info']['productInfo']['id'],isset($cart['cart_info']['productInfo']['attrInfo']) ? $cart['cart_info']['productInfo']['attrInfo']['unique']:''); + } + return $res5; + } + + /* + * 回退优惠卷 + * @param array $order 订单信息 + * @return boolean + * */ + public static function RegressionCoupon($order) + { + if($order['paid'] || $order['status']==-2 || $order['is_del']) return false; + $res=true; + if($order['coupon_id'] && StoreCouponUser::be(['id'=>$order['coupon_id'],'uid'=>$order['uid'],'status'=>1])){ + $res= $res && StoreCouponUser::where(['id'=>$order['coupon_id'],'uid'=>$order['uid']])->update(['status'=>0,'use_time'=>0]); + } + return $res; + } + + /* + * 取消订单 + * @param string order_id 订单id + * */ + public static function cancelOrder($order_id) + { + $order=self::where('order_id',$order_id)->find(); + if(!$order) return self::setErrorInfo('没有查到此订单'); + self::beginTrans(); + try{ + $res=self::RegressionIntegral($order) && self::RegressionCoupon($order); + if($res){ + $order->is_del=1; + self::commitTrans(); + return $order->save(); + } + }catch (\Exception $e){ + self::rollbackTrans(); + return self::setErrorInfo(['line'=>$e->getLine(),'message'=>$e->getMessage()]); + } + } + + public static function getNewOrderId() + { + $count = (int) self::where('add_time',['>=',strtotime(date("Y-m-d"))],['<',strtotime(date("Y-m-d",strtotime('+1 day')))])->count(); + return 'wx'.date('YmdHis',time()).(10000+$count+1); + } + + public static function changeOrderId($orderId) + { + $ymd = substr($orderId,2,8); + $key = substr($orderId,16); + return 'wx'.$ymd.date('His').$key; + } + //TODO JS支付 + public static function jsPay($orderId,$field = 'order_id') + { + if(is_string($orderId)) + $orderInfo = self::where($field,$orderId)->find(); + else + $orderInfo = $orderId; + if(!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!'); + if($orderInfo['paid']) exception('支付已支付!'); + if($orderInfo['pay_price'] <= 0) exception('该支付无需支付!'); + $openid = WechatUser::getOpenId($orderInfo['uid']); + return MiniProgramService::jsPay($openid,$orderInfo['order_id'],$orderInfo['pay_price'],'productr',SystemConfigService::get('site_name')); + } + //TODO 余额支付 + public static function yuePay($order_id,$uid,$formId = '') + { + $orderInfo = self::where('uid',$uid)->where('order_id',$order_id)->where('is_del',0)->find(); + if(!$orderInfo) return self::setErrorInfo('订单不存在!'); + if($orderInfo['paid']) return self::setErrorInfo('该订单已支付!'); +// if($orderInfo['pay_type'] != 'yue') return self::setErrorInfo('该订单不能使用余额支付!'); + $userInfo = User::getUserInfo($uid); + if($userInfo['now_money'] < $orderInfo['pay_price']) + return self::setErrorInfo(['status'=>'pay_deficiency','msg'=>'余额不足'.floatval($orderInfo['pay_price'])]); + self::beginTrans(); + + $res1 = false !== User::bcDec($uid,'now_money',$orderInfo['pay_price'],'uid'); + $res2 = UserBill::expend('购买商品',$uid,'now_money','pay_product',$orderInfo['pay_price'],$orderInfo['id'],$userInfo['now_money'],'余额支付'.floatval($orderInfo['pay_price']).'元购买商品'); + $res3 = self::paySuccess($order_id,'yue',$formId);//余额支付成功 + try{ + HookService::listen('yue_pay_product',$userInfo,$orderInfo,false,PaymentBehavior::class); + }catch (\Exception $e){ + self::rollbackTrans(); + return self::setErrorInfo($e->getMessage()); + } + $res = $res1 && $res2 && $res3; + self::checkTrans($res); + return $res; + } + + /** + * 微信支付 为 0元时 + * @param $order_id + * @param $uid + * @return bool + */ + public static function jsPayPrice($order_id,$uid,$formId = ''){ + $orderInfo = self::where('uid',$uid)->where('order_id',$order_id)->where('is_del',0)->find(); + if(!$orderInfo) return self::setErrorInfo('订单不存在!'); + if($orderInfo['paid']) return self::setErrorInfo('该订单已支付!'); + $userInfo = User::getUserInfo($uid); + self::beginTrans(); + $res1 = UserBill::expend('购买商品',$uid,'now_money','pay_product',$orderInfo['pay_price'],$orderInfo['id'],$userInfo['now_money'],'微信支付'.floatval($orderInfo['pay_price']).'元购买商品'); + $res2 = self::paySuccess($order_id,'weixin',$formId);//微信支付为0时 + $res = $res1 && $res2; + self::checkTrans($res); + return $res; + } + + + + /** + * 用户申请退款 + * @param $uni + * @param $uid + * @param string $refundReasonWap + * @return bool + */ + public static function orderApplyRefund($uni, $uid,$refundReasonWap = '',$refundReasonWapExplain = '',$refundReasonWapImg = array()) + { + $order = self::getUserOrderDetail($uid,$uni); + if(!$order) return self::setErrorInfo('支付订单不存在!'); + if($order['refund_status'] == 2) return self::setErrorInfo('订单已退款!'); + if($order['refund_status'] == 1) return self::setErrorInfo('正在申请退款中!'); + if($order['status'] == 1) return self::setErrorInfo('订单当前无法退款!'); + self::beginTrans(); + $res1 = false !== StoreOrderStatus::status($order['id'],'apply_refund','用户申请退款,原因:'.$refundReasonWap); + $res2 = false !== self::edit(['refund_status'=>1,'refund_reason_time'=>time(),'refund_reason_wap'=>$refundReasonWap,'refund_reason_wap_explain'=>$refundReasonWapExplain,'refund_reason_wap_img'=>json_encode($refundReasonWapImg)],$order['id'],'id'); + $res = $res1 && $res2; + self::checkTrans($res); + if(!$res) + return self::setErrorInfo('申请退款失败!'); + else{ + $adminIds = SystemConfigService::get('site_store_admin_uids'); + if(!empty($adminIds)){ + try{ + if(!($adminList = array_unique(array_filter(explode(',',trim($adminIds)))))){ + self::setErrorInfo('申请退款成功,'); + return false; + } + RoutineTemplate::sendOrderRefundStatus($order,$refundReasonWap,$adminList);//小程序 发送模板消息 + }catch (\Exception $e){} + } + return true; + } + } + + /** + * //TODO 支付成功后 + * @param $orderId + * @param $paytype + * @param $notify + * @return bool + */ + public static function paySuccess($orderId,$paytype='weixin',$formId = '') + { + $order = self::where('order_id',$orderId)->find(); + $resPink = true; + $res1 = self::where('order_id',$orderId)->update(['paid'=>1,'pay_type'=>$paytype,'pay_time'=>time()]);//订单改为支付 + $cartInfo = self::getDb('StoreOrderCartInfo')->where('oid', $order['id'])->column('cart_info', 'unique') ?: []; + foreach ($cartInfo as $k => &$cart) $cart = json_decode($cart, true); + $res2 = true; + foreach ($cartInfo as $k => &$cart) { //减库存加销量 + if ($cart['combination_id']) $res2 = $res2 && StoreCombination::decCombinationStock($cart['cart_num'], $cart['combination_id']); + else if ($cart['seckill_id']) $res2 = $res2 && StoreSeckill::decSeckillStock($cart['cart_num'], $cart['seckill_id']); + else if ($cart['bargain_id']) $res2 = $res2 && StoreBargain::decBargainStock($cart['cart_num'], $cart['bargain_id']); + else $res2 = $res2 && StoreProduct::decProductStock($cart['cart_num'], $cart['productInfo']['id'], isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : ''); + } + User::bcInc($order['uid'],'pay_count',1,'uid'); + if($order->combination_id && $res1 && !$order->refund_status) $resPink = StorePink::createPink($order);//创建拼团 + $oid = self::where('order_id',$orderId)->value('id'); + StoreOrderStatus::status($oid,'pay_success','用户付款成功'); + RoutineTemplate::sendOrderSuccess($formId,$orderId); + HookService::afterListen('user_level',User::where('uid',$order['uid'])->find(),false,UserBehavior::class); + $res = $res1 && $resPink; + return false !== $res; + } + + /* + * 线下支付消息通知 + * 待完善 + * + * */ + public static function createOrderTemplate($order) + { + + //$goodsName = StoreOrderCartInfo::getProductNameList($order['id']); +// RoutineTemplateService::sendTemplate(WechatUser::getOpenId($order['uid']),RoutineTemplateService::ORDER_CREATE, [ +// 'first'=>'亲,您购买的商品已支付成功', +// 'keyword1'=>date('Y/m/d H:i',$order['add_time']), +// 'keyword2'=>implode(',',$goodsName), +// 'keyword3'=>$order['order_id'], +// 'remark'=>'点击查看订单详情' +// ],Url::build('/wap/My/order',['uni'=>$order['order_id']],true,true)); +// RoutineTemplateService::sendAdminNoticeTemplate([ +// 'first'=>"亲,您有一个新订单 \n订单号:{$order['order_id']}", +// 'keyword1'=>'新订单', +// 'keyword2'=>'线下支付', +// 'keyword3'=>date('Y/m/d H:i',time()), +// 'remark'=>'请及时处理' +// ]); + } + + public static function getUserOrderDetail($uid,$key) + { + return self::where('order_id|unique',$key)->where('uid',$uid)->where('is_del',0)->find(); + } + + + /** + * TODO 订单发货 + * @param array $postageData 发货信息 + * @param string $oid orderID + */ + public static function orderPostageAfter($postageData, $oid) + { + $order = self::where('id',$oid)->find(); + $url ='/pages/order_details/index?order_id='.$order['order_id']; + $group = [ + 'first'=>'亲,您的订单已发货,请注意查收', + 'remark'=>'点击查看订单详情' + ]; + if($postageData['delivery_type'] == 'send'){//送货 + $goodsName = StoreOrderCartInfo::getProductNameList($order['id']); + $group = array_merge($group,[ + 'keyword1'=>$goodsName, + 'keyword2'=>$order['pay_type'] == 'offline' ? '线下支付' : date('Y/m/d H:i',$order['pay_time']), + 'keyword3'=>$order['user_address'], + 'keyword4'=>$postageData['delivery_name'], + 'keyword5'=>$postageData['delivery_id'] + ]); + RoutineTemplate::sendOut('ORDER_DELIVER_SUCCESS',$order['uid'],$group,$url); + }else if($postageData['delivery_type'] == 'express'){//发货 + $group = array_merge($group,[ + 'keyword1'=>$order['order_id'], + 'keyword2'=>$postageData['delivery_name'], + 'keyword3'=>$postageData['delivery_id'] + ]); + RoutineTemplate::sendOut('ORDER_POSTAGE_SUCCESS',$order['uid'],$group,$url); + } + } + + public static function orderTakeAfter($order) + { +// $openid = WechatUser::getOpenId($order['uid']); +// RoutineTemplateService::sendTemplate($openid,RoutineTemplateService::ORDER_TAKE_SUCCESS,[ +// 'first'=>'亲,您的订单已成功签收,快去评价一下吧', +// 'keyword1'=>$order['order_id'], +// 'keyword2'=>'已收货', +// 'keyword3'=>date('Y/m/d H:i',time()), +// 'keyword4'=>implode(',',StoreOrderCartInfo::getProductNameList($order['id'])), +// 'remark'=>'点击查看订单详情' +// ],Url::build('My/order',['uni'=>$order['order_id']],true,true)); + } + + /** + * 删除订单 + * @param $uni + * @param $uid + * @return bool + */ + public static function removeOrder($uni, $uid) + { + $order = self::getUserOrderDetail($uid,$uni); + if(!$order) return self::setErrorInfo('订单不存在!'); + $order = self::tidyOrder($order); + if($order['_status']['_type'] != 0 && $order['_status']['_type']!= -2 && $order['_status']['_type'] != 4) + return self::setErrorInfo('该订单无法删除!'); + if(false !== self::edit(['is_del'=>1],$order['id'],'id') && false !==StoreOrderStatus::status($order['id'],'remove_order','删除订单')) { + //未支付和已退款的状态下才可以退积分退库存退优惠券 + if($order['_status']['_type']== 0 || $order['_status']['_type']== -2) { + HookService::afterListen('store_order_regression_all',$order,null,false,OrderBehavior::class); + } + return true; + }else + return self::setErrorInfo('订单删除失败!'); + } + + + /** + * //TODO 用户确认收货 + * @param $uni + * @param $uid + */ + public static function takeOrder($uni, $uid) + { + $order = self::getUserOrderDetail($uid,$uni); + if(!$order) return self::setErrorInfo('订单不存在!'); + $order = self::tidyOrder($order); + if($order['_status']['_type'] != 2) return self::setErrorInfo('订单状态错误!'); + self::beginTrans(); + if(false !== self::edit(['status'=>2],$order['id'],'id') && + false !== StoreOrderStatus::status($order['id'],'user_take_delivery','用户已收货')){ + try{ + HookService::listen('store_product_order_user_take_delivery',$order,$uid,false,GoodsBehavior::class); + }catch (\Exception $e){ + return self::setErrorInfo($e->getMessage()); + } + self::commitTrans(); + return true; + }else{ + self::rollbackTrans(); + return false; + } + } + + public static function tidyOrder($order,$detail = false,$isPic=false) + { + if($detail == true && isset($order['id'])){ + $cartInfo = self::getDb('StoreOrderCartInfo')->where('oid',$order['id'])->column('cart_info','unique')?:[]; + $info=[]; + foreach ($cartInfo as $k=>$cart){ + $cart=json_decode($cart, true); + $cart['unique']=$k; + //新增是否评价字段 + $cart['is_reply'] = self::getDb('store_product_reply')->where('unique',$k)->count(); + array_push($info,$cart); + unset($cart); + } + $order['cartInfo'] = $info; + } + + $status = []; + if(!$order['paid'] && $order['pay_type'] == 'offline' && !$order['status'] >= 2){ + $status['_type'] = 9; + $status['_title'] = '线下付款'; + $status['_msg'] = '等待商家处理,请耐心等待'; + $status['_class'] = 'nobuy'; + }else if(!$order['paid']){ + $status['_type'] = 0; + $status['_title'] = '未支付'; + $status['_msg'] = '立即支付订单吧'; + $status['_class'] = 'nobuy'; + }else if($order['refund_status'] == 1){ + $status['_type'] = -1; + $status['_title'] = '申请退款中'; + $status['_msg'] = '商家审核中,请耐心等待'; + $status['_class'] = 'state-sqtk'; + }else if($order['refund_status'] == 2){ + $status['_type'] = -2; + $status['_title'] = '已退款'; + $status['_msg'] = '已为您退款,感谢您的支持'; + $status['_class'] = 'state-sqtk'; + }else if(!$order['status']){ + if($order['pink_id']){ + if(StorePink::where('id',$order['pink_id'])->where('status',1)->count()){ + $status['_type'] = 1; + $status['_title'] = '拼团中'; + $status['_msg'] = '等待其他人参加拼团'; + $status['_class'] = 'state-nfh'; + }else{ + $status['_type'] = 1; + $status['_title'] = '未发货'; + $status['_msg'] = '商家未发货,请耐心等待'; + $status['_class'] = 'state-nfh'; + } + }else{ + $status['_type'] = 1; + $status['_title'] = '未发货'; + $status['_msg'] = '商家未发货,请耐心等待'; + $status['_class'] = 'state-nfh'; + } + }else if($order['status'] == 1){ + $status['_type'] = 2; + $status['_title'] = '待收货'; + $status['_msg'] = date('m月d日H时i分',StoreOrderStatus::getTime($order['id'],'delivery_goods')).'服务商已发货'; + $status['_class'] = 'state-ysh'; + }else if($order['status'] == 2){ + $status['_type'] = 3; + $status['_title'] = '待评价'; + $status['_msg'] = '已收货,快去评价一下吧'; + $status['_class'] = 'state-ypj'; + }else if($order['status'] == 3){ + $status['_type'] = 4; + $status['_title'] = '交易完成'; + $status['_msg'] = '交易完成,感谢您的支持'; + $status['_class'] = 'state-ytk'; + } + if(isset($order['pay_type'])) + $status['_payType'] = isset(self::$payType[$order['pay_type']]) ? self::$payType[$order['pay_type']] : '其他方式'; + if(isset($order['delivery_type'])) + $status['_deliveryType'] = isset(self::$deliveryType[$order['delivery_type']]) ? self::$deliveryType[$order['delivery_type']] : '其他方式'; + $order['_status'] = $status; + $order['_pay_time']=isset($order['pay_time']) && $order['pay_time'] != null ? date('Y-m-d H:i:s',$order['pay_time']) : date('Y-m-d H:i:s',$order['add_time']); + $order['_add_time']=isset($order['add_time']) ? (strstr($order['add_time'],'-')===false ? date('Y-m-d H:i:s',$order['add_time']) : $order['add_time'] ): ''; + $order['status_pic']=''; + //获取产品状态图片 + if($isPic){ + $order_details_images=\app\core\util\GroupDataService::getData('order_details_images') ? : []; + foreach ($order_details_images as $image){ + if(isset($image['order_status']) && $image['order_status']==$order['_status']['_type']){ + $order['status_pic']=$image['pic']; + break; + } + } + } + return $order; + } + + public static function statusByWhere($status,$uid=0,$model = null) + { +// $orderId = StorePink::where('uid',$uid)->where('status',1)->column('order_id','id');//获取正在拼团的订单编号 + if($model == null) $model = new self; + if('' === $status) + return $model; + else if($status == 0) + return $model->where('paid',0)->where('status',0)->where('refund_status',0); + else if($status == 1)//待发货 + return $model->where('paid',1)->where('status',0)->where('refund_status',0); + else if($status == 2) + return $model->where('paid',1)->where('status',1)->where('refund_status',0); + else if($status == 3) + return $model->where('paid',1)->where('status',2)->where('refund_status',0); + else if($status == 4) + return $model->where('paid',1)->where('status',3)->where('refund_status',0); + else if($status == -1) + return $model->where('paid',1)->where('refund_status',1); + else if($status == -2) + return $model->where('paid',1)->where('refund_status',2); + else if($status == -3) + return $model->where('paid',1)->where('refund_status','IN','1,2'); +// else if($status == 11){ +// return $model->where('order_id','IN',implode(',',$orderId)); +// } + else + return $model; + } + + public static function getUserOrderList($uid,$status = '',$page = 0,$limit = 8) + { + $list = self::statusByWhere($status,$uid)->where('is_del',0)->where('uid',$uid) + ->field('add_time,seckill_id,bargain_id,combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,pink_id,delivery_type') + ->order('add_time DESC')->page((int)$page,(int)$limit)->select()->toArray(); + foreach ($list as $k=>$order){ + $list[$k] = self::tidyOrder($order,true); + } + + return $list; + } + + /** + * 获取推广人地下用户的订单金额 + * @param string $uid + * @param string $status + * @return array + */ + public static function getUserOrderCount($uid = '',$status = ''){ + $res = self::statusByWhere($status,$uid)->where('uid','IN',$uid)->column('pay_price'); + return $res; + } + + public static function searchUserOrder($uid,$order_id) + { + $order = self::where('uid',$uid)->where('order_id',$order_id)->where('is_del',0)->field('seckill_id,bargain_id,combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,delivery_type') + ->order('add_time DESC')->find(); + if(!$order) + return false; + else + return self::tidyOrder($order->toArray(),true); + + } + + public static function orderOver($oid) + { + $res = self::edit(['status'=>'3'],$oid,'id'); + if(!$res) exception('评价后置操作失败!'); + StoreOrderStatus::status($oid,'check_order_over','用户评价'); + } + + public static function checkOrderOver($oid) + { + $uniqueList = StoreOrderCartInfo::where('oid',$oid)->column('unique'); + if(StoreProductReply::where('unique','IN',$uniqueList)->where('oid',$oid)->count() == count($uniqueList)){ + HookService::listen('store_product_order_over',$oid,null,false,GoodsBehavior::class); + self::orderOver($oid); + } + } + + + public static function getOrderStatusNum($uid) + { + $noBuy = self::where('uid',$uid)->where('paid',0)->where('is_del',0)->where('pay_type','<>','offline')->count(); + $noPostageNoPink = self::where('o.uid',$uid)->alias('o')->where('o.paid',1)->where('o.pink_id',0)->where('o.is_del',0)->where('o.status',0)->where('o.pay_type','<>','offline')->count(); + $noPostageYesPink = self::where('o.uid',$uid)->alias('o')->join('StorePink p','o.pink_id = p.id')->where('p.status',2)->where('o.paid',1)->where('o.is_del',0)->where('o.status',0)->where('o.pay_type','<>','offline')->count(); + $noPostage = bcadd($noPostageNoPink,$noPostageYesPink); + $noTake = self::where('uid',$uid)->where('paid',1)->where('is_del',0)->where('status',1)->where('pay_type','<>','offline')->count(); + $noReply = self::where('uid',$uid)->where('paid',1)->where('is_del',0)->where('status',2)->count(); + $noPink = self::where('o.uid',$uid)->alias('o')->join('StorePink p','o.pink_id = p.id')->where('p.status',1)->where('o.paid',1)->where('o.is_del',0)->where('o.status',0)->where('o.pay_type','<>','offline')->count(); + $noRefund = self::where('uid',$uid)->where('paid',1)->where('is_del',0)->where('refund_status','IN','1,2')->count(); + return compact('noBuy','noPostage','noTake','noReply','noPink','noRefund'); + } + + public static function gainUserIntegral($order) + { + if($order['gain_integral'] > 0){ + $userInfo = User::getUserInfo($order['uid']); + ModelBasic::beginTrans(); + $res1 = false != User::where('uid',$userInfo['uid'])->update(['integral'=>bcadd($userInfo['integral'],$order['gain_integral'],2)]); + $res2 = false != UserBill::income('购买商品赠送积分',$order['uid'],'integral','gain',$order['gain_integral'],$order['id'],$userInfo['integral'],'购买商品赠送'.floatval($order['gain_integral']).'积分'); + $res = $res1 && $res2; + ModelBasic::checkTrans($res); + return $res; + } + return true; + } + + /** + * 获取当前订单中有没有拼团存在 + * @param $pid + * @return int|string + */ + public static function getIsOrderPink($pid = 0 ,$uid = 0){ + return self::where('uid',$uid)->where('pink_id',$pid)->where('refund_status',0)->where('is_del',0)->count(); + } + + /** + * 获取order_id + * @param $pid + * @return mixed + */ + public static function getStoreIdPink($pid = 0 ,$uid = 0){ + return self::where('uid',$uid)->where('pink_id',$pid)->where('is_del',0)->value('order_id'); + } + + /** + * 删除当前用户拼团未支付的订单 + */ + public static function delCombination(){ + self::where('combination','GT',0)->where('paid',0)->where('uid',User::getActiveUid())->delete(); + } + + public static function getUserPrice($uid =0){ + if(!$uid) return 0; + $price = self::where('paid',1)->where('uid',$uid)->where('status',2)->where('refund_status',0)->column('pay_price','id'); + $count = 0; + if($price){ + foreach ($price as $v){ + $count = bcadd($count,$v,2); + } + } + return $count; + } + + + /* + * 个人中心获取个人订单列表和订单搜索 + * @param int $uid 用户uid + * @param int | string 查找订单类型 + * @param int $first 分页 + * @param int 每页显示多少条 + * @param string $search 订单号 + * @return array + * */ + public static function getUserOrderSearchList($uid,$type,$page,$limit,$search) + { + if($search){ + $order = self::searchUserOrder($uid,$search)?:[]; + $list = $order == false ? [] : [$order]; + }else{ + $list = self::getUserOrderList($uid,$type,$page,$limit); + } + foreach ($list as $k=>$order){ + $list[$k] = self::tidyOrder($order,true); + if($list[$k]['_status']['_type'] == 3){ + foreach ($order['cartInfo']?:[] as $key=>$product){ + $list[$k]['cartInfo'][$key]['is_reply'] = StoreProductReply::isReply($product['unique'],'product'); + $list[$k]['cartInfo'][$key]['add_time'] = date('Y-m-d H:i',$product['add_time']); + } + } + } + return $list; + } + + /* + * 获取用户下级的订单 + * @param int $xuid 下级用户用户uid + * @param int $uid 用户uid + * @param int $type 订单类型 + * @param int $first 截取行数 + * @param int $limit 展示条数 + * @return array + * */ + public static function getSubordinateOrderlist($xUid,$uid,$type,$first,$limit) + { + $list = []; + if(!$xUid){ + $arr = User::getOneSpreadUid($uid); + foreach($arr as $v) $list = StoreOrder::getUserOrderList($v,$type,$first,$limit); + }else $list = self::getUserOrderList($xUid,$type,$first,$limit); + foreach ($list as $k=>$order){ + $list[$k] = self::tidyOrder($order,true); + if($list[$k]['_status']['_type'] == 3){ + foreach ($order['cartInfo']?:[] as $key=>$product){ + $list[$k]['cartInfo'][$key]['is_reply'] = StoreProductReply::isReply($product['unique'],'product'); + } + } + } + return $list; + } + + /* + * 获取某个用户的订单统计数据 + * @param int $uid 用户uid + * */ + public static function getOrderData($uid) + { + $data['order_count']=self::where(['is_del'=>0,'paid'=>1,'uid'=>$uid,'refund_status'=>0])->count(); + $data['sum_price']=self::where(['is_del'=>0,'paid'=>1,'uid'=>$uid,'refund_status'=>0])->sum('pay_price'); + $data['unpaid_count']=self::statusByWhere(0,$uid)->where('is_del',0)->where('uid',$uid)->count(); + $data['unshipped_count']=self::statusByWhere(1,$uid)->where('is_del',0)->where('uid',$uid)->count(); + $data['received_count']=self::statusByWhere(2,$uid)->where('is_del',0)->where('uid',$uid)->count(); + $data['evaluated_count']=self::statusByWhere(3,$uid)->where('is_del',0)->where('uid',$uid)->count(); + $data['complete_count']=self::statusByWhere(4,$uid)->where('is_del',0)->where('uid',$uid)->count(); + return $data; + } + + + /* + * 累计消费 + * **/ + public static function getOrderStatusSum($uid) + { + return self::where(['uid'=>$uid,'is_del'=>0,'paid'=>1])->sum('pay_price'); + } + + public static function getPinkOrderId($id){ + return self::where('id',$id)->value('order_id'); + } +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreOrderCartInfo.php b/application/ebapi/model/store/StoreOrderCartInfo.php new file mode 100644 index 00000000..72600aab --- /dev/null +++ b/application/ebapi/model/store/StoreOrderCartInfo.php @@ -0,0 +1,48 @@ + + * @day: 2017/12/26 + */ + +namespace app\ebapi\model\store; + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreOrderCartInfo extends ModelBasic +{ + use ModelTrait; + + public static function getCartInfoAttr($value) + { + return json_decode($value,true)?:[]; + } + + public static function setCartInfo($oid,array $cartInfo) + { + $group = []; + foreach ($cartInfo as $cart){ + $group[] = [ + 'oid'=>$oid, + 'cart_id'=>$cart['id'], + 'product_id'=>$cart['productInfo']['id'], + 'cart_info'=>json_encode($cart), + 'unique'=>md5($cart['id'].''.$oid) + ]; + } + return self::setAll($group); + } + + public static function getProductNameList($oid) + { + $cartInfo = self::where('oid',$oid)->select(); + $goodsName = []; + foreach ($cartInfo as $cart){ + $suk = isset($cart['cart_info']['productInfo']['attrInfo']) ? '('.$cart['cart_info']['productInfo']['attrInfo']['suk'].')' : ''; + $goodsName[] = $cart['cart_info']['productInfo']['store_name'].$suk; + } + return $goodsName; + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreOrderStatus.php b/application/ebapi/model/store/StoreOrderStatus.php new file mode 100644 index 00000000..dfca1592 --- /dev/null +++ b/application/ebapi/model/store/StoreOrderStatus.php @@ -0,0 +1,28 @@ + + * @day: 2017/12/28 + */ + +namespace app\ebapi\model\store; + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreOrderStatus extends ModelBasic +{ + use ModelTrait; + + public static function status($oid,$change_type,$change_message,$change_time = null) + { + if($change_time == null) $change_time = time(); + return self::set(compact('oid','change_type','change_message','change_time')); + } + + public static function getTime($oid,$change_type) + { + return self::where('oid',$oid)->where('change_type',$change_type)->value('change_time'); + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StorePink.php b/application/ebapi/model/store/StorePink.php new file mode 100644 index 00000000..7796a8bd --- /dev/null +++ b/application/ebapi/model/store/StorePink.php @@ -0,0 +1,569 @@ + + * @day: 2017/12/18 + */ + +namespace app\ebapi\model\store; + +use app\core\model\routine\RoutineTemplate;//待完善 +use app\ebapi\model\user\User; +use basic\ModelBasic; +use traits\ModelTrait; + +/** + * 拼团Model + * Class StorePink + * @package app\ebapi\model\store + */ +class StorePink extends ModelBasic +{ + use ModelTrait; + + /* + * 获取拼团完成的用户 + * @param int $uid 用户id + * @return array + * */ + public static function getPinkOkList($uid) + { + $list=self::where(['a.status'=>2,'a.is_refund'=>0])->where('a.uid','neq',$uid)->alias('a')->join('__USER__ u','u.uid=a.uid')->column('u.nickname'); + foreach ($list as &$item){ + $item.='拼团成功'; + } + return $list; + } + /* + * 获取拼团完成的商品总件数 + * */ + public static function getPinkOkSumTotalNum($id) + { + + return self::where('status',2)->where('is_refund',0)->sum('total_num'); + } + /** + * 获取一条拼团数据 + * @param $id + * @return mixed + */ + public static function getPinkUserOne($id){ + $model = new self(); + $model = $model->alias('p'); + $model = $model->field('p.*,u.nickname,u.avatar'); + $model = $model->where('id',$id); + $model = $model->join('__USER__ u','u.uid = p.uid'); + $list = $model->find(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取拼团的团员 + * @param $id + * @return mixed + */ + public static function getPinkMember($id){ + $model = new self(); + $model = $model->alias('p'); + $model = $model->field('p.*,u.nickname,u.avatar'); + $model = $model->where('k_id',$id); + $model = $model->where('is_refund',0); + $model = $model->join('__USER__ u','u.uid = p.uid'); + $model = $model->order('id asc'); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 设置结束时间 + * @param $idAll + * @return $this + */ + public static function setPinkStopTime($idAll){ + $model = new self(); + $model = $model->where('id','IN',$idAll); + return $model->update(['stop_time'=>time(),'status'=>2]); + } + + /** + * 获取正在拼团的数据 团长 + * @param int $cid 产品id + * @param int $isAll 是否查找所有拼团 + * @return array + */ + public static function getPinkAll($cid,$isAll=false){ + $model = new self(); + $model = $model->alias('p'); + $model = $model->field('p.*,u.nickname,u.avatar'); + $model = $model->where('stop_time','GT',time()); + $model = $model->where('cid',$cid); + $model = $model->where('k_id',0); + $model = $model->where('is_refund',0); + $model = $model->order('add_time desc'); + $model = $model->join('__USER__ u','u.uid = p.uid'); + $list = $model->select(); + $list=count($list) ? $list->toArray() : []; + if($isAll){ + $pindAll = array(); + foreach ($list as &$v){ + $v['count'] = self::getPinkPeople($v['id'],$v['people']); + $v['h'] = date('H',$v['stop_time']); + $v['i'] = date('i',$v['stop_time']); + $v['s'] = date('s',$v['stop_time']); + $pindAll[] = $v['id'];//开团团长ID + } + return [$list,$pindAll]; + } + return $list; + } + + /** + * 获取还差几人 + */ + public static function getPinkPeople($kid,$people){ + $model = new self(); + $model = $model->where('k_id',$kid)->where('is_refund',0); + $count = bcadd($model->count(),1,0); + return bcsub($people,$count,0); + } + + /** + * 判断订单是否在当前的拼团中 + * @param $orderId + * @param $kid + * @return bool + */ + public static function getOrderIdAndPink($orderId,$kid){ + $model = new self(); + $pink = $model->where('k_id',$kid)->whereOr('id',$kid)->column('order_id'); + if(in_array($orderId,$pink))return true; + else return false; + } + + /** + * 判断用户是否在团内 + * @param $id + * @return int|string + */ + public static function getIsPinkUid($id = 0,$uid = 0){ + $pinkT = self::where('id',$id)->where('uid',$uid)->where('is_refund',0)->count(); + $pink = self::whereOr('k_id',$id)->where('uid',$uid)->where('is_refund',0)->count(); + if($pinkT) return true; + if($pink) return true; + else return false; + } + + + /** + * 判断是否发送模板消息 0 未发送 1已发送 + * @param $uidAll + * @return int|string + */ + public static function isTpl($uidAll,$pid){ + if(is_array($uidAll)){ + $countK = self::where('uid','IN',implode(',',$uidAll))->where('is_tpl',0)->where('id',$pid)->count(); + $count = self::where('uid','IN',implode(',',$uidAll))->where('is_tpl',0)->where('k_id',$pid)->count(); + } + else { + $countK = self::where('uid',$uidAll)->where('is_tpl',0)->where('id',$pid)->count(); + $count = self::where('uid',$uidAll)->where('is_tpl',0)->where('k_id',$pid)->count(); + } + return bcadd($countK,$count,0); + } + /** + * 拼团成功提示模板消息 + * @param $uidAll + * @param $pid + */ + public static function orderPinkAfter($uidAll,$pid){ + $nickname=User::where(['uid'=>self::where(['id'=>$pid])->value('uid')])->value('nickname'); + foreach ($uidAll as $v){ + RoutineTemplate::sendOut('PINK_TRUE',$v,[ + 'keyword1'=>'亲,您的拼团已经完成了', + 'keyword2'=>$nickname, + 'keyword3'=>date('Y-m-d H:i:s',time()), + 'keyword4'=>self::where('id',$pid)->value('price') + ]); + } + self::beginTrans(); + $res1 = self::where('uid','IN',implode(',',$uidAll))->where('id',$pid)->whereOr('k_id',$pid)->update(['is_tpl'=>1]); + self::checkTrans($res1); + } + + /** + * 拼团失败发送的模板消息 + * @param $uid + * @param $pid + */ + public static function orderPinkAfterNo($uid,$pid,$formId='',$fillTilt='',$isRemove=false){ + $store=self::alias('p')->where('p.id|p.k_id',$pid)->field('c.*')->where('p.uid',$uid)->join('__STORE_COMBINATION__ c','c.id=p.cid')->find(); + $pink=self::where('id|k_id',$pid)->where('uid',$uid)->find(); + if($isRemove){ + RoutineTemplate::sendOut('PINK_REMOVE',$uid,[ + 'keyword1'=>$store->title, + 'keyword2'=>$pink->order_id, + 'keyword3'=>$pink->price, + ],$formId,'/pages/order_details/index?order_id='.$pink->order_id); + }else{ + RoutineTemplate::sendOut('PINK_Fill',$uid,[ + 'keyword1'=>$store->title, + 'keyword2'=>$fillTilt, + 'keyword3'=>$pink->order_id, + 'keyword4'=>date('Y-m-d H:i:s',$pink->add_time), + 'keyword5'=>'申请退款金额:¥'.$pink->price, + ],$formId,'/pages/order_details/index?order_id='.$pink->order_id); + } + self::where('id',$pid)->update(['status'=>3,'stop_time'=>time()]); + self::where('k_id',$pid)->update(['status'=>3,'stop_time'=>time()]); + } + + /** + * 获取当前拼团数据返回订单编号 + * @param $id + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getCurrentPink($id,$uid){ + $pink = self::where('id',$id)->where('uid',$uid)->find(); + if(!$pink) $pink = self::where('k_id',$id)->where('uid',$uid)->find(); + return StoreOrder::where('id',$pink['order_id_key'])->value('order_id'); + } + + public static function systemPage($where){ + $model = new self; + $model = $model->alias('p'); + $model = $model->field('p.*,c.title'); + if($where['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$where['data']); + $model = $model->where('p.add_time','>',strtotime($startTime)); + $model = $model->where('p.add_time','<',strtotime($endTime)); + } + if($where['status']) $model = $model->where('p.status',$where['status']); + $model = $model->where('p.k_id',0); + $model = $model->order('p.id desc'); + $model = $model->join('StoreCombination c','c.id=p.cid'); + return self::page($model,function($item)use($where){ + $item['count_people'] = bcadd(self::where('k_id',$item['id'])->count(),1,0); + },$where); + } + + public static function isPinkBe($data,$id){ + $data['id'] = $id; + $count = self::where($data)->count(); + if($count) return $count; + $data['k_id'] = $id; + $count = self::where($data)->count(); + if($count) return $count; + else return 0; + } + public static function isPinkStatus($pinkId){ + if(!$pinkId) return false; + $stopTime = self::where('id',$pinkId)->value('stop_time'); + if($stopTime < time()) return true; //拼团结束 + else return false;//拼团未结束 + } + + /** + * 判断拼团结束 后的状态 + * @param $pinkId + * @return bool + */ + public static function isSetPinkOver($pinkId){ + $people = self::where('id',$pinkId)->value('people'); + $stopTime = self::where('id',$pinkId)->value('stop_time'); + if($stopTime < time()){ + $countNum = self::getPinkPeople($pinkId,$people); + if($countNum) return false;//拼团失败 + else return true;//拼团成功 + }else return true; + } + + /** + * 拼团退款 + * @param $id + * @return bool + */ + public static function setRefundPink($oid){ + $res = true; + $order = StoreOrder::where('id',$oid)->find(); + if($order['pink_id']) $id = $order['pink_id']; + else return $res; + $count = self::where('id',$id)->where('uid',$order['uid'])->find();//正在拼团 团长 + $countY = self::where('k_id',$id)->where('uid',$order['uid'])->find();//正在拼团 团员 + if(!$count && !$countY) return $res; + if($count){//团长 + //判断团内是否还有其他人 如果有 团长为第二个进团的人 + $kCount = self::where('k_id',$id)->order('add_time asc')->find(); + if($kCount){ + $res11 = self::where('k_id',$id)->update(['k_id'=>$kCount['id']]); + $res12 = self::where('id',$kCount['id'])->update(['stop_time'=>$count['add_time']+86400,'k_id'=>0]); + $res1 = $res11 && $res12; + $res2 = self::where('id',$id)->update(['stop_time'=>time()-1,'k_id'=>0,'is_refund'=>$kCount['id'],'status'=>3]); + }else{ + $res1 = true; + $res2 = self::where('id',$id)->update(['stop_time'=>time()-1,'k_id'=>0,'is_refund'=>$id,'status'=>3]); + } + //修改结束时间为前一秒 团长ID为0 + $res = $res1 && $res2; + }else if($countY){//团员 + $res = self::where('id',$countY['id'])->update(['stop_time'=>time()-1,'k_id'=>0,'is_refund'=>$id,'status'=>3]); + } + return $res; + + } + + + + /** + * 拼团人数完成时,判断全部人都是未退款状态 + * @param $pinkIds + * @return bool + */ + public static function setPinkStatus($pinkIds){ + $orderPink = self::where('id','IN',$pinkIds)->where('is_refund',1)->count(); + if(!$orderPink) return true; + else return false; + } + + + /** + * 创建拼团 + * @param $order + * @return mixed + */ + public static function createPink($order){ + $order = StoreOrder::tidyOrder($order,true)->toArray(); + if($order['pink_id']){//拼团存在 + $res = false; + $pink['uid'] = $order['uid'];//用户id + if(self::isPinkBe($pink,$order['pink_id'])) return false; + $pink['order_id'] = $order['order_id'];//订单id 生成 + $pink['order_id_key'] = $order['id'];//订单id 数据库id + $pink['total_num'] = $order['total_num'];//购买个数 + $pink['total_price'] = $order['pay_price'];//总金额 + $pink['k_id'] = $order['pink_id'];//拼团id + foreach ($order['cartInfo'] as $v){ + $pink['cid'] = $v['combination_id'];//拼团产品id + $pink['pid'] = $v['product_id'];//产品id + $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团 + $pink['price'] = $v['productInfo']['price'];//单价 + $pink['stop_time'] = 0;//结束时间 + $pink['add_time'] = time();//开团时间 + $res = self::set($pink)->toArray(); + } + RoutineTemplate::sendOut('PINK_TRUE',$order['uid'],[ + 'keyword1'=>StoreCombination::where('id',$pink['cid'])->value('title'), + 'keyword2'=>User::where('uid',self::where('id',$pink['k_id'])->value('uid'))->value('nickname'), + 'keyword3'=>date('Y-m-d H:i:s',$pink['add_time']), + 'keyword3'=>$pink['total_price'], + ],'','/pages/order_details/index?order_id='.$pink['order_id']); + //处理拼团完成 + list($pinkAll,$pinkT,$count,$idAll,$uidAll)=self::getPinkMemberAndPinkK($pink); + if($pinkT['status']==1){ + if(!$count)//组团完成 + self::PinkComplete($uidAll,$idAll,$pink['uid'],$pinkT); + else + self::PinkFail($pinkAll,$pinkT,0); + } + if($res) return true; + else return false; + }else{ + $res = false; + $pink['uid'] = $order['uid'];//用户id + $pink['order_id'] = $order['order_id'];//订单id 生成 + $pink['order_id_key'] = $order['id'];//订单id 数据库id + $pink['total_num'] = $order['total_num'];//购买个数 + $pink['total_price'] = $order['pay_price'];//总金额 + $pink['k_id'] = 0;//拼团id + foreach ($order['cartInfo'] as $v){ + $pink['cid'] = $v['combination_id'];//拼团产品id + $pink['pid'] = $v['product_id'];//产品id + $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团 + $pink['price'] = $v['productInfo']['price'];//单价 +// $stopTime = StoreCombination::where('id',$v['combination_id'])->value('stop_time');//获取拼团产品结束的时间 +// if($stopTime < time()+86400) $pink['stop_time'] = $stopTime;//结束时间 + $pink['stop_time'] = time()+86400;//结束时间 + $pink['add_time'] = time();//开团时间 + $res1 = self::set($pink)->toArray(); + $res2 = StoreOrder::where('id',$order['id'])->update(['pink_id'=>$res1['id']]); + $res = $res1 && $res2; + } + RoutineTemplate::sendOut('OPEN_PINK_SUCCESS',$order['uid'],[ + 'keyword1'=>date('Y-m-d H:i:s',$pink['add_time']), + 'keyword2'=>date('Y-m-d H:i:s',$pink['stop_time']), + 'keyword3'=>StoreCombination::where('id',$pink['cid'])->value('title'), + 'keyword4'=>$pink['order_id'], + 'keyword4'=>$pink['total_price'], + ],'','/pages/order_details/index?order_id='.$pink['order_id']); + if($res) return true; + else return false; + } + } + /* + * 获取一条今天正在拼团的人的头像和名称 + * */ + public static function getPinkSecondOne() + { + $addTime = mt_rand(time()-30000,time()); + return self::where('p.add_time','GT',$addTime)->alias('p')->where('p.status',1)->join('User u','u.uid=p.uid')->field('u.nickname,u.avatar as src')->find(); + } + /** + * 拼团成功后给团长返佣金 + * @param int $id + * @return bool + */ +// public static function setRakeBackColonel($id = 0){ +// if(!$id) return false; +// $pinkRakeBack = self::where('id',$id)->field('people,price,uid,id')->find()->toArray(); +// $countPrice = bcmul($pinkRakeBack['people'],$pinkRakeBack['price'],2); +// if(bcsub((float)$countPrice,0,2) <= 0) return true; +// $rakeBack = (SystemConfigService::get('rake_back_colonel') ?: 0)/100; +// if($rakeBack <= 0) return true; +// $rakeBackPrice = bcmul($countPrice,$rakeBack,2); +// if($rakeBackPrice <= 0) return true; +// $mark = '拼团成功,奖励佣金'.floatval($rakeBackPrice); +// self::beginTrans(); +// $res1 = UserBill::income('获得拼团佣金',$pinkRakeBack['uid'],'now_money','colonel',$rakeBackPrice,$id,0,$mark); +// $res2 = User::bcInc($pinkRakeBack['uid'],'now_money',$rakeBackPrice,'uid'); +// $res = $res1 && $res2; +// self::checkTrans($res); +// return $res; +// } + + /* + * 拼团完成更改数据写入内容 + * @param array $uidAll 当前拼团uid + * @param array $idAll 当前拼团pink_id + * @param array $pinkT 团长信息 + * @return int + * */ + public static function PinkComplete($uidAll,$idAll,$uid,$pinkT) + { + $pinkBool=6; + try{ + if(self::setPinkStatus($idAll)){ + self::setPinkStopTime($idAll); + if(in_array($uid,$uidAll)){ + if(self::isTpl($uidAll,$pinkT['id'])) self::orderPinkAfter($uidAll,$pinkT['id']); + $pinkBool = 1; + }else $pinkBool = 3; + } + return $pinkBool; + }catch (\Exception $e){ + self::setErrorInfo($e->getMessage()); + return $pinkBool; + } + } + + /* + * 拼团失败 退款 + * @param array $pinkAll 拼团数据,不包括团长 + * @param array $pinkT 团长数据 + * @param int $pinkBool + * @param boolen $isRunErr 是否返回错误信息 + * @param boolen $isIds 是否返回记录所有拼团id + * @return int| boolen + * */ + public static function PinkFail($pinkAll,$pinkT,$pinkBool,$isRunErr=true,$isIds=false){ + self::startTrans(); + $pinkIds=[]; + try{ + if($pinkT['stop_time'] < time()){//拼团时间超时 退款 + //团员退款 + foreach ($pinkAll as $v){ + if(StoreOrder::orderApplyRefund(StoreOrder::getPinkOrderId($v['order_id_key']),$v['uid'],'拼团时间超时') && self::isTpl($v['uid'],$pinkT['id'])){ + self::orderPinkAfterNo($v['uid'],$v['k_id']); + if($isIds) array_push($pinkIds,$v['id']); + $pinkBool = 2; + }else{ + if($isRunErr) return self::setErrorInfo(StoreOrder::getErrorInfo(),true); + } + } + //团长退款 + if(StoreOrder::orderApplyRefund(StoreOrder::getPinkOrderId($pinkT['order_id_key']),$pinkT['uid'],'拼团时间超时') && self::isTpl($pinkT['uid'],$pinkT['id'])){ + self::orderPinkAfterNo($pinkT['uid'],$pinkT['id']); + if($isIds) array_push($pinkIds,$pinkT['id']); + $pinkBool = 2; + }else{ + if($isRunErr) return self::setErrorInfo(StoreOrder::getErrorInfo(),true); + } + if(!$pinkBool) $pinkBool = 3; + } + self::commit(); + if($isIds) return $pinkIds; + return $pinkBool; + }catch (\Exception $e){ + self::rollback(); + return self::setErrorInfo($e->getMessage()); + } + } + + /* + * 获取参团人和团长和拼团总人数 + * @param array $pink + * @return array + * */ + public static function getPinkMemberAndPinkK($pink){ + //查找拼团团员和团长 + if($pink['k_id']){ + $pinkAll = self::getPinkMember($pink['k_id']); + $pinkT = self::getPinkUserOne($pink['k_id']); + }else{ + $pinkAll = self::getPinkMember($pink['id']); + $pinkT = $pink; + } + $count = count($pinkAll)+1; + $count=(int)$pinkT['people']-$count; + $idAll = []; + $uidAll =[]; + //收集拼团用户id和拼团id + foreach ($pinkAll as $k=>$v){ + $idAll[$k] = $v['id']; + $uidAll[$k] = $v['uid']; + } + $idAll[] = $pinkT['id']; + $uidAll[] = $pinkT['uid']; + return [$pinkAll,$pinkT,$count,$idAll,$uidAll]; + } + /* + * 取消开团 + * @param int $uid 用户id + * @param int $pink_id 团长id + * @return boolean + * */ + public static function removePink($uid,$cid,$pink_id,$formId,$nextPinkT=null) + { + $pinkT=self::where(['uid'=>$uid,'id'=>$pink_id,'cid'=>$cid,'k_id'=>0,'is_refund'=>0,'status'=>1])->where('stop_time','GT',time())->find(); + if(!$pinkT) return self::setErrorInfo('未查到拼团信息,无法取消'); + self::startTrans(); + try{ + list($pinkAll,$pinkT,$count,$idAll,$uidAll)=self::getPinkMemberAndPinkK($pinkT); + if(count($pinkAll)){ + if(self::getPinkPeople($pink_id,$pinkT->people)){ + //拼团未完成,拼团有成员取消开团取 紧跟团长后拼团的人 + if(isset($pinkAll[0])) $nextPinkT=$pinkAll[0]; + }else{ + //拼团完成 + self::PinkComplete($uidAll,$idAll,$uid,$pinkT); + return self::setErrorInfo(['status'=>200,'msg'=>'拼团已完成,无法取消']); + } + } + //取消开团 + if(StoreOrder::orderApplyRefund(StoreOrder::getPinkOrderId($pinkT['order_id_key']),$pinkT['uid'],'拼团取消开团') && self::isTpl($pinkT['uid'],$pinkT['id'])) + self::orderPinkAfterNo($pinkT['uid'],$pinkT['id'],$formId,'拼团取消开团',true); + else + return self::setErrorInfo(['status'=>200,'msg'=>StoreOrder::getErrorInfo()],true); + //当前团有人的时候 + if(is_array($nextPinkT)){ + self::where('id',$nextPinkT['id'])->update(['k_id'=>0,'status'=>1,'stop_time'=>$pinkT['stop_time']]); + self::where('k_id',$pinkT['id'])->update(['k_id'=>$nextPinkT['id']]); + StoreOrder::where('order_id',$nextPinkT['order_id'])->update(['pink_id'=>$nextPinkT['id']]); + } + self::commitTrans(); + return true; + }catch (\Exception $e){ + return self::setErrorInfo($e->getLine().':'.$e->getMessage(),true); + } + } +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreProduct.php b/application/ebapi/model/store/StoreProduct.php new file mode 100644 index 00000000..9855681d --- /dev/null +++ b/application/ebapi/model/store/StoreProduct.php @@ -0,0 +1,325 @@ + + * @day: 2017/12/12 + */ + +namespace app\ebapi\model\store; + +use app\admin\model\store\StoreProductAttrValue as StoreProductAttrValuemodel; +use app\core\model\system\SystemUserLevel; +use app\core\model\user\UserLevel; +use basic\ModelBasic; +use app\core\util\SystemConfigService; +use traits\ModelTrait; + +class StoreProduct extends ModelBasic +{ + use ModelTrait; + + protected function getSliderImageAttr($value) + { + return json_decode($value,true)?:[]; + } + + public static function getValidProduct($productId,$field = 'add_time,browse,cate_id,code_path,cost,description,ficti,give_integral,id,image,is_bargain,is_benefit,is_best,is_del,is_hot,is_new,is_postage,is_seckill,is_show,keyword,mer_id,mer_use,ot_price,postage,price,sales,slider_image,sort,stock,store_info,store_name,unit_name,vip_price,IFNULL(sales,0) + IFNULL(ficti,0) as fsales') + { + $Product=self::where('is_del',0)->where('is_show',1)->where('id',$productId)->field($field)->find(); + if($Product) return $Product->toArray(); + else return false; + } + + public static function validWhere() + { + return self::where('is_del',0)->where('is_show',1)->where('mer_id',0); + } + + public static function getProductList($data,$uid) + { + $sId = $data['sid']; + $cId = $data['cid']; + $keyword = $data['keyword']; + $priceOrder = $data['priceOrder']; + $salesOrder = $data['salesOrder']; + $news = $data['news']; + $page = $data['page']; + $limit = $data['limit']; + $model = self::validWhere(); + if($sId){ + $product_ids=self::getDb('store_product_cate')->where('cate_id',$sId)->column('product_id'); + if(count($product_ids)) + $model=$model->where('id',"in",$product_ids); + else + $model=$model->where('cate_id',-1); + }elseif($cId){ + $sids = StoreCategory::pidBySidList($cId)?:[]; + if($sids){ + $sidsr = []; + foreach($sids as $v){ + $sidsr[] = $v['id']; + } + $model=$model->where('cate_id','IN',$sidsr); + } + } + if(!empty($keyword)) $model=$model->where('keyword|store_name','LIKE',htmlspecialchars("%$keyword%")); + if($news!=0) $model=$model->where('is_new',1); + $baseOrder = ''; + if($priceOrder) $baseOrder = $priceOrder == 'desc' ? 'price DESC' : 'price ASC'; +// if($salesOrder) $baseOrder = $salesOrder == 'desc' ? 'sales DESC' : 'sales ASC';//真实销量 + if($salesOrder) $baseOrder = $salesOrder == 'desc' ? 'sales DESC' : 'sales ASC';//虚拟销量 + if($baseOrder) $baseOrder .= ', '; + $model=$model->order($baseOrder.'sort DESC, add_time DESC'); + $list=$model->page((int)$page,(int)$limit)->field('id,store_name,cate_id,image,IFNULL(sales,0) + IFNULL(ficti,0) as sales,price,stock')->select(); + $list=count($list) ? $list->toArray() : []; + return self::setLevelPrice($list,$uid); + } + /* + * 分类搜索 + * @param string $value + * @return array + * */ + public static function getSearchStorePage($keyword,$uid) + { + $model = self::validWhere(); + if(strlen(trim($keyword))) $model = $model->where('store_name|keyword','LIKE',"%$keyword%"); + $list = $model->field('id,store_name,cate_id,image,IFNULL(sales,0) + IFNULL(ficti,0) as sales,price,stock')->select(); + return self::setLevelPrice($list,$uid); + } + /** + * 新品产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getNewProduct($field = '*',$limit = 0,$uid=0) + { + $model = self::where('is_new',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + $list=$model->select(); + $list=count($list) ? $list->toArray() : []; + return self::setLevelPrice($list,$uid); + } + + /** + * 热卖产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getHotProduct($field = '*',$limit = 0,$uid=0) + { + $model = self::where('is_hot',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return self::setLevelPrice($model->select(),$uid); + } + + /** + * 热卖产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getHotProductLoading($field = '*',$offset = 0,$limit = 0) + { + $model = self::where('is_hot',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($offset,$limit); + return $model->select(); + } + + /** + * 精品产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getBestProduct($field = '*',$limit = 0,$uid=0) + { + $model = self::where('is_best',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return self::setLevelPrice($model->select(),$uid); + } + + /* + * 设置会员价格 + * @param object | array $list 产品列表 + * @param int $uid 用户uid + * @return array + * */ + public static function setLevelPrice($list,$uid,$isSingle=false) + { + if(is_object($list)) $list=count($list) ? $list->toArray() : []; + $levelId=UserLevel::getUserLevel($uid); + if($levelId){ + $discount=UserLevel::getUserLevelInfo($levelId,'discount'); + $discount=bcsub(1,bcdiv($discount,100,2),2); + }else{ + $discount=SystemUserLevel::getLevelDiscount(); + $discount=bcsub(1,bcdiv($discount,100,2),2); + } + //如果不是数组直接执行减去会员优惠金额 + if(!is_array($list)) + //不是会员原价返回 + if($levelId) + //如果$isSingle==true 返回优惠后的总金额,否则返回优惠的金额 + return $isSingle ? bcsub($list,bcmul($discount,$list,2),2) : bcmul($discount,$list,2); + else + return $isSingle ? $list : 0; + //当$list为数组时$isSingle==true为一维数组 ,否则为二维 + if($isSingle) + $list['vip_price']=isset($list['price']) ? bcsub($list['price'],bcmul($discount,$list['price'],2),2) : 0; + else + foreach ($list as &$item){ + $item['vip_price']=isset($item['price']) ? bcsub($item['price'],bcmul($discount,$item['price'],2),2) : 0; + } + return $list; + } + + + /** + * 优惠产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getBenefitProduct($field = '*',$limit = 0) + { + $model = self::where('is_benefit',1) + ->where('is_del',0)->where('mer_id',0)->where('stock','>',0) + ->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + public static function cateIdBySimilarityProduct($cateId,$field='*',$limit = 0) + { + $pid = StoreCategory::cateIdByPid($cateId)?:$cateId; + $cateList = StoreCategory::pidByCategory($pid,'id') ?:[]; + $cid = [$pid]; + foreach ($cateList as $cate){ + $cid[] = $cate['id']; + } + $model = self::where('cate_id','IN',$cid)->where('is_show',1)->where('is_del',0) + ->field($field)->order('sort DESC,id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + public static function isValidProduct($productId) + { + return self::be(['id'=>$productId,'is_del'=>0,'is_show'=>1]) > 0; + } + + public static function getProductStock($productId,$uniqueId = '') + { + return $uniqueId == '' ? + self::where('id',$productId)->value('stock')?:0 + : StoreProductAttr::uniqueByStock($uniqueId); + } + + public static function decProductStock($num,$productId,$unique = '') + { + if($unique){ + $res = false !== StoreProductAttrValuemodel::decProductAttrStock($productId,$unique,$num); + $res = $res && self::where('id',$productId)->setInc('sales',$num); + }else{ + $res = false !== self::where('id',$productId)->dec('stock',$num)->inc('sales',$num)->update(); + } + return $res; + } + + /* + * 减少销量,增加库存 + * @param int $num 增加库存数量 + * @param int $productId 产品id + * @param string $unique 属性唯一值 + * @return boolean + * */ + public static function incProductStock($num,$productId,$unique = '') + { + if($unique){ + $res = false !== StoreProductAttrValuemodel::incProductAttrStock($productId,$unique,$num); + $res = $res && self::where('id',$productId)->setDec('sales',$num); + }else{ + $res = false !== self::where('id',$productId)->inc('stock',$num)->dec('sales',$num)->update(); + } + return $res; + } + + public static function getPacketPrice($storeInfo,$productValue) + { + $store_brokerage_ratio=SystemConfigService::get('store_brokerage_ratio'); + $store_brokerage_ratio=bcdiv($store_brokerage_ratio,100,2); + if(count($productValue)){ + $Maxkey=self::getArrayMax($productValue,'price'); + $Minkey=self::getArrayMin($productValue,'price'); + + if(isset($productValue[$Maxkey])){ + $value=$productValue[$Maxkey]; + if($value['cost'] > $value['price']) + $maxPrice=0; + else + $maxPrice=bcmul($store_brokerage_ratio,bcsub($value['price'],$value['cost']),0); + unset($value); + }else $maxPrice=0; + + if(isset($productValue[$Minkey])){ + $value=$productValue[$Minkey]; + if($value['cost'] > $value['price']) + $minPrice=0; + else + $minPrice=bcmul($store_brokerage_ratio,bcsub($value['price'],$value['cost']),0); + unset($value); + }else $minPrice=0; + if($minPrice==0 && $maxPrice==0) + return 0; + else + return $minPrice.'~'.$maxPrice; + }else{ + if($storeInfo['cost'] < $storeInfo['price']) + return bcmul($store_brokerage_ratio,bcsub($storeInfo['price'],$storeInfo['cost']),0); + else + return 0; + } + } + /* + * 获取二维数组中最大的值 + * */ + public static function getArrayMax($arr,$field) + { + $temp=[]; + foreach ($arr as $k=>$v){ + $temp[]=$v[$field]; + } + $maxNumber=max($temp); + foreach ($arr as $k=>$v){ + if($maxNumber==$v[$field]) return $k; + } + return 0; + } + /* + * 获取二维数组中最小的值 + * */ + public static function getArrayMin($arr,$field) + { + $temp=[]; + foreach ($arr as $k=>$v){ + $temp[]=$v[$field]; + } + $minNumber=min($temp); + foreach ($arr as $k=>$v){ + if($minNumber==$v[$field]) return $k; + } + return 0; + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreProductAttr.php b/application/ebapi/model/store/StoreProductAttr.php new file mode 100644 index 00000000..d05c215f --- /dev/null +++ b/application/ebapi/model/store/StoreProductAttr.php @@ -0,0 +1,75 @@ + + * @day: 2017/12/13 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use think\Db; +use traits\ModelTrait; + +class StoreProductAttr extends ModelBasic +{ + + use ModelTrait; + + protected function getAttrValuesAttr($value) + { + return explode(',',$value); + } + + public static function storeProductAttrValueDb() + { + return Db::name('StoreProductAttrValue'); + } + + + /** + * 获取商品属性数据 + * @param $productId + * @return array + */ + public static function getProductAttrDetail($productId) + { + $attrDetail = self::where('product_id',$productId)->order('attr_values asc')->select()->toArray()?:[]; + $_values = self::storeProductAttrValueDb()->where('product_id',$productId)->select(); + $values = []; + foreach ($_values as $value){ + $values[$value['suk']] = $value; + } + foreach ($attrDetail as $k=>$v){ + $attr = $v['attr_values']; +// unset($productAttr[$k]['attr_values']); + foreach ($attr as $kk=>$vv){ + $attrDetail[$k]['attr_value'][$kk]['attr'] = $vv; + $attrDetail[$k]['attr_value'][$kk]['check'] = false; + } + } + return [$attrDetail,$values]; + } + + public static function uniqueByStock($unique) + { + return self::storeProductAttrValueDb()->where('unique',$unique)->value('stock')?:0; + } + + public static function uniqueByAttrInfo($unique, $field = '*') + { + return self::storeProductAttrValueDb()->field($field)->where('unique',$unique)->find(); + } + + public static function issetProductUnique($productId,$unique) + { + $res = self::be(['product_id'=>$productId]); + if($unique){ + return $res && self::storeProductAttrValueDb()->where('product_id',$productId)->where('unique',$unique)->count() > 0; + }else{ + return !$res; + } + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreProductRelation.php b/application/ebapi/model/store/StoreProductRelation.php new file mode 100644 index 00000000..139f923c --- /dev/null +++ b/application/ebapi/model/store/StoreProductRelation.php @@ -0,0 +1,142 @@ + + * @day: 2017/11/11 + */ + +namespace app\ebapi\model\store; + +use app\core\behavior\GoodsBehavior; +use service\HookService; +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 点赞收藏model + * Class StoreProductRelation + * @package app\ebapi\model\store + */ +class StoreProductRelation extends ModelBasic +{ + use ModelTrait; + + /** + * 获取用户点赞所有产品的个数 + * @param $uid + * @return int|string + */ + public static function getUserIdLike($uid = 0){ + $count = self::where('uid',$uid)->where('type','like')->count(); + return $count; + } + + /** + * 获取用户收藏所有产品的个数 + * @param $uid + * @return int|string + */ + public static function getUserIdCollect($uid = 0){ + $count = self::where('uid',$uid)->where('type','collect')->count(); + return $count; + } + + /** + * 添加点赞 收藏 + * @param $productId + * @param $uid + * @param $relationType + * @param string $category + * @return bool + */ + public static function productRelation($productId,$uid,$relationType,$category = 'product') + { + if(!$productId) return self::setErrorInfo('产品不存在!'); + $relationType = strtolower($relationType); + $category = strtolower($category); + $data = ['uid'=>$uid,'product_id'=>$productId,'type'=>$relationType,'category'=>$category]; + if(self::be($data)) return true; + $data['add_time'] = time(); + self::set($data); + HookService::afterListen('store_'.$category.'_'.$relationType,$productId,$uid,false,GoodsBehavior::class); + return true; + } + + /** + * 批量 添加点赞 收藏 + * @param $productIdS + * @param $uid + * @param $relationType + * @param string $category + * @return bool + */ + public static function productRelationAll($productIdS,$uid,$relationType,$category = 'product'){ + $res = true; + if(is_array($productIdS)){ + self::beginTrans(); + foreach ($productIdS as $productId){ + $res = $res && self::productRelation($productId,$uid,$relationType,$category); + } + self::checkTrans($res); + return $res; + } + return $res; + } + + /** + * 取消 点赞 收藏 + * @param $productId + * @param $uid + * @param $relationType + * @param string $category + * @return bool + */ + public static function unProductRelation($productId,$uid,$relationType,$category = 'product') + { + if(!$productId) return self::setErrorInfo('产品不存在!'); + $relationType = strtolower($relationType); + $category = strtolower($category); + self::where(['uid'=>$uid,'product_id'=>$productId,'type'=>$relationType,'category'=>$category])->delete(); + HookService::afterListen('store_'.$category.'_un_'.$relationType,$productId,$uid,false,GoodsBehavior::class); + return true; + } + + public static function productRelationNum($productId,$relationType,$category = 'product') + { + $relationType = strtolower($relationType); + $category = strtolower($category); + return self::where('type',$relationType)->where('product_id',$productId)->where('category',$category)->count(); + } + + public static function isProductRelation($product_id,$uid,$relationType,$category = 'product') + { + $type = strtolower($relationType); + $category = strtolower($category); + return self::be(compact('product_id','uid','type','category')); + } + + /* + * 获取某个用户收藏产品 + * @param int uid 用户id + * @param int $first 行数 + * @param int $limit 展示行数 + * @return array + * */ + public static function getUserCollectProduct($uid,$page,$limit) + { + $list = self::where('A.uid',$uid) + ->field('B.id pid,B.store_name,B.price,B.ot_price,B.sales,B.image,B.is_del,B.is_show')->alias('A') + ->where('A.type','collect')->where('A.category','product') + ->order('A.add_time DESC')->join('__STORE_PRODUCT__ B','A.product_id = B.id') + ->page((int)$page,(int)$limit)->select()->toArray(); + foreach ($list as $k=>$product){ + if($product['pid']){ + $list[$k]['is_fail'] = $product['is_del'] && $product['is_show']; + }else{ + unset($list[$k]); + } + } + return $list; + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreProductReply.php b/application/ebapi/model/store/StoreProductReply.php new file mode 100644 index 00000000..2555d2dd --- /dev/null +++ b/application/ebapi/model/store/StoreProductReply.php @@ -0,0 +1,133 @@ + + * @day: 2017/12/29 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use service\UtilService; +use traits\ModelTrait; + +class StoreProductReply extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + protected function setPicsAttr($value) + { + return is_array($value) ? json_encode($value) : $value; + } + + protected function getPicsAttr($value) + { + return json_decode($value,true); + } + + public static function reply($group,$type = 'product') + { + $group['reply_type'] = $type; + return self::set($group); + } + + public static function productValidWhere($alias = '') + { + $model = new self; + if($alias){ + $model->alias($alias); + $alias .= '.'; + } + return $model->where("{$alias}is_del",0)->where("{$alias}reply_type",'product'); + } + + /* + * 设置查询产品评论条件 + * @param int $productId 产品id + * @param string $order 排序方式 + * @return object + * */ + public static function setProductReplyWhere($productId,$type=0,$alias='A') + { + $model = self::productValidWhere($alias)->where('A.product_id',$productId) + ->field('A.product_score,A.service_score,A.comment,A.merchant_reply_content,A.merchant_reply_time,A.pics,A.add_time,B.nickname,B.avatar,C.cart_info,A.merchant_reply_content') + ->join('__USER__ B','A.uid = B.uid') + ->join('__STORE_ORDER_CART_INFO__ C','A.unique = C.unique'); + switch ($type){ + case 1: + $model=$model->where('A.product_score',5);//好评 + break; + case 2: + $model=$model->where('A.product_score',['<',5],['>',2]);//中评 + break; + case 3: + $model=$model->where('A.product_score','<',2);//差评 + break; + } + return $model; + } + + public static function getProductReplyList($productId,$order = 0,$page = 0,$limit = 8) + { + $list = self::setProductReplyWhere($productId,$order)->page((int)$page,(int)$limit)->select()->toArray()?:[]; + foreach ($list as $k=>$reply){ + $list[$k] = self::tidyProductReply($reply); + } + return $list; + } + + public static function tidyProductReply($res) + { + $res['cart_info'] = json_decode($res['cart_info'],true)?:[]; + $res['suk'] = isset($res['cart_info']['productInfo']['attrInfo']) ? $res['cart_info']['productInfo']['attrInfo']['suk'] : ''; + $res['nickname'] = UtilService::anonymity($res['nickname']); + $res['merchant_reply_time'] = date('Y-m-d H:i',$res['merchant_reply_time']); + $res['add_time'] = date('Y-m-d H:i',$res['add_time']); + $res['star'] = bcadd($res['product_score'],$res['service_score'],2); + $res['star'] =bcdiv($res['star'],2,0); + $res['comment'] = $res['comment'] ? :'此用户没有填写评价'; + unset($res['cart_info']); + return $res; + } + + public static function isReply($unique,$reply_type = 'product') + { + return self::be(['unique'=>$unique,'reply_type'=>$reply_type]); + } + + public static function getRecProductReply($productId) + { + $res = self::productValidWhere('A')->where('A.product_id',$productId) + ->field('A.product_score,A.service_score,A.comment,A.merchant_reply_content,A.merchant_reply_time,A.pics,A.add_time,B.nickname,B.avatar,C.cart_info') + ->join('__USER__ B','A.uid = B.uid') + ->join('__STORE_ORDER_CART_INFO__ C','A.unique = C.unique') + ->order('A.add_time DESC,A.product_score DESC, A.service_score DESC, A.add_time DESC')->find(); + if(!$res) return null; + return self::tidyProductReply($res->toArray()); + } + + public static function productReplyCount($productId) + { +// \think\Db::listen(function($sql, $time, $explain){ +// // 记录SQL +// echo $sql. ' ['.$time.'s]'; +// }); + $data['sum_count']=self::setProductReplyWhere($productId)->count(); + $data['good_count']=self::setProductReplyWhere($productId,1)->count(); + $data['in_count']=self::setProductReplyWhere($productId,2)->count(); + $data['poor_count']=self::setProductReplyWhere($productId,3)->count(); + $data['reply_chance']=bcdiv($data['good_count'],$data['sum_count'],2); + $data['reply_star']=bcmul($data['reply_chance'],5,0); + $data['reply_chance']=bcmul($data['reply_chance'],100,2); + return $data; + } + +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreSeckill.php b/application/ebapi/model/store/StoreSeckill.php new file mode 100644 index 00000000..a304b8a9 --- /dev/null +++ b/application/ebapi/model/store/StoreSeckill.php @@ -0,0 +1,147 @@ + + * @day: 2017/12/18 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use app\core\util\GroupDataService; + +class StoreSeckill extends ModelBasic +{ + + protected function getImagesAttr($value) + { + return json_decode($value,true)?:[]; + } + + public static function getSeckillCount() + { + $seckillTime = GroupDataService::getData('routine_seckill_time')?:[];//秒杀时间段 + $timeInfo=['time'=>0,'continued'=>0]; + foreach($seckillTime as $key=>$value){ + $currentHour = date('H'); + $activityEndHour = bcadd((int)$value['time'],(int)$value['continued'],0); + if($currentHour >= (int)$value['time'] && $currentHour < $activityEndHour && $activityEndHour < 24){ + $timeInfo=$value; + break; + } + } + if($timeInfo['time']==0) return 0; + $activityEndHour = bcadd((int)$timeInfo['time'],(int)$timeInfo['continued'],0); + $startTime = bcadd(strtotime(date('Y-m-d')),bcmul($timeInfo['time'],3600,0)); + $stopTime = bcadd(strtotime(date('Y-m-d')),bcmul($activityEndHour,3600,0)); + return self::where('is_del',0)->where('status',1)->where('start_time','<=',$startTime)->where('stop_time','>=',$stopTime)->count(); + } + /* + * 获取秒杀列表 + * + * */ + public static function seckillList($startTime,$stopTime,$offset = 0,$limit = 20) + { + $list = StoreSeckill::where('is_del',0)->where('status',1)->where('start_time','<=',$startTime)->where('stop_time','>=',$stopTime)->order('sort desc')->limit($offset,$limit)->select(); + if($list) return $list->toArray(); + else return []; + } + /** + * 获取所有秒杀产品 + * @param string $field + * @return array + */ + public static function getListAll($offset = 0,$limit = 10,$field = 'id,product_id,image,title,price,ot_price,start_time,stop_time,stock,sales'){ + $time = time(); + $model = self::where('is_del',0)->where('status',1)->where('stock','>',0)->field($field) + ->where('start_time','<',$time)->where('stop_time','>',$time)->order('sort DESC,add_time DESC'); + $model = $model->limit($offset,$limit); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + /** + * 获取热门推荐的秒杀产品 + * @param int $limit + * @param string $field + * @return array + */ + public static function getHotList($limit = 0,$field = 'id,product_id,image,title,price,ot_price,start_time,stop_time,stock') + { + $time = time(); + $model = self::where('is_hot',1)->where('is_del',0)->where('status',1)->where('stock','>',0)->field($field) + ->where('start_time','<',$time)->where('stop_time','>',$time)->order('sort DESC,add_time DESC'); + if($limit) $model->limit($limit); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取一条秒杀产品 + * @param $id + * @param string $field + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getValidProduct($id,$field = '*') + { + $time = time(); + return self::where('id',$id)->where('is_del',0)->where('status',1)->where('start_time','<',$time)->where('stop_time','>',$time) + ->field($field)->find(); + } + + public static function initFailSeckill() + { + self::where('is_hot',1)->where('is_del',0)->where('status','<>',1)->where('stop_time','<',time())->update(['status'=>'-1']); + } + + public static function idBySimilaritySeckill($id,$limit = 4,$field='*') + { + $time = time(); + $list = []; + $productId = self::where('id',$id)->value('product_id'); + if($productId){ + $list = array_merge($list, self::where('product_id',$productId)->where('id','<>',$id) + ->where('is_del',0)->where('status',1)->where('stock','>',0) + ->field($field)->where('start_time','<',$time)->where('stop_time','>',$time) + ->order('sort DESC,add_time DESC')->limit($limit)->select()->toArray()); + } + $limit = $limit - count($list); + if($limit){ + $list = array_merge($list,self::getHotList($limit,$field)); + } + + return $list; + } + + /** 获取秒杀产品库存 + * @param $id + * @return mixed + */ + public static function getProductStock($id){ + return self::where('id',$id)->value('stock'); + } + + /** + * 修改秒杀库存 + * @param int $num + * @param int $seckillId + * @return bool + */ + public static function decSeckillStock($num = 0,$seckillId = 0){ + $res = false !== self::where('id',$seckillId)->dec('stock',$num)->inc('sales',$num)->update(); + return $res; + } + + /** + * 增加库存较少销量 + * @param int $num + * @param int $seckillId + * @return bool + */ + public static function incSeckillStock($num = 0,$seckillId = 0){ + $res = false !== self::where('id',$seckillId)->inc('stock',$num)->dec('sales',$num)->update(); + return $res; + } +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreService.php b/application/ebapi/model/store/StoreService.php new file mode 100644 index 00000000..a110b0ef --- /dev/null +++ b/application/ebapi/model/store/StoreService.php @@ -0,0 +1,17 @@ + + * @day: 2017/12/23 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreService extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/ebapi/model/store/StoreServiceLog.php b/application/ebapi/model/store/StoreServiceLog.php new file mode 100644 index 00000000..9752ea3f --- /dev/null +++ b/application/ebapi/model/store/StoreServiceLog.php @@ -0,0 +1,17 @@ + + * @day: 2017/12/23 + */ + +namespace app\ebapi\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreServiceLog extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/ebapi/model/user/User.php b/application/ebapi/model/user/User.php new file mode 100644 index 00000000..6bc54042 --- /dev/null +++ b/application/ebapi/model/user/User.php @@ -0,0 +1,294 @@ + + * @day: 2017/12/21 + */ + +namespace app\ebapi\model\user; + +use app\core\model\user\UserBill; +use app\ebapi\model\store\StoreOrder; +use basic\ModelBasic; +use app\core\util\SystemConfigService; +use think\Request; +use think\Session; +use traits\ModelTrait; + +/** + * 用户 + * Class User + * @package app\ebapi\model\user + */ +class User extends ModelBasic +{ + use ModelTrait; + + public static function updateWechatUser($wechatUser,$uid) + { + $userinfo=self::where('uid',$uid)->find(); + if($userinfo->spread_uid){ + return self::edit([ + 'nickname'=>$wechatUser['nickname']?:'', + 'avatar'=>$wechatUser['headimgurl']?:'', + ],$uid,'uid'); + }else { + $data=[ + 'nickname' => $wechatUser['nickname'] ?: '', + 'avatar' => $wechatUser['headimgurl'] ?: '', + 'is_promoter' =>$userinfo->is_promoter, + 'spread_uid' => 0, + 'spread_time' =>0, + 'last_time' => time(), + 'last_ip' => Request::instance()->ip(), + ]; + if(isset($wechatUser['code']) && !$userinfo->is_promoter && $wechatUser['code']){ + $data['is_promoter']=1; + $data['spread_uid']=$wechatUser['code']; + $data['spread_time']=time(); + } + return self::edit($data, $uid, 'uid'); + } + } + + + + + /** + * 小程序用户添加 + * @param $routineUser + * @param int $spread_uid + * @return object + */ + public static function setRoutineUser($routineUser,$spread_uid = 0){ + self::beginTrans(); + $res1 = true; + if($spread_uid) $res1 = self::where('uid',$spread_uid)->inc('spread_count',1); + $storeBrokerageStatu = SystemConfigService::get('store_brokerage_statu') ? : 1;//获取后台分销类型 + $res2 = self::set([ + 'account'=>'rt'.$routineUser['uid'].time(), + 'pwd'=>md5(123456), + 'nickname'=>$routineUser['nickname']?:'', + 'avatar'=>$routineUser['headimgurl']?:'', + 'spread_uid'=>$spread_uid, + 'is_promoter'=>$spread_uid || $storeBrokerageStatu != 1 ? 1: 0, + 'spread_time'=>$spread_uid ? time() : 0, + 'uid'=>$routineUser['uid'], + 'add_time'=>$routineUser['add_time'], + 'add_ip'=>Request::instance()->ip(), + 'last_time'=>time(), + 'last_ip'=>Request::instance()->ip(), + 'user_type'=>$routineUser['user_type'] + ]); + $res = $res1 && $res2; + self::checkTrans($res); + return $res2; + } + + /** + * 获得当前登陆用户UID + * @return int $uid + */ + public static function getActiveUid() + { + $uid = null; + $uid = Session::get('LoginUid'); + if($uid) return $uid; + else return 0; + } + + /** + * TODO 查询当前用户信息 + * @param $uid $uid 用户编号 + * @param string $field $field 查询的字段 + * @return array + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function getUserInfo($uid,$field = '') + { + if(strlen(trim($field))) $userInfo = self::where('uid',$uid)->field($field)->find(); + else $userInfo = self::where('uid',$uid)->find(); + if(!$userInfo) return false; + return $userInfo->toArray(); + } + + /** + * 判断当前用户是否推广员 + * @param int $uid + * @return bool + */ + public static function isUserSpread($uid = 0){ + if(!$uid) return false; + $status = (int)SystemConfigService::get('store_brokerage_statu'); + $isPromoter = true; + if($status == 1) $isPromoter = self::where('uid',$uid)->value('is_promoter'); + if($isPromoter) return true; + else return false; + } + + + /** + * 小程序用户一级分销 + * @param $orderInfo + * @return bool + */ + public static function backOrderBrokerage($orderInfo) + { + $userInfo = User::getUserInfo($orderInfo['uid']); + if(!$userInfo || !$userInfo['spread_uid']) return true; + $storeBrokerageStatu = SystemConfigService::get('store_brokerage_statu') ? : 1;//获取后台分销类型 + if($storeBrokerageStatu == 1){ + if(!User::be(['uid'=>$userInfo['spread_uid'],'is_promoter'=>1])) return true; + } + $brokerageRatio = (SystemConfigService::get('store_brokerage_ratio') ?: 0)/100; + if($brokerageRatio <= 0) return true; + $cost = isset($orderInfo['cost']) ? $orderInfo['cost'] : 0;//成本价 + if($cost > $orderInfo['pay_price']) return true;//成本价大于支付价格时直接返回 + //支付金额减去邮费 + $orderInfo['pay_price'] = bcsub($orderInfo['pay_price'],$orderInfo['pay_postage'],2); + $brokeragePrice = bcmul(bcsub($orderInfo['pay_price'],$cost,2),$brokerageRatio,2); + if($brokeragePrice <= 0) return true; + $mark = $userInfo['nickname'].'成功消费'.floatval($orderInfo['pay_price']).'元,奖励推广佣金'.floatval($brokeragePrice); + self::beginTrans(); + $res1 = UserBill::income('获得推广佣金',$userInfo['spread_uid'],'now_money','brokerage',$brokeragePrice,$orderInfo['id'],0,$mark); + $res2 = self::bcInc($userInfo['spread_uid'],'now_money',$brokeragePrice,'uid'); + $res = $res1 && $res2; + self::checkTrans($res); + if($res) self::backOrderBrokerageTwo($orderInfo); + return $res; + } + + /** + * 小程序 二级推广 + * @param $orderInfo + * @return bool + */ + public static function backOrderBrokerageTwo($orderInfo){ + $userInfo = User::getUserInfo($orderInfo['uid']); + $userInfoTwo = User::getUserInfo($userInfo['spread_uid']); + if(!$userInfoTwo || !$userInfoTwo['spread_uid']) return true; + $storeBrokerageStatu = SystemConfigService::get('store_brokerage_statu') ? : 1;//获取后台分销类型 + if($storeBrokerageStatu == 1){ + if(!User::be(['uid'=>$userInfoTwo['spread_uid'],'is_promoter'=>1])) return true; + } + $brokerageRatio = (SystemConfigService::get('store_brokerage_two') ?: 0)/100; + if($brokerageRatio <= 0) return true; + $cost = isset($orderInfo['cost']) ? $orderInfo['cost'] : 0;//成本价 + if($cost > $orderInfo['pay_price']) return true;//成本价大于支付价格时直接返回 + $brokeragePrice = bcmul(bcsub($orderInfo['pay_price'],$cost,2),$brokerageRatio,2); + if($brokeragePrice <= 0) return true; + $mark = '二级推广人'.$userInfo['nickname'].'成功消费'.floatval($orderInfo['pay_price']).'元,奖励推广佣金'.floatval($brokeragePrice); + self::beginTrans(); + $res1 = UserBill::income('获得推广佣金',$userInfoTwo['spread_uid'],'now_money','brokerage',$brokeragePrice,$orderInfo['id'],0,$mark); + $res2 = self::bcInc($userInfoTwo['spread_uid'],'now_money',$brokeragePrice,'uid'); + $res = $res1 && $res2; + self::checkTrans($res); + return $res; + } + /* + * 获取推荐人 + * @param int $two_uid + * @param int $first + * @param int $limit + * @return array + * */ + public static function getSpreadList($uid,$first,$limit) + { + $list=self::where('spread_uid',$uid)->field('uid,nickname,avatar,add_time')->limit($first,$limit)->order('add_time DESC')->select(); + foreach ($list as $k=>$user){ + $list[$k]['add_time'] = date('Y/m/d',$user['add_time']); + $list[$k]['price'] = StoreOrder::getUserPrice($user['uid']); + } + $count = self::where('spread_uid',$uid)->field('uid,nickname,avatar,add_time')->count(); + $data['count'] = $count; + $data['list'] = $list; + return $data; + } + + /* + * 获取某个用户的下级uid + * @param int $uid 用户uid + * @return array + * */ + public static function getOneSpreadUid($uid) + { + return self::where('spread_uid',$uid)->column('uid'); + } + + /* + * 修改个人信息 + * */ + public static function editUser($avatar,$nickname,$uid) + { + return self::edit(['avatar'=>$avatar,'nickname'=>$nickname],$uid,'uid'); + } + /** + * TODO 获取推广人数 一级 + * @param int $uid + * @return bool|int|string + */ + public static function getSpreadCount($uid = 0){ + if(!$uid) return false; + return self::where('spread_uid',$uid)->count(); + } + + public static function setUserSpreadCount($uid){ + self::where('uid',$uid)->update(['spread_count'=>self::getSpreadCount($uid)]); + } + + /** + * TODO 获取推广人数 二级 + * @param int $uid + * @return bool|int|string + */ + public static function getSpreadLevelCount($uid = 0){ + if(!$uid) return false; + $uidSubordinate = self::where('spread_uid',$uid)->column('uid'); + if(!count($uidSubordinate)) return 0; + return self::where('spread_uid','IN',implode(',',$uidSubordinate))->count(); + } + + /** + * 获取用户下级推广人 + * @param int $uid 当前用户 + * @param int $grade 等级 0 一级 1 二级 + * @param string $orderBy 排序 + * @return array|bool|void + */ + public static function getUserSpreadGrade($uid = 0,$grade = 0,$orderBy = '',$keyword = '',$offset = 0,$limit = 20){ + if(!$uid) return []; + $gradeGroup = [0,1]; + if(!in_array($grade,$gradeGroup)) return self::setErrorInfo('等级错误'); + $userStair = self::where('spread_uid',$uid)->column('uid'); + if(!count($userStair)) return []; + if($grade == 0) return self::getUserSpreadCountList(implode(',',$userStair),$orderBy,$keyword,$offset,$limit); + $userSecondary = self::where('spread_uid','in',implode(',',$userStair))->column('uid'); + return self::getUserSpreadCountList(implode(',',$userSecondary),$orderBy,$keyword,$offset,$limit); + } + + /** + * 获取团队信息 + * @param string $uid + * @param string $orderBy + * @param string $keyword + */ + public static function getUserSpreadCountList($uid, $orderBy = '',$keyword = '',$offset = 0,$limit = 20) + { + $model = new self; + if($orderBy==='') $orderBy='u.add_time desc'; + $model = $model->alias(' u'); + $model = $model->join('StoreOrder o','u.uid=o.uid','LEFT'); + $model = $model->where('u.uid','IN',$uid); + $model = $model->field("u.uid,u.nickname,u.avatar,from_unixtime(u.add_time,'%Y/%m/%d') as time,u.spread_count as childCount,COUNT(o.id) as orderCount,SUM(o.pay_price) as numberCount"); + if(strlen(trim($keyword))) $model = $model->where('u.nickname|u.phone','like',"%$keyword%"); + $model = $model->group('u.uid'); + $model = $model->order($orderBy); + $model = $model->limit($offset,$limit); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } +} \ No newline at end of file diff --git a/application/ebapi/model/user/UserAddress.php b/application/ebapi/model/user/UserAddress.php new file mode 100644 index 00000000..ea45495a --- /dev/null +++ b/application/ebapi/model/user/UserAddress.php @@ -0,0 +1,55 @@ + + * @day: 2017/12/25 + */ + +namespace app\ebapi\model\user; + + +use basic\ModelBasic; +use traits\ModelTrait; + +/** 用户收货地址 + * Class UserAddress + * @package app\ebapi\model\user + */ +class UserAddress extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function setDefaultAddress($id,$uid) + { + self::beginTrans(); + $res1 = self::where('uid',$uid)->update(['is_default'=>0]); + $res2 = self::where('id',$id)->where('uid',$uid)->update(['is_default'=>1]); + $res =$res1 !== false && $res2 !== false; + self::checkTrans($res); + return $res; + } + + public static function userValidAddressWhere($model=null,$prefix = '') + { + if($prefix) $prefix .='.'; + $model = self::getSelfModel($model); + return $model->where("{$prefix}is_del",0); + } + + public static function getUserValidAddressList($uid,$page=1,$limit=8,$field = '*') + { + return self::userValidAddressWhere()->where('uid',$uid)->order('add_time DESC')->field($field)->page((int)$page,(int)$limit)->select()->toArray()?:[]; + } + + public static function getUserDefaultAddress($uid,$field = '*') + { + return self::userValidAddressWhere()->where('uid',$uid)->where('is_default',1)->field($field)->find(); + } +} \ No newline at end of file diff --git a/application/ebapi/model/user/UserExtract.php b/application/ebapi/model/user/UserExtract.php new file mode 100644 index 00000000..c9d00db6 --- /dev/null +++ b/application/ebapi/model/user/UserExtract.php @@ -0,0 +1,150 @@ + + * @day: 2018/3/3 + */ + +namespace app\ebapi\model\user; + + +use app\core\model\user\UserBill; +use basic\ModelBasic; +use app\core\util\SystemConfigService; +use app\core\util\Template; +use traits\ModelTrait; + + +/** 用户提现 + * Class UserExtract + * @package app\ebapi\model\user + */ +class UserExtract extends ModelBasic +{ + use ModelTrait; + + //审核中 + const AUDIT_STATUS = 0; + //未通过 + const FAIL_STATUS = -1; + //已提现 + const SUCCESS_STATUS = 1; + + protected static $extractType = ['alipay','bank','weixin']; + + protected static $extractTypeMsg = ['alipay'=>'支付宝','bank'=>'银行卡','weixin'=>'微信']; + + protected static $status = array( + -1=>'未通过', + 0 =>'审核中', + 1 =>'已提现' + ); + + /* + * 用户自主提现记录提现记录,后台执行审核 + * @param array $userInfo 用户个人信息 + * @param array $data 提现详细信息 + * @return boolean + * */ + public static function userExtract($userInfo,$data){ + if(!in_array($data['extract_type'],self::$extractType)) + return self::setErrorInfo('提现方式不存在'); + $userInfo = User::get($userInfo['uid']); + $brokerage = UserBill::getBrokerage($userInfo['uid']);//获取总佣金 + $extractTotalPrice = self::userExtractTotalPrice($userInfo['uid']);//累计提现 + $extractPrice = (float)bcsub($brokerage,$extractTotalPrice,2);//减去已提现金额 + $extractPrice = (float)bcsub($extractPrice,self::userExtractTotalPrice($userInfo['uid'],0),2);//减去提现申请中的金额 + if($extractPrice < 0) return self::setErrorInfo('提现佣金不足'.$data['money']); + if($data['money'] > $extractPrice) return self::setErrorInfo('提现佣金不足'.$data['money']); + $balance = bcsub($userInfo['now_money'],$data['money'],2); + if($balance < 0) $balance=0; + $insertData = [ + 'uid'=>$userInfo['uid'], + 'extract_type'=>$data['extract_type'], + 'extract_price'=>(int)$data['money'], + 'add_time'=>time(), + 'balance'=>$balance, + 'status'=>self::AUDIT_STATUS + ]; + if(isset($data['name'])) $insertData['real_name'] = $data['name']; + else $insertData['real_name'] = $userInfo['nickname']; + if(isset($data['cardnum'])) $insertData['bank_code'] = $data['cardnum']; + else $insertData['bank_code'] = ''; + if(isset($data['bankname'])) $insertData['bank_address']=$data['bankname']; + else $insertData['bank_address']=''; + if(isset($data['weixin'])) $insertData['wechat'] = $data['weixin']; + else $insertData['wechat'] = $userInfo['nickname']; + if($data['extract_type'] == 'alipay'){ + if(!$data['alipay_code']) return self::setErrorInfo('请输入支付宝账号'); + $insertData['alipay_code'] = $data['alipay_code']; + $mark = '使用支付宝提现'.$insertData['extract_price'].'元'; + }elseif($data['extract_type'] == 'bank'){ + if(!$data['cardnum']) return self::setErrorInfo('请输入银行卡账号'); + if(!$data['bankname']) return self::setErrorInfo('请输入开户行信息'); + $mark = '使用银联卡'.$insertData['bank_code'].'提现'.$insertData['extract_price'].'元'; + }elseif($data['extract_type'] == 'weixin') $mark = '使用微信提现'.$insertData['extract_price'].'元'; + self::beginTrans(); + try{ + $res1 = self::set($insertData); + if(!$res1) return self::setErrorInfo('提现失败'); + $res2 = User::edit(['now_money'=>$balance],$userInfo['uid'],'uid'); + $res3 = UserBill::expend('余额提现',$userInfo['uid'],'now_money','extract',$data['money'],$res1['id'],$balance,$mark); + $res = $res2 && $res3; + if($res){ + self::commitTrans(); + //发送模板消息 + return true; + }else return self::setErrorInfo('提现失败!'); + }catch (\Exception $e){ + self::rollbackTrans(); + return self::setErrorInfo('提现失败!'); + } + } + + /** + * 获得用户最后一次提现信息 + * @param $openid + * @return mixed + */ + public static function userLastInfo($uid) + { + return self::where(compact('uid'))->order('add_time DESC')->find(); + } + + /** + * 获得用户提现总金额 + * @param $uid + * @return mixed + */ + public static function userExtractTotalPrice($uid,$status=self::SUCCESS_STATUS) + { + return self::where('uid',$uid)->where('status',$status)->value('SUM(extract_price)')?:0; + } + + /* + * 用户提现记录列表 + * @param int $uid 用户uid + * @param int $first 截取行数 + * @param int $limit 截取数 + * @return array + * */ + public static function extractList($uid,$first = 0,$limit = 8) + { + $list=UserExtract::where('uid',$uid)->order('add_time desc')->limit($first,$limit)->select(); + foreach($list as &$v){ + $v['add_time']=date('Y/m/d',$v['add_time']); + } + return $list; + } + + /* + * 获取累计已提现佣金 + * @param int $uid + * @return float + * */ + public static function extractSum($uid) + { + return self::where('uid',$uid)->where('status',1)->sum('extract_price'); + } + +} \ No newline at end of file diff --git a/application/ebapi/model/user/UserNotice.php b/application/ebapi/model/user/UserNotice.php new file mode 100644 index 00000000..fedc2e54 --- /dev/null +++ b/application/ebapi/model/user/UserNotice.php @@ -0,0 +1,57 @@ + + * @day: 2017/11/11 + */ + +namespace app\ebapi\model\user; + +use app\admin\model\user\UserNoticeSee; +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 用户通知 + * Class UserNotice + * @package app\ebapi\model\user + */ +class UserNotice extends ModelBasic +{ + use ModelTrait; + public static function getNotice($uid){ + $count_notice = self::where('uid','like',"%,$uid,%")->where("is_send",1)->count(); + $see_notice = UserNoticeSee::where("uid",$uid)->count(); + return $count_notice-$see_notice; + } + /** + * @return array + */ + public static function getNoticeList($uid,$page,$limit = 8){ + //定义分页信息 + $count = self::where('uid','like',"%,$uid,%")->count(); + $data["lastpage"] = ceil($count/$limit) <= ($page+1) ? 1 : 0; + + $where['uid'] = array("like","%,$uid,%"); +// $where['uid'] = array(array("like","%,$uid,%"),array("eq",""), 'or'); + $where['is_send'] = 1; + $list = self::where($where)->field('id,user,title,content,add_time')->order("add_time desc")->limit($page*$limit,$limit)->select()->toArray(); + foreach ($list as $key => $value) { + $list[$key]["add_time"] = date("Y-m-d H:i:s",$value["add_time"]); + $list[$key]["is_see"] = UserNoticeSee::where("uid",$uid)->where("nid",$value["id"])->count() > 0 ? 1 : 0; + } + $data["list"] = $list; + return $data; + } + /** + * @return array + */ + public static function seeNotice($uid,$nid){ + if(UserNoticeSee::where("uid",$uid)->where("nid",$nid)->count() <= 0){ + $data["nid"] = $nid; + $data["uid"] = $uid; + $data["add_time"] = time(); + UserNoticeSee::set($data); + } + } +} \ No newline at end of file diff --git a/application/ebapi/model/user/UserRecharge.php b/application/ebapi/model/user/UserRecharge.php new file mode 100644 index 00000000..718d946e --- /dev/null +++ b/application/ebapi/model/user/UserRecharge.php @@ -0,0 +1,65 @@ + + * @day: 2018/01/05 + */ + +namespace app\ebapi\model\user; + +use app\core\model\user\UserBill; +use basic\ModelBasic; +use app\core\util\MiniProgramService; +use traits\ModelTrait; + +/** 用户充值 + * Class UserRecharge + * @package app\ebapi\model\user + */ +class UserRecharge extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function addRecharge($uid,$price,$recharge_type = 'weixin',$paid = 0) + { + $order_id = self::getNewOrderId($uid); + return self::set(compact('order_id','uid','price','recharge_type','paid')); + } + + public static function getNewOrderId($uid = 0) + { + if(!$uid) return false; + $count = (int) self::where('add_time',['>=',strtotime(date("Y-m-d"))],['<',strtotime(date("Y-m-d",strtotime('+1 day')))])->count(); + return 'wx1'.date('YmdHis',time()).(10000+$count+$uid); + } + + public static function jsPay($orderInfo) + { + return MiniProgramService::jsPay(WechatUser::uidToOpenid($orderInfo['uid']),$orderInfo['order_id'],$orderInfo['price'],'user_recharge','用户充值'); + } + + /** + * //TODO用户充值成功后 + * @param $orderId + */ + public static function rechargeSuccess($orderId) + { + $order = self::where('order_id',$orderId)->where('paid',0)->find(); + if(!$order) return false; + $user = User::getUserInfo($order['uid']); + self::beginTrans(); + $res1 = self::where('order_id',$order['order_id'])->update(['paid'=>1,'pay_time'=>time()]); + $res2 = UserBill::income('用户余额充值',$order['uid'],'now_money','recharge',$order['price'],$order['id'],$user['now_money'],'成功充值余额'.floatval($order['price']).'元'); + $res3 = User::edit(['now_money'=>bcadd($user['now_money'],$order['price'],2)],$order['uid'],'uid'); + $res = $res1 && $res2 && $res3; + self::checkTrans($res); + return $res; + } +} \ No newline at end of file diff --git a/application/ebapi/model/user/UserSign.php b/application/ebapi/model/user/UserSign.php new file mode 100644 index 00000000..d6cba19d --- /dev/null +++ b/application/ebapi/model/user/UserSign.php @@ -0,0 +1,56 @@ + + * @day: 2018/02/28 + */ + +namespace app\ebapi\model\user; + + +use basic\ModelBasic; +use app\core\util\SystemConfigService; +use think\Model; + +/** 用户签到 + * Class UserSign + * @package app\ebapi\model\user + */ +class UserSign +{ + public static function checkUserSigned($uid) + { + return UserBill::be(['uid'=>$uid,'add_time'=>['>',strtotime('today')],'category'=>'integral','type'=>'sign']); + } + + public static function userSignedCount($uid) + { + return self::userSignBillWhere($uid)->count(); + } + + /** + * @param $uid + * @return Model + */ + public static function userSignBillWhere($uid) + { + return UserBill::where(['uid'=>$uid,'category'=>'integral','type'=>'sign']); + } + + public static function sign($userInfo) + { + $uid = $userInfo['uid']; + $min = SystemConfigService::get('sx_sign_min_int')?:0; + $max = SystemConfigService::get('sx_sign_max_int')?:5; + $integral = rand($min,$max); + ModelBasic::beginTrans(); + $res1 = UserBill::income('用户签到',$uid,'integral','sign',$integral,0,$userInfo['integral'],'签到获得'.floatval($integral).'积分'); + $res2 = User::bcInc($uid,'integral',$integral,'uid'); + $res = $res1 && $res2; + ModelBasic::checkTrans($res); + if($res) + return $integral; + else + return false; + } +} \ No newline at end of file diff --git a/application/ebapi/model/user/WechatUser.php b/application/ebapi/model/user/WechatUser.php new file mode 100644 index 00000000..f1d5c7d1 --- /dev/null +++ b/application/ebapi/model/user/WechatUser.php @@ -0,0 +1,127 @@ + + * @day: 2017/12/21 + */ + +namespace app\ebapi\model\user; + +use basic\ModelBasic; +use traits\ModelTrait; +use app\core\util\SystemConfigService; +use app\core\model\routine\RoutineQrcode; +use app\ebapi\model\store\StoreCouponUser; +/** + * 用户附加表 + * Class WechatUser + * @package app\ebapi\model\user + */ +class WechatUser extends ModelBasic +{ + use ModelTrait; + + public static function getOpenId($uid = ''){ + if($uid == '') return false; + return self::where('uid',$uid)->value('routine_openid'); + } + /** + * 用uid获得openid + * @param $uid + * @return mixed + */ + public static function uidToOpenid($uid) + { + $openid = self::where('uid',$uid)->value('routine_openid'); + return $openid; + } + + /** + * 用openid获得uid + * @param $uid + * @return mixed + */ + public static function openidTouid($openid) + { + return self::where('routine_openid',$openid)->value('uid'); + } + + public static function userTakeOrderGiveCoupon($uid) + { + $couponId = SystemConfigService::get('store_order_give_coupon'); + if($couponId) StoreCouponUser::addUserCoupon($uid,$couponId); + } + + + /** + * 小程序创建用户后返回uid + * @param $routineInfo + * @return mixed + */ + public static function routineOauth($routine){ + $routineInfo['nickname'] = filterEmoji($routine['nickName']);//姓名 + $routineInfo['sex'] = $routine['gender'];//性别 + $routineInfo['language'] = $routine['language'];//语言 + $routineInfo['city'] = $routine['city'];//城市 + $routineInfo['province'] = $routine['province'];//省份 + $routineInfo['country'] = $routine['country'];//国家 + $routineInfo['headimgurl'] = $routine['avatarUrl'];//头像 +// $routineInfo[''] = $routine['code'];//临时登录凭证 是获取用户openid和session_key(会话密匙) + $routineInfo['routine_openid'] = $routine['openId'];//openid + $routineInfo['session_key'] = $routine['session_key'];//会话密匙 + $routineInfo['unionid'] = $routine['unionId'];//用户在开放平台的唯一标识符 + $routineInfo['user_type'] = 'routine';//用户类型 + $page = '';//跳转小程序的页面 + $spid = 0;//绑定关系uid + //获取是否有扫码进小程序 + if($routine['code']){ + $info = RoutineQrcode::getRoutineQrcodeFindType($routine['code']); + if($info){ + $spid = $info['third_id']; + $page = $info['page']; + }else{ + $spid = $routine['spid']; + } + }else if($routine['spid']) $spid = $routine['spid']; + // 判断unionid 存在根据unionid判断 + $routineInfo['code']=$spid; + if($routineInfo['unionid'] != '' && self::be(['unionid'=>$routineInfo['unionid']])){ + self::edit($routineInfo,$routineInfo['unionid'],'unionid'); + $uid = self::where('unionid',$routineInfo['unionid'])->value('uid'); + User::updateWechatUser($routineInfo,$uid); + }else if(self::be(['routine_openid'=>$routineInfo['routine_openid']])){ //根据小程序openid判断 + self::edit($routineInfo,$routineInfo['routine_openid'],'routine_openid'); + $uid = self::where('routine_openid',$routineInfo['routine_openid'])->value('uid'); + User::updateWechatUser($routineInfo,$uid); + }else{ + $routineInfo['add_time'] = time();//用户添加时间 + $routineInfo = self::set($routineInfo); + if(User::isUserSpread($spid)) { + $res = User::setRoutineUser($routineInfo,$spid); //用户上级 + }else $res = User::setRoutineUser($routineInfo); + $uid = $res->uid; + } + $data['page'] = $page; + $data['uid'] = $uid; + return $data; + } + /** + * 判断是否是小程序用户 + * @param int $uid + * @return bool|int|string + */ + public static function isRoutineUser($uid = 0){ + if(!$uid) return false; + return self::where('uid',$uid)->where('user_type','routine')->count(); + } + + /** + * @param int $uid + * @return int + */ + public static function isUserStatus($uid = 0){ + if(!$uid) return 0; + $user = User::getUserInfo($uid); + return $user['status']; + } +} \ No newline at end of file diff --git a/application/ebapi/tags.php b/application/ebapi/tags.php new file mode 100644 index 00000000..eeabe1a5 --- /dev/null +++ b/application/ebapi/tags.php @@ -0,0 +1,29 @@ + +// +---------------------------------------------------------------------- + +// 应用行为扩展定义文件 +return [ + // 应用初始化 + 'app_init' => [], + // 应用开始 + 'app_begin' => [], + // 模块初始化 + 'module_init' => [], + // 操作开始执行 + 'action_begin' => [], + // 视图内容过滤 + 'view_filter' => [], + // 日志写入 + 'log_write' => [], + // 应用结束 + 'app_end' => [], + +];