| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <?php
- namespace app\common\service;
- use app\common\model\UserModel;
- use app\common\model\UserUnmoneyModel;
- use think\facade\Db;
- use utils\RedisCache;
- /**
- * 用户服务 by wes
- * Class UserService
- * @package app\common\service
- */
- class UserService
- {
- protected static $instance = null;
- protected $model = null;
- public function __construct()
- {
- $this->model = new UserModel();
- }
- /**
- * 静态化入口
- * @return static|null
- */
- public static function make()
- {
- if(!self::$instance){
- self::$instance = new static();
- }
- return self::$instance;
- }
- /**
- * 用户缓存信息
- * @param int $uid
- * @return array|mixed
- */
- public function getCacheInfo($uid, $field='', $cache=false)
- {
- $cacheKey = "caches:users:info:u{$uid}".($field?'_'.md5($field):'');
- $data = RedisCache::get($cacheKey);
- if($data && $cache){
- return $data;
- }
- $where = ['id'=> $uid];
- $field = $field? $field : 'id,user_name,mobile,level,code,pid,money,score,profit_money,level_type,status,is_auth,is_reward,user_type,store_type,has_fd';
- $data = $this->model->where($where)->field($field)->findOrEmpty();
- $data = $data? $data->toArray():[];
- if($data && $cache){
- RedisCache::set($cacheKey, $data, rand(3,5));
- }
- return $data;
- }
- /**
- * 结算利润到余额
- * @param $uid
- * @throws Exception
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function switchProfitToMoney($uid)
- {
- $userInfo = UserModel::where('id', $uid)->field('id,mobile,money,profit_money,status')->find();
- $profitMoney = isset($userInfo['profit_money'])? intval($userInfo['profit_money']): 0;
- $userMoney = isset($userInfo['money'])? floatval($userInfo['money']): 0;
- $userStatus = isset($userInfo['status'])? $userInfo['status'] : 0;
- if(empty($userInfo) || $userStatus != 1){
- sr_throw('用户参数错误或已被冻结');
- }
- if ($profitMoney < 100){
- sr_throw('利润小于100,结算失败');
- }else{
- $profitMoney = $profitMoney - $profitMoney % 100;
- $updateAccount = UserModel::where('id', $uid)
- ->inc('money',$profitMoney)
- ->inc('total_profit_money', $profitMoney)
- ->dec('profit_money', $profitMoney)
- ->update();
- if(!$updateAccount){
- sr_throw('利润结算失败');
- }
- $data = [
- 'uid'=>$uid,
- 'type'=> 8,
- 'money'=> $profitMoney,
- 'status'=> 1,
- 'state'=> 2,
- 'before_money'=> $userMoney,
- 'after_money'=> floatval($userMoney+$profitMoney),
- 'remark'=> '利润结算到余额',
- 'create_time'=>date('Y-m-d H:i:s')
- ];
- if(!UserUnmoneyModel::insertGetId($data)){
- sr_throw('利润结算处理失败');
- }
- }
- }
- /**
- * 用户升级
- * @return array|string
- */
- public function updateLevel()
- {
- $cacheKey = "caches:users:updateLevel:".date('YmdHi');
- if(RedisCache::get($cacheKey.'_lock')){
- return '请不要频繁提交处理';
- }
- Db::startTrans();
- try {
- RedisCache::setnx($cacheKey . 'lock', date('Y-m-d H:i:s'), rand(5, 10));
- $list = $this->model->where('has_update_level', '>', 0)
- ->field('id,level,pid,path')
- ->select();
- $list = $list? $list->toArray() : [];
- if (empty($list)) {
- return '暂无用户需要升级';
- }
- // 等级配置
- $levelConfig = LevelSettingService::make()->getConfigData(0, 1);
- if (empty($levelConfig)) {
- return '请先配置等级升级参数';
- }
- // 处理升级
- $noCatchUids = []; // 未升级的用户
- $levelIds = []; // 升级了的用户
- foreach ($list as $item) {
- $uid = isset($item['id']) ? $item['id'] : 0;
- $path = isset($item['path']) ? $item['path'] : 0;
- $userLevel = isset($item['level']) ? intval($item['level']) : 0;
- // 判断团队人数获取可升等级
- $updateLevel = 0;
- $teamCount = $this->getTeamCount($uid, $path); // 团队人数
- foreach ($levelConfig as $val) {
- $needTeamCount = isset($val['team_num']) ? $val['team_num'] : 0;
- $level = isset($val['level']) ? $val['level'] : 0;
- // 如果团队人数满足当前等级要求(排除)
- if ($level > 0 && $needTeamCount && $teamCount >= $needTeamCount) {
- $updateLevel = $level;
- }
- }
- // 如果当前用户需要升级
- $ztCount = 0;
- if ($updateLevel > $userLevel) {
- // 所需直推等级
- $ztLevel = isset($levelConfig[$updateLevel]['zt_level']) ? intval($levelConfig[$updateLevel]['zt_level']) : 0;
- $ztCount = $this->getZtCount($uid, $ztLevel);
- // 可升级的等级所需直推人数
- $needZtCount = isset($levelConfig[$updateLevel]['zt_num']) ? intval($levelConfig[$updateLevel]['zt_num']) : 0;
- if ($needZtCount <= $ztCount) {
- // 当前用户升级,且去掉可升级状态
- $this->model->where('id', $uid)->update(['level' => $updateLevel, 'has_update_level' => 0, 'update_time' => date('Y-m-d H:i:s')]);
- $levelIds[] = $uid;
- }else{
- $noCatchUids[] = $uid;
- }
- }else{
- $noCatchUids[] = $uid;
- }
- // 用户升级后,处理上层用户升级(设置为可升级状态)
- if ($path && $updateLevel>$userLevel) {
- $this->model->whereIn('id', explode(',', $path))->update(['has_update_level' => 1, 'update_time' => date('Y-m-d H:i:s')]);
- }
- // 处理缓存
- RedisCache::set("caches:users:updateLevel:user_{$uid}:".date('YmdHi'), ['msg'=>'升级处理成功','data'=> $val,'team'=>$teamCount,'zt'=>$ztCount,'updateLevel'=> $updateLevel,'config'=>$levelConfig,'date'=>date('Y-m-d H:i:s')], 3600);
- }
- // 如果存在未升级用户清除升级状态
- if($noCatchUids){
- $this->model->whereIn('id', $noCatchUids)->update(['has_update_level' => 0, 'update_time' => date('Y-m-d H:i:s')]);
- }
- Db::commit();
- RedisCache::set($cacheKey.'_success', ['msg'=>'升级处理成功','total'=> count($list),'level'=>count($levelIds),'date'=>date('Y-m-d H:i:s')], 7200);
- return ['code'=>200, 'msg'=>"处理升级成功,累计处理用户".count($list)."个,升级用户".count($levelIds).'个'];
- } catch (\Exception $exception){
- Db::rollback();
- RedisCache::set($cacheKey.'_fail', ['msg'=> $exception->getMessage(),'trace'=> $exception->getTrace(),'date'=>date('Y-m-d H:i:s')], 7200);
- return ['code'=>500, 'msg'=>"处理升级失败:".$exception->getMessage()];
- }
- }
- /**
- * 统计有效直推人数
- * @param $uid
- * @param int $level 等级
- * @return array|int|mixed
- * @throws \think\db\exception\DbException
- */
- public function getZtCount($uid, $level = 0)
- {
- $cacheKey = "caches:users:counts:zt_num_{$uid}_{$level}";
- $data = RedisCache::get($cacheKey);
- if($data){
- return $data;
- }
- $where = ['pid'=> $uid,'has_fd'=>1];
- if($level>0){
- $where['level'] = $level;
- }
- $data = $this->model->where($where)->count('id');
- if($data){
- RedisCache::set($cacheKey, $data, rand(10,20));
- }
- return $data;
- }
- /**
- * 统计有效团队人数
- * @param $uid 用户ID
- * @param $path
- * @return array|int|mixed
- * @throws \think\db\exception\DbException
- */
- public function getTeamCount($uid, $path)
- {
- $cacheKey = "caches:users:counts:team_num_{$uid}";
- $data = RedisCache::get($cacheKey);
- if($data){
- return $data;
- }
- $data = $this->model->where('path','like',"%{$path}")
- ->where('has_fd',1)
- ->count('id');
- if($data){
- RedisCache::set($cacheKey, $data, rand(10,20));
- }
- return $data;
- }
- }
|