| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- <?php
- /**
- * 对接桃牛接口
- * @author: lyh
- * @date: 2019/4/3
- */
- namespace App\Http\Controllers\Api;
- use App\Http\Controllers\Controller;
- use App\Modes\AdverAlarm;
- use App\Modes\AdverDeductLog;
- use App\Modes\Advertising;
- use App\Modes\AdverVisit;
- use App\Modes\Area;
- use App\Modes\Config;
- use App\Modes\Industry;
- use Carbon\Carbon;
- use Illuminate\Http\Request;
- class TaoniuController extends Controller
- {
- /**
- * 桃牛获取广告接口
- * @author lyh
- * @date 2019/4/3
- * @description
- * 要求:筛选条件包括:关键字、地区、行业、数量
- * @todo 待定
- */
- public function adver(Request $request)
- {
- $validator = \Validator::make($param = $request->all(), [
- 'keyword' => 'min:1', // 查询-关键字
- 'industry' => 'exists:industry,content', // 查询-行业
- 'province' => 'exists:area,name', // 查询-省
- 'city' => 'exists:area,name', // 查询-市
- 'district' => 'exists:area,name', // 查询-区
- 'num' => 'required|integer', //查询-提取广告数量
- 'shop_master_id' => 'required|integer',// 防作弊-主商家id
- //'shop_slave_id' => 'required|integer',//防作弊-子商家id、
- //'user_industry' => 'required|exists:industry,content', // 防作弊-当前登录用户的所在的行业
- //'uid' => 'required|integer', //防作弊-用户id
- 'ip' => 'required|ipv4', // 防作弊-ip
- 'is_free' => 'required|integer|between:0,1', //防作弊 0-扣费 1-免费
- 'type' => 'required|integer|between:1,2' // 防作弊-1-点击、2-浏览、3-展现
- ]);
- if ($validator->fails()) {
- return showJsonErr($validator->errors()->first());
- }
- $adver = Advertising::select(['id', 'scene', 'title', 'image', 'scene', 'image_group', 'content', 'redirect'])
- ->where('residue_num', '>=', 1)
- ->where('status', 3)
- ->limit($param['num'])
- ->orderBy(\DB::raw('rand()')); // @TODO 随机待优化
- // 关键字查询
- if (!empty($param['keyword'])) {
- $adver->where('title', 'like', "%{$param['keyword']}%");
- }
- // 行业查询
- if (!empty($param['industry'])) {
- $adver->where('industry', Industry::whereContent($param['industry'])->select('id')->first()->id);
- }
- // 省级查询
- if (!empty($param['province'])) {
- $adver->where('province', Area::whereName($param['province'])->select(['id'])->first()->id);
- }
- // 地级市查询
- if (!empty($param['city'])) {
- $adver->where('city', Area::whereName($param['city'])->select(['id'])->first()->id);
- }
- // 县区查询
- if (!empty($param['district'])) {
- $adver->where('district', Area::whereName($param['district'])->select(['id'])->first()->id);
- }
- $res = $adver->get();
- if (empty($res)) {
- return showJsonErr(1012);
- }
- $param['adver'] = collect($res)->pluck('id');
- $param['ip'] = $request->ip();
- if (!empty($param['shop_slave_id'])) {
- }
- $param['shop_id'] = $param['shop_master_id'] . '-' . $param['shop_slave_id'];
- // 保存广告获取日志
- AdverVisit::insertGetId($param);
- $remark = [];
- if ($res->isNotEmpty() && $param['is_free'] == 0) {
- foreach ($res as $ad) {
- $param['adver_id'] = $ad->id;
- // 扣费
- $remark = $this->deduction($param);
- }
- }
- return showJsonSucc(1001, ['data' => $res, 'remark' => $remark]);
- }
- /**
- * 广告扣费
- * @author lyh
- * @date 2019/4/3
- * @description
- * 要求:支持批量
- * 预计要做的防作弊规则是这样:
- * 1. 根据同用户点击同一个商家,某个时间段M内,最多只能N次生效
- * 2. 根据同IP点击同一个商家,某个时间段M内,最多只能N次生效
- * 3. 根据同一个用户,点击同一个行业的某个商家,某个时间段M内,最多只能N次生效
- * 4. 根据同一个IP,点击同一个行业的某个商家,某个时间段M内,最多只能N次生效
- *
- */
- public function adverDeduction(Request $request)
- {
- $validator = \Validator::make($param = $request->all(), [
- 'uid' => 'required|integer',
- 'shopId' => 'required|integer',
- 'ip' => 'required',
- 'industry' => 'required|exists:industry,content',
- 'adver_id' => 'required|exists:advertising,id',
- 'is_free' => 'required|integer|between:0,1', // 0-扣费 1-免费
- 'type' => 'required|integer|between:1,3' // 1-点击、2-浏览、3-展现
- ]);
- if ($validator->fails()) {
- return showJsonErr($validator->errors()->first());
- }
- $param['industry'] = Industry::whereContent($param['industry'])->first()->id;
- // 请求记录
- AdverDeductLog::insertGetId([
- 'uid' => $param['uid'],
- 'shop_id' => $param['shopId'],
- 'ip' => $param['ip'],
- 'industry' => $param['industry'],
- 'adver_id' => $param['adver_id'],
- 'is_free' => $param['is_free'],
- 'type' => $param['type']
- ]);
- // 对广告统计
- switch ($param['type']) {
- case 1:
- Advertising::whereId($param['adver_id'])->increment('click_num');
- break;
- case 2:
- Advertising::whereId($param['adver_id'])->increment('browse_num');
- break;
- case 3:
- Advertising::whereId($param['adver_id'])->increment('show_num');
- break;
- default;
- }
- $remark = [];
- if ($param['is_free'] == 0) {
- /**********根据同用户点击同一个商家,某个时间段M内,最多只能N次生效**********/
- $where = [['adver_id', '=', $param['adver_id']], ['uid', ' = ', $param['uid']], ['shop_id', ' = ', $param['shopId']]];
- $re = $this->checkCache($adver_id = $param['adver_id'], $keyStart = 'user', $keyEnd = 'shoper', $paramStart = $param['uid'], $paramEnd = $param['shopId'], $where);
- if (is_string($re)) {
- $remark[] = $re;
- }
- /**********根据同IP点击同一个商家,某个时间段M内,最多只能N次生效**********/
- $where = [['adver_id', ' = ', $param['adver_id']], ['ip', ' = ', $param['ip']], ['shop_id', ' = ', $param['shop_id']]];
- $re = $this->checkCache($adver_id = $param['adver_id'], $keyStart = 'ip', $keyEnd = 'shoper', $paramStart = $param['ip'], $paramEnd = $param['shopId'], $where);
- if (is_string($re)) {
- $remark[] = $re;
- }
- /**********根据同一个用户,点击同一个行业的某个商家,某个时间段M内,最多只能N次生效**********/
- $where = [['adver_id', ' = ', $param['adver_id']], ['uid', ' = ', $param['uid']], ['industry', ' = ', $param['industry']]];
- $re = $this->checkCache($adver_id = $param['adver_id'], $keyStart = 'user', $keyEnd = 'industry', $paramStart = $param['uid'], $paramEnd = $param['industry'], $where);
- if (is_string($re)) {
- $remark[] = $re;
- }
- /**********根据同一个IP,点击同一个行业的某个商家,某个时间段M内,最多只能N次生效**********/
- $where = [['adver_id', ' = ', $param['adver_id']], ['ip', ' = ', $param['ip']], ['industry', ' = ', $param['industry']]];
- $re = $this->checkCache($adver_id = $param['adver_id'], $keyStart = 'ip', $keyEnd = 'industry', $paramStart = $param['ip'], $paramEnd = $param['industry'], $where);
- if (is_string($re)) {
- $remark[] = $re;
- }
- if (!empty($remark)) {
- return showJsonErr('扣费失败', $remark);
- }
- $adver = Advertising::find($param['adver_id']);
- if ($adver->residue_num <= 0) {
- return showJsonErr("广告[ID:{$param['adver_id']},剩余次数为{$adver->residue_num}");
- }
- $res = Advertising::whereId($param['adver_id'])->decrement('residue_num');
- if (empty($res)) {
- return showJsonErr("广告[id:{$param['adver_id']}]扣费失败");
- }
- // 广告过期
- $adver = Advertising::whereId($param['adver_id'])->select(['residue_num'])->first();
- if ($adver->residue_num <= 0) {
- Advertising::whereId($param['adver_id'])->update(['status' => 9]);
- // todo 告诉广告发布者广告到期?
- }
- }
- return showJsonSucc("广告[id:{$param['adver_id']}]请求成功", $remark);
- }
- /**
- * 分享计费
- * @author lyh
- * @date 2019/4/3
- * @param \Request $request
- * @description
- * todo 待定
- */
- public function shareBilling(\Request $request)
- {
- }
- /**
- * @author lyh
- * @date 2019/4/4
- * @param $duration
- * @param $time
- * @return array
- * @description
- */
- private function sendMsg($adverId, $duration, $time, $where = [], $remark = '%s')
- {
- $afterTime = Carbon::now()->subMinute($duration);
- $requestNum = AdverDeductLog::whereBetween('created_at', [$afterTime, Carbon::now()])
- ->where($where)
- ->count('id');
- // 如果请求次数过多,则发送消息给城市运营商
- // if ($requestNum > $time) {
- $remark = sprintf($remark, $requestNum);
- $adver = Advertising::find($adverId);
- // todo
- AdverAlarm::insert([
- 'uid' => $adver->uid, // 广告发布人
- 'province' => $adver->province,
- 'city' => $adver->city,
- 'district' => $adver->district,
- 'remark' => $remark
- ]);
- // }
- }
- private function checkCache($adverId, $keyStart, $keyEnd, $paramStart, $paramEnd, $where)
- {
- $prefix = sprintf('%sAND%s_', strtoupper($keyStart), strtoupper($keyEnd));
- $duration = Config::getValue("{$prefix}DURATION");
- $time = Config::getValue("{$prefix}TIME");
- $cachekey = sprintf(' %sAnd%s_%s_%s', $keyStart, $keyEnd, $paramStart, $paramEnd);
- $attri = [
- 'user' => '用户',
- 'shoper' => '商家',
- 'ip' => 'IP',
- 'industry' => '行业'
- ];
- $msgStart = $attri[$keyStart];
- $msgEnd = $attri[$keyEnd];
- $commonComment = sprintf('%s[%s]点击%s[%s],在%s分钟内', $msgStart, $paramStart, $msgEnd, $paramEnd, $duration);
- if (\Cache::has($cachekey)) {
- $usdtNum = \Cache::get($cachekey);
- if ($usdtNum >= $time) {
- // todo 发送消息给谁
- $this->sendMsg($adverId, $duration, $time, $where, $remark = $commonComment . "请求了[%s]次");
- // return showJsonErr('触发失败'); // todo 修改提示内容
- $remark = sprintf("[对接提醒:该消息内容正式上线会去除]: %s生效了%s次", $commonComment, $usdtNum);
- return $remark;
- } else {
- \Cache::increment($cachekey);
- }
- } else {
- \Cache::add($cachekey, 1, $duration);
- }
- return true;
- }
- /**
- * 获取广告扣费
- * @author lyh
- * @date 2019/4/19
- * @param $param
- * @return array
- * @description
- */
- private function deduction($param)
- {
- $param['industry'] = Industry::whereContent($param['user_industry'])->first()->id;
- // 请求记录
- AdverDeductLog::insertGetId([
- 'uid' => $param['uid'],
- 'shop_id' => $param['shop_id'],
- 'ip' => $param['ip'],
- 'industry' => $param['industry'],
- 'adver_id' => $param['adver_id'],
- 'is_free' => $param['is_free'],
- 'type' => $param['type'],
- 'shop_slave_id' => $param['shop_slave_id'],
- 'shop_master_id' => $param['shop_master_id']
- ]);
- // 对广告统计
- switch ($param['type']) {
- case 1:
- Advertising::whereId($param['adver_id'])->increment('click_num');
- break;
- case 2:
- Advertising::whereId($param['adver_id'])->increment('browse_num');
- break;
- case 3:
- Advertising::whereId($param['adver_id'])->increment('show_num');
- break;
- default;
- }
- $remark = [];
- if ($param['is_free'] == 0) {
- /**********根据同用户点击同一个商家,某个时间段M内,最多只能N次生效**********/
- $where = [['adver_id', '=', $param['adver_id']], ['uid', ' = ', $param['uid']], ['shop_id', ' = ', $param['shop_id']]];
- $re = $this->checkCache($adver_id = $param['adver_id'], $keyStart = 'user', $keyEnd = 'shoper', $paramStart = $param['uid'], $paramEnd = $param['shop_id'], $where);
- if (is_string($re)) {
- $remark[] = $re;
- }
- /**********根据同IP点击同一个商家,某个时间段M内,最多只能N次生效**********/
- $where = [['adver_id', ' = ', $param['adver_id']], ['ip', ' = ', $param['ip']], ['shop_id', ' = ', $param['shop_id']]];
- $re = $this->checkCache($adver_id = $param['adver_id'], $keyStart = 'ip', $keyEnd = 'shoper', $paramStart = $param['ip'], $paramEnd = $param['shop_id'], $where);
- if (is_string($re)) {
- $remark[] = $re;
- }
- /**********根据同一个用户,点击同一个行业的某个商家,某个时间段M内,最多只能N次生效**********/
- $where = [['adver_id', ' = ', $param['adver_id']], ['uid', ' = ', $param['uid']], ['industry', ' = ', $param['industry']]];
- $re = $this->checkCache($adver_id = $param['adver_id'], $keyStart = 'user', $keyEnd = 'industry', $paramStart = $param['uid'], $paramEnd = $param['industry'], $where);
- if (is_string($re)) {
- $remark[] = $re;
- }
- /**********根据同一个IP,点击同一个行业的某个商家,某个时间段M内,最多只能N次生效**********/
- $where = [['adver_id', ' = ', $param['adver_id']], ['ip', ' = ', $param['ip']], ['industry', ' = ', $param['industry']]];
- $re = $this->checkCache($adver_id = $param['adver_id'], $keyStart = 'ip', $keyEnd = 'industry', $paramStart = $param['ip'], $paramEnd = $param['industry'], $where);
- if (is_string($re)) {
- $remark[] = $re;
- }
- $adver = Advertising::find($param['adver_id']);
- if ($adver->residue_num <= 0) {
- $remark[] = "广告[ID:{$param['adver_id']},剩余次数为{$adver->residue_num}";
- }
- $res = Advertising::whereId($param['adver_id'])->decrement('residue_num');
- if (empty($res)) {
- $remark[] = "广告[id:{$param['adver_id']}]扣费失败";
- }
- // 广告过期
- $adver = Advertising::whereId($param['adver_id'])->select(['residue_num'])->first();
- if ($adver->residue_num <= 0) {
- Advertising::whereId($param['adver_id'])->update(['status' => 9]);
- // todo 告诉广告发布者广告到期?
- }
- }
- return $remark;
- }
- }
|