From 6a99ae542b6decbd5767a15d1fda8b4f464b52a5 Mon Sep 17 00:00:00 2001 From: wangxinglong <2371974647@qq.com> Date: Tue, 14 Dec 2021 17:34:27 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=88=E7=89=88=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common.php | 12 +- app/controller/api/Coupon.php | 215 +++++++++++++++++------- app/controller/api/User.php | 71 +++++++- app/controller/manager/Coupon.php | 6 +- app/model/Coupon.php | 4 + app/model/CouponMain.php | 8 +- app/repository/CouponRepository.php | 2 +- app/repository/DictionaryRepository.php | 1 + app/service/Tool.php | 56 ++++++ app/traits/CouponMainTrait.php | 24 +++ app/traits/CouponTrait.php | 21 ++- app/validate/CouponRelease.php | 2 +- favicon.ico | Bin 67646 -> 0 bytes public/favicon.ico | Bin 67646 -> 4286 bytes view/manager/index/dashboard.html | 16 +- 15 files changed, 352 insertions(+), 86 deletions(-) delete mode 100644 favicon.ico diff --git a/app/common.php b/app/common.php index 52e6feb..911bfbd 100644 --- a/app/common.php +++ b/app/common.php @@ -872,4 +872,14 @@ if (!function_exists('encodeCouponCycle')) { } } - +if (!function_exists('is_mobile')) { + /** + * 判断手机号 + * @param string $num 要验证的手机号 + * @return bool + */ + function is_mobile($num) + { + return preg_match("/^1(3|4|5|6|7|8|9)\d{9}$/", $num); + } +} diff --git a/app/controller/api/Coupon.php b/app/controller/api/Coupon.php index bc759c9..1b60bff 100644 --- a/app/controller/api/Coupon.php +++ b/app/controller/api/Coupon.php @@ -9,6 +9,7 @@ use app\model\CouponMain; use app\model\Deduction; use app\model\Redpack; use app\model\Score; +use app\model\UsingRule; use app\repository\AccountRepository; use app\repository\BusinessRepository; use app\repository\CouponRepository; @@ -194,7 +195,7 @@ class Coupon extends Base try { //检查是否可以领取 0可领取 1已领取 - AccountRepository::getInstance()->getCouponReceiveStatusText($account->user_code,$couponMain);//领取状态 + AccountRepository::getInstance()->getCouponReceiveStatusText($account,$couponMain);//领取状态 }catch (RepositoryException $e){ return $this->json(4001,$e->getMessage()); } @@ -224,6 +225,7 @@ class Coupon extends Base "is_verificated" => couponMain::COMMON_OFF,//版本 未知作用 ]; CouponRepository::getInstance()->receiveCoupon($data); + $couponMain->save(["received_count"=>Db::raw("received_count + 1")]); Db::commit(); return $this->json(); }catch (RepositoryException $e){ @@ -260,7 +262,7 @@ class Coupon extends Base } $coupon = CouponRepository::getInstance()->findById($couponId,[],function ($q){ - return $q->with(["couponMain"]); + return $q->with(["couponMain","redpack"]); }); if($coupon->consumer_code != $account->user_code ){ @@ -276,14 +278,27 @@ class Coupon extends Base if($coupon->on_shelf != CouponMain::on_shelf_on){ return $this->json(4001, "优惠券下架"); } - if(strtotime($coupon->end_time) < $time){ + + + if(!isset($coupon->couponMain) || empty($coupon->couponMain)){ + return $this->json(4001, "商家优惠券信息错误"); + } + $usingRule = UsingRule::findOne(["coupon_id"=>$coupon->couponMain->id]); + if(empty($usingRule)){ + return $this->json(4001, "商家优惠券使用规则信息错误"); + } + if(strtotime($coupon->couponMain->end_time) < $time){ return $this->json(4001, "优惠券已过期"); } - if(!isset($coupon->couponMain)||empty($coupon->couponMain)){ - return $this->json(4001, "商家优惠券信息错误"); + //一天的开始时间 + if(strtotime(date("Y-m-d " . $usingRule->day_start_time)) > $time){ + return $this->json(4001, "请在当天{$usingRule->day_start_time}-{$usingRule->day_start_time}使用"); + } + //一天的结束时间 + if(strtotime(date("Y-m-d ".$usingRule->day_end_time)) < $time){ + return $this->json(4001, "请在当天{$usingRule->day_start_time}-{$usingRule->day_start_time}使用"); } - $business = BusinessRepository::getInstance()->getModel()->with(["agency"])->where(["code"=>$coupon->couponMain->business_code])->lock(true)->find(); if(empty($business)){ return $this->json(4001, "商家不存在"); @@ -298,90 +313,111 @@ class Coupon extends Base try { // 1. 修改优惠券状态 $coupon->save([ - "is_verificated"=>CouponModel::is_verificated_on, - "used_time"=>date("Y-m-d H:i:s" ,$time), - "verificate_time"=>date("Y-m-d H:i:s" ,$time) + "is_verificated" => CouponModel::is_verificated_on, + "used_time" => date("Y-m-d H:i:s" ,$time), + "verificate_time" => date("Y-m-d H:i:s" ,$time), + ]); + $coupon->couponMain->save([ + "verification_count" => Db::raw("verification_count + 1"),//已验证数量+1 + "using_count" => Db::raw("using_count - 1"),//进行中数量-1 ]); + //可分配金额 - $deductionMoney = $coupon->couponMain->deduction_money; - $agencyMoney = ($deductionMoney/100) * $coupon->couponMain->commission_agency; - $adminMoney = ($deductionMoney/100) * $coupon->couponMain->commission_admin; - $consumerMoney = ($deductionMoney/100) * $coupon->couponMain->commission_consumer; + $deductionMoney = $coupon->couponMain->deduction_money; + $agencyMoney = (($deductionMoney/100) * $coupon->couponMain->commission_agency); + $adminMoney = (($deductionMoney/100) * $coupon->couponMain->commission_admin); + $consumerMoney = (($deductionMoney/100) * $coupon->couponMain->commission_consumer); + $agencyMoney = round($agencyMoney,2); //四舍五入 精确到分 + $adminMoney = round($adminMoney,2); //四舍五入 精确到分 + $consumerMoney = round($consumerMoney,2); //四舍五入 精确到分 // 2. 写入优惠券流水 $couponBillData = [ - "coupon_main_id"=>$coupon->couponMain->id, - "coupon_id"=>$coupon->id, - "user_code"=>$account->user_code, - "agency_code"=>$business->agency_code, - "commission_agency"=>$coupon->couponMain->commission_agency, - "commission_admin"=>$coupon->couponMain->commission_admin, - "commission_consumer"=>$coupon->couponMain->commission_consumer, - "money"=>$coupon->couponMain->money, - "agency_money"=>$agencyMoney, - "admin_money"=>$adminMoney, - "consumer_money"=>$consumerMoney, - "lat"=>$lat, - "lng"=>$lng, + "coupon_main_id" =>$coupon->couponMain->id, + "coupon_id" =>$coupon->id, + "user_code" =>$account->user_code, + "agency_code" =>$business->agency_code, + "commission_agency" =>$coupon->couponMain->commission_agency, + "commission_admin" =>$coupon->couponMain->commission_admin, + "commission_consumer" =>$coupon->couponMain->commission_consumer, + "money" =>$coupon->couponMain->money, + "agency_money" =>$agencyMoney, + "admin_money" =>$adminMoney, + "consumer_money" =>$consumerMoney, + "lat" =>$lat, + "lng" =>$lng, ]; $couponBill = CouponBill::create($couponBillData); // 3. 写入商家扣费记录 $deductionData = [ - "money"=>$deductionMoney, - "business_code"=>$business->code, - "business_name"=>$business->business_name, - "balance"=>$business->balance - $deductionMoney, - "reason"=> sprintf("[%s]验证优惠券[%s]扣除[%s]",$account->nick_name, $coupon->couponMain->name,$deductionMoney), - "coupon_main_id"=> $coupon->couponMain->id, - "coupon_id"=> $coupon->id, - "bill_id"=> $couponBill->id, - "create_time"=> date("Y-m-d H:i:s",$time), + "money" => $deductionMoney, + "business_code" => $business->code, + "business_name" => $business->business_name, + "balance" => $business->balance - $deductionMoney, + "reason" => sprintf("[%s]验证优惠券[%s]扣除[%s]",$account->nick_name, $coupon->couponMain->name,$deductionMoney), + "coupon_main_id" => $coupon->couponMain->id, + "coupon_id" => $coupon->id, + "bill_id" => $couponBill->id, + "create_time" => date("Y-m-d H:i:s",$time), ]; Deduction::create($deductionData); //4. 商家扣钱 - $business->save(["balance"=>$business->balance - $deductionMoney]); + $business->save(["balance"=>Db::raw("balance - {$deductionMoney}")]); //5. 渠道商加钱 - if(isset($business->agency)&&$business->agency){ + if(isset($business->agency) && $business->agency){ $business->agency->inc("balance",$agencyMoney)->update(); } - //6. 用户提现到零钱 - $RedpackData =[ - "mch_billno"=>createUuid(), - "openid"=>$account->open_id, - "user_code"=>$account->user_code, - "money"=>$consumerMoney*100, - ]; - $redpackModelData = Redpack::create($RedpackData); - $payment = WechatPay::getInstance(); + //6. 用户提现到零钱 写入红包记录 + if($consumerMoney > 0){ + $payment = WechatPay::getInstance(); - $redpack = $payment->redpack; - $res = $redpackData = [ - 'mch_billno' => $time.randomStr(0,10), - 'send_name' => '红包', - 're_openid' => $redpackModelData->openid, - 'total_num' => 1, //固定为1,可不传 - 'total_amount' => $redpackModelData->money, //单位为分,不小于100 - 'wishing' => '恭喜发财', - 'client_ip' => $this->request->ip(), //可不传,不传则由 SDK 取当前客户端 IP - 'act_name' => '验证优惠券得红包', - 'remark' => '验证优惠券得红包',//测试备注 - // ... - ]; + //如果付款过一次了 就查询付款状态 + if(isset($coupon->redpack)&&$coupon->redpack){ + $result = $payment->transfer->queryBalanceOrder($coupon->redpack->mch_billno); + //var_dump($result); + //企业付款成功 + if(isset($result["status"])&&$result["status"]=="SUCCESS"){ + Db::commit(); + return $this->json(); + } + Log::info("查询企业付款失败:".json_encode($result,JSON_UNESCAPED_UNICODE)); + }else{ + $mch_billno = createUuid(); + $amount = $consumerMoney*100; + $toBalanceData = [ + 'partner_trade_no' =>$mch_billno,// 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号) + 'openid' => $account->open_id, + 'check_name' => 'NO_CHECK',// NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名 + 'amount' => $amount, //单位为分,不小于100 + 'desc' => '验证优惠券签到', + ]; + $result = $payment->transfer->toBalance($toBalanceData); + //var_dump($result); - $result = $redpack->sendNormal($redpackData); - var_dump($result); + //付款成功才提交 + if(isset($result['payment_no'])){ + Db::commit(); + return $this->json(); + } + Log::info("企业发起付款失败:".json_encode($result,JSON_UNESCAPED_UNICODE)); + } - Db::rollback(); + //默认回滚 + Db::rollback(); + return $this->json(5001, "验证失败,发放红包失败"); + } + Db::commit(); + return $this->json(); }catch (RepositoryException $e){ Db::rollback(); - return $this->json(5001, "服务器错误"); + return $this->json(5001, "Repository服务器错误"); }catch (\Exception $e){ - echo $e->getMessage(); + //echo $e->getMessage(); Db::rollback(); return $this->json(5002, "服务器错误"); } @@ -462,7 +498,10 @@ class Coupon extends Base $couponMain['money'] = floor($couponMain['money'] * 100) / 100; $totalMoney = $couponMain['money'] * $couponMain['count']; - if ($account->business["balance"] < $totalMoney) { + //未领取的优惠券 + $NotClaimedMoney = CouponRepository::getInstance()->getBusinessNotClaimedCoupon($account->business["code"]); + + if ($account->business["balance"] < ($totalMoney + $NotClaimedMoney)) { return $this->json(4001, '商家余额不足'); } @@ -706,4 +745,50 @@ class Coupon extends Base return $this->json(0,"success",$couponMain->toArray()); } + + /** + * 已使用优惠券 评分 + * */ + public function score() + { + $accountId = $this->request->user['user_id'] ?? 0; + $couponId = input("couponId/d",0); + $score = input("score/d",5); + + if($score > 5|| $score <= 0){ + return $this->json(4001, "参数错误"); + } + $account = AccountRepository::getInstance()->findById($accountId, [], function ($q) { + return $q->with(['business', 'parent']); + }); + + if(empty($account)){ + return $this->json(6001,"无效的用户"); + } + + $coupon = CouponRepository::getInstance()->findById($couponId,[],function ($q){ + return $q->with(["scoreModel"]); + }); + + if($coupon->consumer_code != $account->user_code ){ + return $this->json(4001, "参数错误"); + } + + if(isset($score->scoreModel) && $score->scoreModel){ + return $this->json(4001, "已经评论过了"); + } + try { + $coupon->scoreModel()->save([ + "user_code"=>$account->user_code, + "business_code"=>$coupon->business_code, + "score"=>$score, + "coupon_id"=>$coupon->id, + "create_time"=>date("Y-m-d H:i:s"), + ]); + return $this->json(); + }catch (RepositoryException| \Exception $e){ + return $this->json(4001, "评分失败"); + } + + } } \ No newline at end of file diff --git a/app/controller/api/User.php b/app/controller/api/User.php index b429a7b..470cd9f 100644 --- a/app/controller/api/User.php +++ b/app/controller/api/User.php @@ -8,11 +8,13 @@ use app\repository\BusinessRepository; use app\repository\CouponRepository; use app\service\File; use app\service\Jwt; +use app\service\Tool; use app\service\wx\WechatApplets; use app\validate\User as UserValidate; use EasyWeChat\Kernel\Exceptions\InvalidConfigException; use Exception; use think\exception\ValidateException; +use think\facade\Config; use think\response\Json; /** @@ -24,7 +26,7 @@ use think\response\Json; class User extends Base { protected $noNeedLogin = [ - 'login', + 'login','checkNewAccount',"decodeMobile" ]; /** @@ -40,6 +42,8 @@ class User extends Base 'nick_name' => $this->request->param('nickName', ''), 'avatar_url' => $this->request->param('avatarUrl', ''), 'gender' => $this->request->param('gender', 0), + 'real_name' => $this->request->param('real_name/s', '',"trim"), + 'mobile' => $this->request->param('mobile/s', ''), ]; $validate = new UserValidate(); @@ -69,6 +73,12 @@ class User extends Base $nowDate = date('Y-m-d H:i:s'); if (!$account) { + if(empty($params['real_name'])){ + return $this->json(4001, '真实姓名不能为空'); + } + if(!is_mobile($params['mobile'])){ + return $this->json(4001, '手机号格式错误'); + } // 自动注册 $account = $repo->create([ 'user_code' => createUuid(), // 用户UUID @@ -79,6 +89,8 @@ class User extends Base 'nick_name' => $params['nick_name'] ?: generateDefaultNickName(), 'avatar_url' => $params['avatar_url'] ?: Account::DEFAULT_AVATAR, 'gender' => $params['gender'], + 'real_name' => $params['real_name'], + 'mobile' => $params['mobile'], ]); } else { @@ -226,4 +238,61 @@ class User extends Base } } + //检查是新用户还是老用户 + public function checkNewAccount() + { + Config::load('extra/wechat', 'wechat'); + $config = config('wechat'); + $code = $this->request->param('code/s'); + $appId = $config["applets_appId"]??'';//appid + $appSecret = $config["applets_appSecret"]??'';//appsecret + $url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' + . $appId + . '&secret=' + . $appSecret + . '&js_code=' + . $code + . '&grant_type=authorization_code'; + $data = json_decode(Tool::httpRequest($url, "get"), true); + //返回状态 + if (isset($data["openid"])) { + $account = AccountRepository::getInstance()->findByOpenID($data["openid"]); + if(empty($account)){ + return $this->json(0, "fail",["isNewAccount"=>true,"session_key"=>$data["session_key"]]); + } + return $this->json(0, "fail",["isNewAccount"=>false,"session_key"=>$data["session_key"]]); + } + return $this->json(0, "fail",["isNewAccount"=>true]); + } + + /** + * 解密手机号 + * */ + public function decodeMobile() + { + $params = input('post.'); + $rules = [ + 'encryptedData|加密数据' => 'require', + 'iv|IV' => 'require', + 'session_key|会话标识' => 'require', + ]; + + $validate = $this->validateByApi($params, $rules); + + if ($validate !== true) { + return $validate; + } + + // 解密手机相关数据 + $minApp = WechatApplets::getInstance(); + $sessionKey = $params['session_key'] ?? ''; + $decryptData = $minApp->encryptor->decryptData($sessionKey, $params['iv'], $params['encryptedData']); + $phone = $decryptData['phoneNumber'] ?? ''; // 通过iv和加密数据 解密出手机号 + + if ($phone) { + return $this->json(0,"success",["mobile"=>$phone]); + } + return $this->json(5001,"获取手机号失败"); + } + } \ No newline at end of file diff --git a/app/controller/manager/Coupon.php b/app/controller/manager/Coupon.php index d4fbf75..aaa3da8 100644 --- a/app/controller/manager/Coupon.php +++ b/app/controller/manager/Coupon.php @@ -225,7 +225,11 @@ class Coupon extends Base $data['money'] = floor($data['money'] * 100) / 100; $totalMoney = $data['money'] * $data['count']; - if ($business["balance"] < $totalMoney) { + + //未领取的优惠券 + $NotClaimedMoney = CouponRepository::getInstance()->getBusinessNotClaimedCoupon($account->business["code"]); + + if ($business["balance"] < ($totalMoney + $NotClaimedMoney)) { return $this->json(4001, '商家余额不足'); } diff --git a/app/model/Coupon.php b/app/model/Coupon.php index d9dd88f..e94324b 100644 --- a/app/model/Coupon.php +++ b/app/model/Coupon.php @@ -41,4 +41,8 @@ class Coupon extends Base { return $this->hasOne(Score::class, 'coupon_id', 'id'); } + public function redpack() + { + return $this->hasOne(Redpack::class, 'coupon_id', 'id'); + } } \ No newline at end of file diff --git a/app/model/CouponMain.php b/app/model/CouponMain.php index a5a95a4..46709ad 100644 --- a/app/model/CouponMain.php +++ b/app/model/CouponMain.php @@ -32,11 +32,13 @@ class CouponMain extends Base { return $this->hasOne(UsingRule::class, 'coupon_id',"id"); } + //创建完成之后 public static function onAfterInsert( $obj) { - $obj->sort = $obj->id; - $obj->using_count = $obj->count; - $obj->received_count = 0; + $obj->sort = $obj->id; + $obj->using_count = $obj->count; + $obj->received_count = 0; + $obj->verification_count = 0; $obj->save(); } } \ No newline at end of file diff --git a/app/repository/CouponRepository.php b/app/repository/CouponRepository.php index 6014051..048db46 100644 --- a/app/repository/CouponRepository.php +++ b/app/repository/CouponRepository.php @@ -79,7 +79,7 @@ class CouponRepository extends Repository //创建优惠券使用规则 $usingRule["coupon_id"] = $couponMain->id; UsingRule::create($usingRule); - Business::where("code", $data["business_code"])->dec("balance", $totalMoney)->update(); + //Business::where("code", $data["business_code"])->dec("balance", $totalMoney)->update(); } /** diff --git a/app/repository/DictionaryRepository.php b/app/repository/DictionaryRepository.php index 0660ea0..7e9cb1a 100644 --- a/app/repository/DictionaryRepository.php +++ b/app/repository/DictionaryRepository.php @@ -174,6 +174,7 @@ class DictionaryRepository extends Repository } return "
该优惠券可以在" . encodeCouponCycle($usingRule->cycle) . "进行使用
该优惠券可以在每天的" . $usingRule->day_start_time ."到" .$usingRule->day_end_time ."进行使用
+
该优惠券每天一共可以领取". $usingRule->day_total ."张
该优惠券每天每人可以领取". $usingRule->person_day_total ."张
该优惠券每人总共可以领取". $usingRule->person_total ."张
"; } diff --git a/app/service/Tool.php b/app/service/Tool.php index 89e7a0a..87c2f5b 100644 --- a/app/service/Tool.php +++ b/app/service/Tool.php @@ -50,4 +50,60 @@ class Tool { return str_replace(' ', '', trim($str)); } + + /** + * CURL请求 + * @param $url 请求url地址 + * @param $method 请求方法 get post + * @param null $postfields post数据数组 + * @param array $headers 请求header信息 + * @param bool|false $debug 调试开启 默认false + * @return mixed + */ + static function httpRequest($url, $method = "post", $postfields = null, $headers = array(), $debug = false) + { + $method = strtoupper($method); + $ci = curl_init(); + /* Curl settings */ + curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0"); + curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间,如果设置为0,则无限等待 */ + curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */ + curl_setopt($ci, CURLOPT_RETURNTRANSFER, true); + switch ($method) { + case "POST": + curl_setopt($ci, CURLOPT_POST, true); + if (!empty($postfields)) { + $tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields; + curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr); + } + break; + default: + curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */ + break; + } + $ssl = preg_match('/^https:\/\//i', $url) ? TRUE : FALSE; + curl_setopt($ci, CURLOPT_URL, $url); + if ($ssl) { + curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts + curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在 + } + curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($ci, CURLOPT_MAXREDIRS, 2);/*指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的*/ + curl_setopt($ci, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ci, CURLINFO_HEADER_OUT, true); + $response = curl_exec($ci); + $requestinfo = curl_getinfo($ci); + if ($debug) { + echo "=====post data======\r\n"; + var_dump($postfields); + echo "=====info===== \r\n"; + print_r($requestinfo); + echo "=====response=====\r\n"; + print_r($response); + } + curl_close($ci); + return $response; + } + } diff --git a/app/traits/CouponMainTrait.php b/app/traits/CouponMainTrait.php index 278797e..b1fd56b 100644 --- a/app/traits/CouponMainTrait.php +++ b/app/traits/CouponMainTrait.php @@ -49,4 +49,28 @@ trait CouponMainTrait ->where("is_verificated",Coupon::is_verificated_on) ->count(); } + + /** + * 获取商户没有被领取的优惠券 需要扣除多少钱 + * */ + public function getBusinessNotClaimedCoupon($businessCode) + { + $date = date("Y-m-d"); + $totalDeductionMoney = 0; + $couponMain = CouponMain::where("business_code", $businessCode) + ->where("status", CouponMain::status_on) + ->where("on_shelf", CouponMain::on_shelf_on) + ->whereTime("start_time", "<=", $date) + ->whereTime("end_time", ">=", $date) + ->whereRaw(" verification_count < count ") + ->field("id,(deduction_money * (count - verification_count)) as total_deduction_money") + ->select() + ->toArray(); + + foreach ($couponMain as $item) { + $totalDeductionMoney += $item["total_deduction_money"]; + } + return $totalDeductionMoney; + + } } \ No newline at end of file diff --git a/app/traits/CouponTrait.php b/app/traits/CouponTrait.php index b3536ae..a4d1db9 100644 --- a/app/traits/CouponTrait.php +++ b/app/traits/CouponTrait.php @@ -3,6 +3,7 @@ namespace app\traits; use app\exception\RepositoryException; +use app\model\Account; use app\model\CouponMain; use app\model\UsingRule; use think\Model; @@ -102,7 +103,7 @@ trait CouponTrait /** * 查看某个优惠券的是否可以领取 0 可以领取 1 已领取不能再领取 - * @param $accountCode + * @param Account $account * @param CouponMain $couponMain * @return void * @throws RepositoryException @@ -110,11 +111,11 @@ trait CouponTrait * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ - public function getCouponReceiveStatusText($accountCode,CouponMain $couponMain ) + public function getCouponReceiveStatusText(Account $account,CouponMain $couponMain ) { //没有领取记录就可以领取 $ReceiveCount = Coupon::where("coupon_id",$couponMain->id) - ->where("consumer_code",$accountCode)->count(); + ->where("consumer_code",$account->user_code)->count(); //确定使用规则 @@ -135,7 +136,7 @@ trait CouponTrait //单人日限量 $todayReceivesCount = Coupon::where("coupon_id",$couponMain->id) - ->where("consumer_code",$accountCode) + ->where("consumer_code",$account->user_code) ->whereTime("received_time","between",[date("Y-m-d 00:00:00"),date("Y-m-d 23:59:59")]) ->count(); if($todayReceivesCount >= $usingRule->person_day_total ){ @@ -147,10 +148,20 @@ trait CouponTrait throw new RepositoryException("单人总限量达到上限"); } + //白名单 + if(!empty($couponMain->white_list)){ + if (empty($account->real_name) || empty($account->mobile)) { + throw new RepositoryException("请先授权手机号和真实姓名"); + } + if (false === strpos($couponMain->white_list, $account->mobile . "-" . $account->real_name)) { + throw new RepositoryException("您没有在该优惠券白名单内"); + } + } - + //领取不做限制 使用才做限制 + return; $time = time(); //一天的开始时间 if(strtotime(date("Y-m-d " . $usingRule->day_start_time)) > $time){ diff --git a/app/validate/CouponRelease.php b/app/validate/CouponRelease.php index 9d5f740..ca7ebf9 100644 --- a/app/validate/CouponRelease.php +++ b/app/validate/CouponRelease.php @@ -16,7 +16,7 @@ class CouponRelease extends Validate 'end_time|结束时间' => 'require|date|checkEndTime', 'name|优惠券名称' => 'require|length:3,32', 'money|金额' => 'require|>:0|<:5000', -// 'deduction_money|扣除金额' => 'require|>=:0|<:5000', + 'deduction_money|扣除金额' => 'require|>=:0.1|<:5000', //'image_url|预览图' => '', //'using_rule|使用规则' => '', //'punishing_rule|处罚规则' => '', diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index 20232b9ce97c56b910bc79bfbce8dc5d0666a5be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67646 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 -
+
@@ -68,7 +68,7 @@
-
+

分销排行榜 查看全部 @@ -84,31 +84,31 @@
- + -
用户管理
+
消费者管理
-
+
渠道管理
-
+
预约管理
-
+
报告管理
-
+