* @version : Huomp 1.0 */ namespace huomp\controller\finance; use huo\controller\agent\AgentCache; use huo\controller\common\Base; use huo\controller\member\MemCache; use huo\model\finance\SettleModel; use huo\model\log\DayMemLogModel; use huo\model\member\MemberModel; use huo\model\member\MemoauthModel; use huo\model\user\AgentExtModel; use huo\model\user\UserModel; use huolib\constant\MemConst; use huolib\constant\OauthConst; use huolib\constant\SettleConst; use huolib\tool\StrUtils; use huomp\logic\finance\SettleLogLogic; use think\Db; class RiskAnalysis extends Base { const ALARM_TYPE_REMAIN = 'remain';/* 告警类型 留存 */ const ALARM_TYPE_WITHDRAW = 'withdraw';/* 告警类型 提现比 */ const ALARM_TYPE_EXPAND = 'expand';/* 告警类型 拓展比 */ const ALARM_TYPE_WECHAT = 'wechat';/* 告警类型 关注微信比 */ const ALARM_TYPE_MOBILE = 'mobile';/* 告警类型 手机比 */ const ALARM_TYPE_SAME_IP = 'same_ip';/* 告警类型 同IP比 */ const ALARM_TYPE_WARRANT = 'warrant';/* 告警类型 授权比 */ const ALARM_TYPE_REALNAME = 'realname';/* 告警类型 实名比 */ const ALARM_REMAIN = 0;/* 告警指标 留存 */ const ALARM_WITHDRAW = 10;/* 告警指标 提现比 */ const ALARM_EXPAND = 1;/* 告警指标 拓展比 */ const ALARM_WECHAT = 5;/* 告警指标 关注微信比 */ const ALARM_MOBILE = 5;/* 告警指标 手机比 */ const ALARM_SAME_IP = 30;/* 告警指标 同IP比 */ const ALARM_WARRANT = 5;/* 告警指标 授权比 */ const ALARM_REALNAME = 60;/* 告警指标 授权比 */ private $agent_id; private $mem_id; private $sub_agent_ids; private $sub_mem_ids; public function __construct($agent_id) { $this->agent_id = $agent_id; $this->mem_id = (new UserModel())->getMemIdById($agent_id); $this->sub_mem_ids = (new MemberModel())->getIdsByParentMemId($this->mem_id); $this->sub_agent_ids = (new UserModel())->getIdsByMemIds($this->sub_mem_ids); } /** * 获取报告数据 */ public function getReport() { return [ self::ALARM_TYPE_WITHDRAW => $this->withdraw(), self::ALARM_TYPE_EXPAND => $this->expand(), self::ALARM_TYPE_WECHAT => $this->wechat(), self::ALARM_TYPE_WARRANT => $this->warrant(), self::ALARM_TYPE_MOBILE => $this->mobile(), self::ALARM_TYPE_REALNAME => $this->realname(), self::ALARM_TYPE_SAME_IP => $this->sameIp(), ]; } /** * 留存 * 【下线徒弟的留存,2-3-4-5-6-7-15-30日留存数据】 * 【2-3-4-5-6-7日留存任意一个参数=0则警报】 * * @return array */ public function remain() { $_days = [2, 3, 4, 5, 6, 7, 15, 30]; //查询指定日期的留存数据 $_ldm_model = new DayMemLogModel(); $_table_name = $_ldm_model->getName(); $_return_data = []; foreach ($_days as $day) { $_calculate_date = strtotime("-{$day} days"); $_table_date = date("Ym", $_calculate_date); $_record_date = date('Y-m-d', $_calculate_date); $_key = 'day'.$day; $_data = Db::name($_table_name.'_'.$_table_date) ->field([$_key, 'sub_mem_cnt']) ->where(['date' => $_record_date, 'mem_id' => $this->mem_id]) ->find(); $_value = $_data[$_key]; $_sub_mem_cnt = $_data['sub_mem_cnt']; $temp = [ 'type' => self::ALARM_TYPE_REMAIN, 'is_alarm' => false, 'data' => [], ]; $_rate = empty($_sub_mem_cnt) ? 0 : ($_value / $_sub_mem_cnt) * 100; if ($_rate <= self::ALARM_REMAIN) { $temp['is_alarm'] = true; } $temp['data'] = [ 'day' => $day, 'total' => $_sub_mem_cnt, 'eligible' => $_value, 'rate' => StrUtils::formatNumber($_rate), ]; $_return_data[] = $temp; } return $_return_data; } /** * 提现比 * 【下线徒弟的提现比例=提现徒弟数量/总徒弟数量】 * 【低于10%则警报】 */ private function withdraw() { $_return_data = [ 'type' => self::ALARM_TYPE_WITHDRAW, 'is_alarm' => false, 'data' => [], ]; if (empty($this->sub_agent_ids)) { $_return_data['data'] = [ 'total' => 0, 'eligible' => 0, 'rate_default' => StrUtils::formatNumber(self::ALARM_WITHDRAW), 'rate' => StrUtils::formatNumber(0), ]; return $_return_data; } $_total = count($this->sub_agent_ids); $_settle_log_logic = new SettleLogLogic(); $_where = [ 'agent_id' => ['in', $this->sub_agent_ids], 'type' => SettleConst::SETTLE_TYPE_MP ]; $_eligible = $_settle_log_logic->getSettleCnt($_where); $_rate = ($_eligible / $_total) * 100; if ($_rate < self::ALARM_WITHDRAW) { $_return_data['is_alarm'] = true; } $_return_data['data'] = [ 'total' => $_total, 'eligible' => $_eligible, 'rate_default' => StrUtils::formatNumber(self::ALARM_WITHDRAW), 'rate' => StrUtils::formatNumber($_rate), ]; return $_return_data; } /** * 拓展比【下线徒弟继续拓展徒弟的比例=下线徒弟有徒弟的数量/总徒弟数量】 * 【低于1%警报】 */ private function expand() { $_return_data = [ 'type' => self::ALARM_TYPE_EXPAND, 'is_alarm' => false, 'data' => [], ]; if (empty($this->sub_agent_ids)) { $_return_data['data'] = [ 'total' => 0, 'eligible' => 0, 'rate_default' => StrUtils::formatNumber(self::ALARM_EXPAND), 'rate' => StrUtils::formatNumber(0), ]; return $_return_data; } $_total = count($this->sub_agent_ids); $_agent_ext_model = new AgentExtModel(); $_where = [ 'agent_id' => ['in', $this->sub_agent_ids], 'reg_cnt' => ['>', 0], ]; $_eligible = $_agent_ext_model->getCnt($_where); $_rate = ($_eligible / $_total) * 100; if ($_rate < self::ALARM_EXPAND) { $_return_data['is_alarm'] = true; } $_return_data['data'] = [ 'total' => $_total, 'eligible' => $_eligible, 'rate_default' => StrUtils::formatNumber(self::ALARM_EXPAND), 'rate' => StrUtils::formatNumber($_rate), ]; return $_return_data; } /** * 关注微信比 * 【下线徒弟账号关注微信的比例=下线徒弟有关注微信的数量/总徒弟数量】 * 【低于5%警报】 */ private function wechat() { $_return_data = [ 'type' => self::ALARM_TYPE_WECHAT, 'is_alarm' => false, 'data' => [], ]; if (empty($this->sub_mem_ids)) { $_return_data['data'] = [ 'total' => 0, 'eligible' => 0, 'rate_default' => StrUtils::formatNumber(self::ALARM_WECHAT), 'rate' => StrUtils::formatNumber(0), ]; return $_return_data; } $_total = count($this->sub_mem_ids); $_where = [ 'mem_id' => ['in', $this->sub_mem_ids], 'from' => OauthConst::OAUTH_WEIXIN, 'status' => OauthConst::WEIXIN_SUBSCRIBE, ]; $_member_model = new MemoauthModel(); $_eligible = $_member_model->where($_where)->count(); $_rate = ($_eligible / $_total) * 100; if ($_rate < self::ALARM_WECHAT) { $_return_data['is_alarm'] = true; } $_return_data['data'] = [ 'total' => $_total, 'eligible' => $_eligible, 'rate_default' => StrUtils::formatNumber(self::ALARM_WECHAT), 'rate' => StrUtils::formatNumber($_rate), ]; return $_return_data; } /** * 授权比 * 【下线徒弟授权的比例=下线徒弟授权的数量/总徒弟数量】 * 【低于5%警报】 */ private function warrant() { $_return_data = [ 'type' => self::ALARM_TYPE_WARRANT, 'is_alarm' => false, 'data' => [], ]; if (empty($this->sub_mem_ids)) { $_return_data['data'] = [ 'total' => 0, 'eligible' => 0, 'rate_default' => StrUtils::formatNumber(self::ALARM_WARRANT), 'rate' => StrUtils::formatNumber(0), ]; return $_return_data; } $_total = count($this->sub_mem_ids); $_where = [ 'id' => ['in', $this->sub_mem_ids], 'status' => MemConst::STATUS_NORMAL, ]; $_member_model = new MemberModel(); $_eligible = $_member_model->where($_where)->count(); $_rate = ($_eligible / $_total) * 100; if ($_rate < self::ALARM_WARRANT) { $_return_data['is_alarm'] = true; } $_return_data['data'] = [ 'total' => $_total, 'eligible' => $_eligible, 'rate_default' => StrUtils::formatNumber(self::ALARM_WARRANT), 'rate' => StrUtils::formatNumber($_rate), ]; return $_return_data; } /** * 手机比 * 【下线徒弟账号绑定手机号的比例=下线徒弟有绑定手机号的数量/总徒弟数量】 * 【低于5%警报】 */ private function mobile() { $_return_data = [ 'type' => self::ALARM_TYPE_MOBILE, 'is_alarm' => false, 'data' => [], ]; if (empty($this->sub_mem_ids)) { $_return_data['data'] = [ 'total' => 0, 'eligible' => 0, 'rate_default' => StrUtils::formatNumber(self::ALARM_MOBILE), 'rate' => StrUtils::formatNumber(0), ]; return $_return_data; } $_total = count($this->sub_mem_ids); $_where = [ 'id' => ['in', $this->sub_mem_ids], 'mobile' => ['<>', ''], ]; $_member_model = new MemberModel(); $_eligible = $_member_model->where($_where)->count(); $_rate = ($_eligible / $_total) * 100; if ($_rate < self::ALARM_MOBILE) { $_return_data['is_alarm'] = true; } $_return_data['data'] = [ 'total' => $_total, 'eligible' => $_eligible, 'rate_default' => StrUtils::formatNumber(self::ALARM_MOBILE), 'rate' => StrUtils::formatNumber($_rate), ]; return $_return_data; } /** * 实名比 * 【下线徒弟账号实名的比例=下线徒弟有实名的数量/总徒弟数量】 * 【低于60%警报】 */ private function realname() { $_return_data = [ 'type' => self::ALARM_TYPE_REALNAME, 'is_alarm' => false, 'data' => [], ]; if (empty($this->sub_mem_ids)) { $_return_data['data'] = [ 'total' => 0, 'eligible' => 0, 'rate_default' => StrUtils::formatNumber(self::ALARM_REALNAME), 'rate' => StrUtils::formatNumber(0), ]; return $_return_data; } $_total = count($this->sub_mem_ids); $_where = [ 'id' => ['in', $this->sub_mem_ids], 'real_name' => ['<>', ''], ]; $_member_model = new MemberModel(); $_eligible = $_member_model->where($_where)->count(); $_rate = ($_eligible / $_total) * 100; if ($_rate < self::ALARM_REALNAME) { $_return_data['is_alarm'] = true; } $_return_data['data'] = [ 'total' => $_total, 'eligible' => $_eligible, 'rate_default' => StrUtils::formatNumber(self::ALARM_REALNAME), 'rate' => StrUtils::formatNumber($_rate), ]; return $_return_data; } /** * 同IP比 * 【下线徒弟注册IP的网段相同比例=相同网段徒弟数量/总徒弟数量】 * 【大于30%警报】 */ private function sameIp() { $_return_data = [ 'type' => self::ALARM_TYPE_SAME_IP, 'is_alarm' => false, 'data' => [], ]; if (empty($this->sub_mem_ids)) { $_return_data['data'] = [ 'total' => 0, 'eligible' => 0, 'rate_default' => StrUtils::formatNumber(self::ALARM_SAME_IP), 'rate' => StrUtils::formatNumber(0), ]; return $_return_data; } $_total = count($this->sub_mem_ids); $_eligible = 0; $_ips = []; $_member_cache = new MemCache(); foreach ($this->sub_mem_ids as $_sub_mem_id) { $_sub_mem_info = $_member_cache->getInfoById($_sub_mem_id); if (in_array($_sub_mem_info['reg_ip'], $_ips)) { $_eligible++; } else { $_ips[] = $_sub_mem_info['reg_ip']; } } $_rate = ($_eligible / $_total) * 100; if ($_rate > self::ALARM_SAME_IP) { $_return_data['is_alarm'] = true; } $_return_data['data'] = [ 'total' => $_total, 'eligible' => $_eligible, 'rate_default' => StrUtils::formatNumber(self::ALARM_SAME_IP), 'rate' => StrUtils::formatNumber($_rate), ]; return $_return_data; } public function getAgentMoney() { $_agent_ext = AgentCache::ins()->getAgentExtByAgentId($this->agent_id); $_total_settle = (new SettleModel())->getTotalAmount($this->agent_id); $_sub_settle_total = (new SettleModel())->getSubTotalAmount($this->agent_id); $_sub_share_total = (new AgentExtModel())->getSubShareTotal($this->agent_id); $_share_total = empty($_agent_ext['share_total']) ? 0.00 : $_agent_ext['share_total']; return [ 'share_total' => $_share_total, 'total_settle' => $_total_settle, 'sub_share_total' => $_sub_share_total, 'sub_settle_total' => $_sub_settle_total ]; } }