Browse Source

复制伴声

lizhen_gitee 3 years ago
parent
commit
8eb862ec0c
51 changed files with 2109 additions and 1 deletions
  1. 1 0
      addons/faqueue/.addonrc
  2. 73 0
      addons/faqueue/Faqueue.php
  3. 5 0
      addons/faqueue/config.php
  4. 15 0
      addons/faqueue/controller/Index.php
  5. 10 0
      addons/faqueue/info.ini
  6. 21 0
      addons/faqueue/install.sql
  7. 109 0
      addons/faqueue/library/QueueApi.php
  8. 96 0
      addons/faqueue/library/jobs/CheckRelegation.php
  9. 43 0
      addons/faqueue/library/jobs/EmailJob.php
  10. 43 0
      addons/faqueue/library/jobs/SendImMsessageJob.php
  11. 49 0
      addons/faqueue/library/jobs/SmsJob.php
  12. 29 0
      addons/faqueue/model/FaqueueLog.php
  13. 401 0
      application/api/controller/Noble.php
  14. 2 1
      application/api/controller/Party.php
  15. 0 0
      application/api/controller/Tenim.php
  16. 42 0
      application/api/controller/User.php
  17. 34 0
      application/common/controller/Api.php
  18. 101 0
      application/common/controller/RedisLeaderboard.php
  19. 17 0
      application/common/model/Gift.php
  20. 17 0
      application/common/model/GiftBack.php
  21. 22 0
      application/common/model/GiftBox.php
  22. 54 0
      application/common/model/GiftUserParty.php
  23. 77 0
      application/common/model/Guild.php
  24. 17 0
      application/common/model/GuildApply.php
  25. 17 0
      application/common/model/GuildMember.php
  26. 34 0
      application/common/model/Message.php
  27. 15 0
      application/common/model/Music.php
  28. 17 0
      application/common/model/NobleLevel.php
  29. 106 0
      application/common/model/Party.php
  30. 17 0
      application/common/model/PartyBackground.php
  31. 17 0
      application/common/model/PartyCellection.php
  32. 15 0
      application/common/model/PartyGif.php
  33. 15 0
      application/common/model/PartyGifType.php
  34. 15 0
      application/common/model/PartyHeadgif.php
  35. 16 0
      application/common/model/PartyHot.php
  36. 17 0
      application/common/model/PartyJoin.php
  37. 17 0
      application/common/model/PartyType.php
  38. 19 0
      application/common/model/RedisTops.php
  39. 79 0
      application/common/model/TaskLog.php
  40. 170 0
      application/common/model/User.php
  41. 17 0
      application/common/model/UserAnchor.php
  42. 17 0
      application/common/model/UserAuth.php
  43. 15 0
      application/common/model/UserChangeLog.php
  44. 16 0
      application/common/model/UserCharmRank.php
  45. 40 0
      application/common/model/UserJewelLog.php
  46. 15 0
      application/common/model/UserOnsiteTime.php
  47. 15 0
      application/common/model/UserProfitLog.php
  48. 41 0
      application/common/model/UserSoundcoinLog.php
  49. 33 0
      application/common/model/ViewUserSkill.php
  50. 34 0
      application/config.php
  51. 2 0
      application/extra/site.php

+ 1 - 0
addons/faqueue/.addonrc

@@ -0,0 +1 @@
+{"license":"regular","licenseto":"13631","licensekey":"yUzRX1kLuNQoKmWh i6mPhOO0vTPF4ApBsr6ihw==","menus":["faqueue","faqueue\/log","faqueue\/log\/index"],"files":["application\\admin\\controller\\faqueue\\Log.php","application\\admin\\lang\\zh-cn\\faqueue\\log.php","application\\admin\\model\\faqueue\\Log.php","application\\admin\\view\\faqueue\\log\\index.html","public\\assets\\js\\backend\\faqueue\\log.js"]}

+ 73 - 0
addons/faqueue/Faqueue.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace addons\faqueue;
+
+use app\common\library\Menu;
+use think\Addons;
+
+/**
+ * 插件
+ */
+class Faqueue extends Addons
+{
+
+    /**
+     * 插件安装方法
+     * @return bool
+     */
+    public function install()
+    {
+        $menu = [
+            [
+                'name'   => 'faqueue',
+                'title'  => '消息队列',
+                'ismenu' => 1,
+                'icon'   => 'fa fa-list',
+                'remark' => '消息队列',
+                'sublist' => [
+                    [
+                        'name' => 'faqueue/log',
+                        'title' => '任务完成记录',
+                        'sublist' => [
+                            ['name' => 'faqueue/log/index', 'title' => '查看'],
+                        ]
+                    ],
+                ]
+            ]
+        ];
+        Menu::create($menu);
+        return true;
+    }
+
+    /**
+     * 插件卸载方法
+     * @return bool
+     */
+    public function uninstall()
+    {
+        Menu::delete('faqueue');
+        return true;
+    }
+
+    /**
+     * 插件启用方法
+     * @return bool
+     */
+    public function enable()
+    {
+        Menu::enable('faqueue');
+        return true;
+    }
+
+    /**
+     * 插件禁用方法
+     * @return bool
+     */
+    public function disable()
+    {
+        Menu::disable('faqueue');
+        return true;
+    }
+
+
+}

+ 5 - 0
addons/faqueue/config.php

@@ -0,0 +1,5 @@
+<?php
+
+return [
+
+];

+ 15 - 0
addons/faqueue/controller/Index.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace addons\faqueue\controller;
+
+use think\addons\Controller;
+
+class Index extends Controller
+{
+
+    public function index()
+    {
+        $this->error("当前插件暂无前台页面");
+    }
+
+}

+ 10 - 0
addons/faqueue/info.ini

@@ -0,0 +1,10 @@
+name = faqueue
+title = 消息队列
+intro = 基于think-queue消息队列
+author = 君君要上天
+website = https://www.fastadmin.net
+version = 1.0.1
+state = 1
+url = /addons/faqueue
+license = regular
+licenseto = 13631

+ 21 - 0
addons/faqueue/install.sql

@@ -0,0 +1,21 @@
+CREATE TABLE  IF NOT EXISTS `__PREFIX__faqueue_jobs` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `queue` varchar(255) NOT NULL,
+  `payload` longtext NOT NULL,
+  `attempts` tinyint(3) unsigned NOT NULL,
+  `reserved` tinyint(3) unsigned NOT NULL,
+  `reserved_at` int(10) unsigned DEFAULT NULL,
+  `available_at` int(10) unsigned NOT NULL,
+  `created_at` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `__PREFIX__faqueue_log` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `queue` varchar(255) DEFAULT NULL COMMENT '队列名',
+  `job` varchar(100) DEFAULT NULL COMMENT '执行类',
+  `data` longtext COMMENT '任务数据',
+  `create_time` int(10) DEFAULT NULL COMMENT '开始执行时间',
+  `update_time` int(10) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

+ 109 - 0
addons/faqueue/library/QueueApi.php

@@ -0,0 +1,109 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zhoujun
+ * Date: 2018/9/1
+ * Time: 12:11
+ */
+
+namespace addons\faqueue\library;
+
+use addons\faqueue\model\FaqueueLog;
+use think\Db;
+use think\Queue;
+
+class QueueApi
+{
+
+    public static function sendEmail($subject, $to, $message)
+    {
+
+        $data = [
+            'subject' => $subject,
+            'to'      => $to,
+            'message' => $message,
+        ];
+
+        return self::push('addons\faqueue\library\jobs\EmailJob', $data);
+
+    }
+
+
+    public static function smsSend($mobile, $code = null, $event = 'default')
+    {
+        $data = [
+            'method' => 'send',
+            'mobile' => $mobile,
+            'code'   => $code,
+            'event'  => $event,
+        ];
+        return self::push('addons\faqueue\library\jobs\SmsJob', $data);
+    }
+
+    public static function smsNotice($mobile, $msg = '', $template = null)
+    {
+        $data = [
+            'method'   => 'notice',
+            'mobile'   => $mobile,
+            'msg'      => $msg,
+            'template' => $template,
+        ];
+        return self::push('addons\faqueue\library\jobs\SmsJob', $data);
+    }
+
+    //发生im消息推送-自定义消息飘屏
+    public static function sendGroupMessage($type, $sender, $receiver, $partyInfo, $giftUserParty)
+    {
+        if (!$type) {
+            return false;
+        }
+
+        $messageData = [
+            'type'    => $type,
+            'content' => [
+                'party_info'  => [
+                    'party_id'   => $partyInfo['id'],
+                    'room_type'  => $partyInfo['room_type'],
+                    'party_name' => $partyInfo['party_name']
+                ],
+                'notice_info' => [
+                    'sender'         => $sender,
+                    'receiver'       => $receiver,
+                    'gift_num'       => $giftUserParty['number'],
+                    'gift_name'      => $giftUserParty['gift_name'],
+                    'gift_image'     => $giftUserParty['gift_gif_image'],
+                    'gift_rgb_color' => "#fde4ac"
+                ]
+            ]
+        ];
+
+        return self::later(1, 'addons\faqueue\library\jobs\SendImMsessageJob', $messageData);
+    }
+
+    //定时检测贵族保级
+    public static function timeRelegation($id, $endTime=0,$noble=0)
+    {
+        if (empty($id)) {
+            return false;
+        }
+
+        $messageData = [
+            'user_id'=>$id,
+            'end_time'=>$endTime,
+            'noble'=>$noble
+        ];
+
+        return self::later($endTime-time(),'addons\faqueue\library\jobs\CheckRelegation', $messageData);
+//        return self::later(30,'addons\faqueue\library\jobs\CheckRelegation', $messageData);
+    }
+
+    public static function push($job, $data = '', $queue = null)
+    {
+        return Queue::push($job, $data, $queue);
+    }
+
+    public static function later($delay, $job, $data = '', $queue = null)
+    {
+        return Queue::later($delay, $job, $data, $queue);
+    }
+}

+ 96 - 0
addons/faqueue/library/jobs/CheckRelegation.php

@@ -0,0 +1,96 @@
+<?php
+
+namespace addons\faqueue\library\jobs;
+
+use addons\faqueue\library\QueueApi;
+use addons\faqueue\model\FaqueueLog;
+use app\admin\model\AdminMessage;
+use app\admin\model\UserMessage;
+use app\common\library\weChat\weChatMp;
+use think\Db;
+use think\Log;
+use think\queue\job;
+
+class CheckRelegation
+{
+    private $redis;
+
+    function __construct()
+    {
+        $redis = new \Redis();
+        $redisconfig = config("redis");
+        $redis->connect($redisconfig["host"], $redisconfig["port"], 86400 * 31);
+        $this->redis = $redis;
+    }
+
+    public function fire(Job $job, $data)
+    {
+        $user_id = $data['user_id'];
+        $user = Db::name('user')->where('id',$user_id)->field('id,noble,noble_duetime')->find();
+
+        //贵族等级高于30天前定时等级。视为无效任务
+        if (!$user || $user['noble']>$data['noble'] || $user['noble_duetime']>$data['end_time']){
+            $job->delete();
+            echo 11111;
+            return;
+        }
+
+        //玩家当前贵族等级
+        $userNoble = $user['noble'];
+        $nobleDuetime = $user['noble_duetime'];
+        $userRenew2 = $this->redis->get('user_renew2_'.$user_id);
+        $getNobleLevelData = $this->getNobleLevelData($userNoble);
+        if (empty($getNobleLevelData)) {
+            $job->delete();
+            return;
+        }
+
+        $renew2 = $getNobleLevelData['renew2'];
+//        $this->redis->set('user_renew_'.$user_id,0);
+        $this->redis->set('user_renew2_'.$user_id,0);
+        $duetime = strtotime("+1 month",$nobleDuetime);
+
+        //如果不是最大等级保级说明是重新回到该爵位,需扣除之前回到回到该爵位的消保
+        //增加月保级消费(处理保级),和月消费分开(处理升级)
+
+        if ($userRenew2!=0 && $userRenew2>=$renew2){
+            //保级成功,延长过期时间
+            Db::name('user')->where('id',$user_id)->setField('noble_duetime',$duetime);
+
+        }else{
+            //降级,>骑士
+            $userNoble = $userNoble - 1;
+            if ($userNoble<1) {
+                $job->delete();
+                return;
+            }
+            Db::name('user')->where('id',$user_id)->update(['noble'=>$userNoble,'noble_duetime'=>$duetime]);
+        }
+
+        $job->delete();
+        (new FaqueueLog())->log($job->getQueue(), $job->getName(), $data);
+
+        //重新定时任务
+        if ($userNoble>1) QueueApi::timeRelegation($user_id,$duetime,$userNoble);
+    }
+
+    public function failed($data)
+    {
+        Log::write("任务失败:" . print_r(['data' => $data,], true), 'error');
+    }
+
+    /**
+     * 获取指定等级的贵族数据
+     * @param $level_id
+     */
+    private function getNobleLevelData($level_id)
+    {
+        $getNobleLevelList = $this->redis->get('noble_level_list');
+        if (empty($getNobleLevelList)) return [];
+        $getNobleLevelList = unserialize($getNobleLevelList);
+        foreach ($getNobleLevelList as $v){
+            if ($level_id == $v['id']) return $v;
+        }
+        return [];
+    }
+}

+ 43 - 0
addons/faqueue/library/jobs/EmailJob.php

@@ -0,0 +1,43 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zhoujun
+ * Date: 2018/9/1
+ * Time: 11:58
+ */
+
+namespace addons\faqueue\library\jobs;
+
+use addons\faqueue\model\FaqueueLog;
+use app\common\library\Email;
+use think\Log;
+use think\queue\job;
+
+class EmailJob
+{
+    public function fire(Job $job, $data){
+
+        $email = new Email();
+
+        $result = $email->subject($data['subject'])
+            ->to($data['to'])
+            ->message($data['message'])
+            ->send();
+
+        if($result){
+            $job->delete();
+            (new FaqueueLog())->log($job->getQueue(),$job->getName(),$data);
+        }else{
+            $job->release();
+            Log::write("邮件发送失败:".print_r([
+                    'name' => $job->getName(),
+                    'error'=> $email->getError()
+                ],true),'error');
+        }
+
+    }
+
+    public function failed($data){
+        Log::write("邮件任务失败:".print_r(['data' => $data,],true),'error');
+    }
+}

+ 43 - 0
addons/faqueue/library/jobs/SendImMsessageJob.php

@@ -0,0 +1,43 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zhoujun
+ * Date: 2018/9/1
+ * Time: 11:40
+ */
+
+namespace addons\faqueue\library\jobs;
+
+use addons\faqueue\model\FaqueueLog;
+use app\admin\model\AdminMessage;
+use app\admin\model\UserMessage;
+use app\common\library\Sms;
+use app\common\library\Trtcim;
+use app\common\library\weChat\weChatMp;
+use app\common\model\Party;
+use think\Log;
+use think\queue\job;
+
+class SendImMsessageJob
+{
+    public function fire(Job $job, $data)
+    {
+        if($data['type'] == 71){
+            Trtcim::sendGroupMsg($data['content']['party_info']['party_id'], $data);
+        }else{
+            $partyIds = Party::where(['status' => 1, 'is_online' => 1, 'is_close' => 0])->column('id');
+            foreach ($partyIds as $key => $value) {
+                Trtcim::sendGroupMsg($value, $data);
+            }
+        }
+
+        $job->delete();
+        (new FaqueueLog())->log($job->getQueue(), $job->getName(), $data);
+
+    }
+
+    public function failed($data)
+    {
+        Log::write("任务失败:" . print_r(['data' => $data,], true), 'error');
+    }
+}

+ 49 - 0
addons/faqueue/library/jobs/SmsJob.php

@@ -0,0 +1,49 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zhoujun
+ * Date: 2018/9/1
+ * Time: 11:40
+ */
+namespace addons\faqueue\library\jobs;
+
+use addons\faqueue\model\FaqueueLog;
+use app\common\library\Sms;
+use think\Log;
+use think\queue\job;
+
+class SmsJob
+{
+    public function fire(Job $job, $data){
+
+        $method = $data['method'];
+
+        switch ($method){
+            case 'send':
+                $result = Sms::send($data['mobile'],$data['code'],$data['event']);
+                break;
+            case 'notice':
+                $result = Sms::notice($data['mobile'],$data['smg'],$data['template']);
+                break;
+            default:
+                $result = false;
+        }
+
+        if($result){
+            Log::write("发送成功,result:".print_r($result,true));
+            $job->delete();
+            (new FaqueueLog())->log($job->getQueue(),$job->getName(),$data);
+        }else{
+            $job->release();
+            Log::write("短信发送失败:".print_r([
+                    'name' => $job->getName(),
+                    'result' => $result
+                ],true),'error');
+        }
+
+    }
+
+    public function failed($data){
+        Log::write("短信任务失败:".print_r(['data' => $data,],true),'error');
+    }
+}

+ 29 - 0
addons/faqueue/model/FaqueueLog.php

@@ -0,0 +1,29 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zhoujun
+ * Date: 18-9-4
+ * Time: 下午1:44
+ */
+
+namespace addons\faqueue\model;
+
+use think\Config;
+use think\Db;
+use think\Model;
+
+class FaqueueLog extends Model
+{
+
+    protected $autoWriteTimestamp = 'int';
+
+    public function log($queue , $job, $data){
+
+        return $this->data([
+            'job' => $job,
+            'queue' => $queue,
+            'data' => is_string($data) ? $data : json_encode($data),
+        ])->save();
+    }
+
+}

+ 401 - 0
application/api/controller/Noble.php

@@ -0,0 +1,401 @@
+<?php
+
+namespace app\api\controller;
+
+
+use addons\faqueue\library\QueueApi;
+use app\common\controller\Api;
+use app\common\model\Gateway;
+use think\Db;
+
+use think\exception\ValidateException;
+
+/**
+ * 贵族接口
+ */
+class Noble extends Api
+{
+    protected $noNeedLogin = ['getNobleLevelList','getNobleLevelPrivilegeInfo','onNoble'];
+    protected $noNeedRight = ['*'];
+
+    /**
+     * 获取贵族等级列表
+     */
+    public function getNobleLevelList() {
+        $noblelevelList = controller('api/Party')->checkGetNobleLevelList(config('token')['key']);
+        return $this->success("获取成功!",$noblelevelList);
+    }
+
+    /**
+     * 根据贵族等级ID获取贵族等级特权
+     */
+    public function getNobleLevelPrivilegeInfo() {
+        $level_id = $this->request->request("level_id");
+        if (!$level_id) {
+            $this->error(__('Invalid parameters'));
+        }
+        $nplModel = new \app\common\model\NobleLevelPrivilege();
+        $where = [];
+        $where["level_id"] = $level_id;
+        $where["is_show"] = 1;
+        $nplInfo = $nplModel->where($where)->select();
+
+        if($nplInfo) {
+            return $this->success("获取成功!",$nplInfo);
+        } else {
+            return $this->success("数据为空!",[]);
+        }
+
+    }
+
+    /**
+     * 获取贵族等级以及到期时间
+     */
+    public function getNobleDuetime() {
+        $level_id = $this->request->request("level_id");
+        if (!$level_id) {
+            $this->error(__('Invalid parameters'));
+        }
+        $userModel = new \app\common\model\User();
+        $info = $userModel->getUserNobleInfo($level_id,$this->auth->id);
+        return $this->success("获取成功!",$info);
+    }
+
+    /**
+     * 获取贵族等级所需金额
+     */
+    public function getNobleLogInfo() {
+        $level_id = $this->request->request("level_id");
+        if (!$level_id) {
+            $this->error(__('Invalid parameters'));
+        }
+        $nldlModel = new \app\common\model\NobleDredgeLog();
+        $noblelevelModel = new \app\common\model\NobleLevel();
+        $noblelevelInfo = $noblelevelModel->where(["id"=>$level_id])->find();
+
+        // 获取贵族等级开通信息
+        $where = [];
+        $where["user_id"] = $this->auth->id;
+        $where["level_no"] = $noblelevelInfo["level_no"];
+        $nldlCount = 0;
+        $nldlInfo = $nldlModel->where($where)->limit(1)->order("dredge_num","desc")->select();
+        $nldlInfo && $nldlInfo = $nldlInfo[0];
+        // 判断是否是首月开通
+        if($nldlInfo) {
+            $nldlCount = $nldlInfo["dredge_num"];
+        }
+        $money = $nldlCount>0?$noblelevelInfo["renew"]:$noblelevelInfo["first"];
+        $data["money"] = $money;
+        return $this->success("获取成功!",$data);
+    }
+
+    /**
+     * 开通贵族
+     */
+    public function beNoble() {
+        $level_id = $this->request->request("level_id"); // 贵族等级ID
+        if (!$level_id) {
+            $this->error(__('Invalid parameters'));
+        }
+
+        $time = time();
+        // 获取贵族信息
+        $noblelevelModel = new \app\common\model\NobleLevel();
+        $nldlModel = new \app\common\model\NobleDredgeLog();
+        $noblelevelInfo = $noblelevelModel->where(["id"=>$level_id])->find();
+
+        // 获取贵族等级开通信息
+        $where = [];
+        $where["user_id"] = $this->auth->id;
+        $where["level_no"] = $noblelevelInfo["level_no"];
+        $nldlCount = 0;
+        $nldlInfo = $nldlModel->where($where)->limit(1)->order("dredge_num","desc")->select();
+        $nldlInfo && $nldlInfo = $nldlInfo[0];
+        // 判断是否是首月开通
+        if($nldlInfo) {
+            $nldlCount = $nldlInfo["dredge_num"];
+//            if(time() - $nldlInfo["createtime"] < 60) { // 同一个人,同一等级,一分钟之内重复开通,鉴定为系统bug
+//                $this->error("您刚刚开通过此贵族特权");
+//            }
+        }
+        $money = $nldlCount>0?$noblelevelInfo["renew"]:$noblelevelInfo["first"];
+
+        if(!$noblelevelInfo || $money <= 0) {
+            $this->error(__('贵族等级信息有误!'));
+        }
+        $userModel = new \app\common\model\User();
+        $userjewellogModel = new \app\common\model\UserJewelLog();
+        $where = [];
+        $where["id"] = $this->auth->id;
+        $userInfo = $userModel->where($where)->find();
+        // 判断用户余额
+        if($userInfo["jewel"]-$money < 0) {
+            $this->error("您的钻石余额不足,请先充值");
+        }
+
+        // 获取当前用户贵族等级
+        if($userInfo["noble"] == $level_id) {
+            $duetime = $userInfo["noble_duetime"];
+        } else {
+            $duetime = $time;
+        }
+
+        Db::startTrans();
+        try{
+            // 扣除当前用户钻石余额 更新用户贵族信息
+            $where = [];
+            $where["id"] = $this->auth->id;
+            $duetime = strtotime("+1 month",$duetime);
+            $nextMonth = strtotime("+1 month",$time);
+            $data = [];
+            $data["noble"] = $level_id;
+            $data["noble_duetime"] = $duetime;
+            $submoney = bcsub($userInfo["jewel"],$money);
+            // 开通返现
+            $return = $nldlCount>0?$noblelevelInfo["give"]:$noblelevelInfo["firstgive"];
+            $data["jewel"] = bcadd($submoney,$return);
+
+            $res1 = $userModel->update($data,$where);
+            // 添加当前用户钻石流水记录
+            $res2 = $userjewellogModel->addUserJewelLog($this->auth->id, $money, "-", $userInfo["jewel"], "开通贵族:'" . $noblelevelInfo["name"] . "',扣除" . $money . "钻石!", 5);
+
+            // 添加贵族等级开通明细
+            $data = [];
+            $data["user_id"] = $this->auth->id;
+            $data["level_no"] = $noblelevelInfo["level_no"];
+            $data["dredge_num"] = $nldlCount+1;
+            $data["createtime"] = $time;
+            $res3 = $nldlModel->insertGetId($data);
+
+            // 添加当前用户钻石流水记录
+            $res4 = $userjewellogModel->addUserJewelLog($this->auth->id, $return, "+", $userInfo["jewel"] - $money, "开通贵族:'" . $noblelevelInfo["name"] . "',赠送" . $money . "钻石!", 5);
+
+
+            if($res1 && $res2 && $res3 && $res4) {
+                Db::commit();
+                // $this->onNobleEffect($noblelevelInfo,$this->auth->id,$this->auth->nickname);
+                $this->onNobleAttire($noblelevelInfo,$this->auth->id,$nextMonth,$time);
+
+                // +exp
+                $nobleArr = ['1'=>'entymIFE3J'];
+                isset($nobleArr[$level_id]) && \app\common\model\TaskLog::tofinish($this->auth->id,$nobleArr[$level_id],1);
+
+                // +message
+                \app\common\model\Message::addMessage($this->auth->id,"贵族开通通知","恭喜,您已成功开通!".$noblelevelInfo["name"]." 贵族特权!");
+
+                // 赠送消息尾灯
+                \app\common\model\AttireBack::addToMyBack(15,$this->auth->id);
+
+                // 赠送聊天气泡
+                if($noblelevelInfo->tqgq) {
+                    $params_from = $this->request->request("params_from"); // 贵族等级ID
+                    $attireInfo = \app\common\model\Attire::where(["use"=>1,"use_id"=>$level_id])->find();
+                    $attireInfo && \app\common\model\AttireBack::addToMyBack($attireInfo->id,$this->auth->id,$params_from);
+                }
+
+
+                $this->success("开通成功!");
+            }
+
+        }catch (ValidateException $e) {
+            Db::rollback();
+            $this->error($e->getMessage());
+        } catch (PDOException $e) {
+            Db::rollback();
+            $this->error($e->getMessage());
+        } catch (Exception $e) {
+            Db::rollback();
+            $this->error($e->getMessage());
+        }
+    }
+
+
+    /**
+     * 获取指定等级的贵族数据
+     * @param $level_id
+     */
+    private function getNobleLevelData($level_id)
+    {
+
+        $getNobleLevelList = controller('api/Party')->checkGetNobleLevelList(config('token')['key']);
+        foreach ($getNobleLevelList as $v){
+            if ($level_id == $v['id']) return $v;
+        }
+        return [];
+    }
+
+    /**
+     * 消费足额开通贵族(内部调用)
+     * @param string $tokenKey 内部调用密码
+     * @param string $level_id
+     * @return void
+     */
+    public function checkBeNoble2($tokenKey='',$level_id=''){
+
+        if ($tokenKey!==config('token')['key']) return;
+        $this->beNoble2($level_id);
+    }
+    private function beNoble2($level_id) {
+        if (empty($level_id)) return;
+
+        //算当日0点开启的
+        $time = strtotime(date('Y-m-d'),time());
+        // 获取贵族信息
+        $noblelevelModel = new \app\common\model\NobleLevel();
+        $nldlModel = new \app\common\model\NobleDredgeLog();
+        $noblelevelInfo = $this->getNobleLevelData($level_id);
+
+        Db::startTrans();
+        try {
+            // 获取贵族等级开通信息
+            $where = [];
+            $where["user_id"] = $this->auth->id;
+            $where["level_no"] = $noblelevelInfo["level_no"];
+            $nldlCount = 0;
+            $nldlInfo = $nldlModel->where($where)->order("dredge_num", "desc")->find();
+            if (!empty($nldlInfo)) $nldlCount = $nldlInfo["dredge_num"];
+
+            // 更新用户贵族信息
+            $userModel = new \app\common\model\User();
+            $where = [];
+            $where["id"] = $this->auth->id;
+            $duetime = strtotime("+1 month", $time);
+            $nextMonth = $duetime;
+            $data = [];
+//            if($level_id>$this->auth->noble_max) {
+//                $data["noble_max"] = $level_id;
+//            }
+            $data["noble"] = $level_id;
+            $data["noble_duetime"] = $duetime;
+            $res1 = $userModel->update($data, $where);
+
+            // 添加贵族等级开通明细
+            $data = [];
+            $data["user_id"] = $this->auth->id;
+            $data["level_no"] = $noblelevelInfo["level_no"];
+            $data["dredge_num"] = $nldlCount + 1;
+            $data["createtime"] = time();
+            $res2 = $nldlModel->insertGetId($data);
+
+            if ($res1 && $res2) {
+                Db::commit();
+                // $this->onNobleEffect($noblelevelInfo,$this->auth->id,$this->auth->nickname);
+                $this->onNobleAttire($noblelevelInfo, $this->auth->id, $nextMonth, $time);
+
+                // +exp
+                $nobleArr = ['1' => 'entymIFE3J'];
+                isset($nobleArr[$level_id]) && \app\common\model\TaskLog::tofinish($this->auth->id, $nobleArr[$level_id], 1);
+                // +message
+                \app\common\model\Message::addMessage($this->auth->id, "贵族开通通知", "恭喜,您已成功开通!" . $noblelevelInfo["name"] . " 贵族特权!");
+
+                // 赠送消息尾灯
+                \app\common\model\AttireBack::addToMyBack(15, $this->auth->id);
+
+                // 赠送聊天气泡
+                if ($noblelevelInfo['tqgq']) {
+                    $params_from = $this->request->request("params_from"); // 贵族等级ID
+                    $attireInfo = \app\common\model\Attire::where(["use" => 1, "use_id" => $level_id])->find();
+                    $attireInfo && \app\common\model\AttireBack::addToMyBack($attireInfo->id, $this->auth->id, $params_from);
+                }
+
+                $this->onNobleEffect($noblelevelInfo,$this->auth->id,$this->auth->nickname);
+                //定时保级
+//                echo '升级'.$level_id;
+                if ($level_id>1) QueueApi::timeRelegation($this->auth->id,$nextMonth,$level_id);
+            }
+        }catch (ValidateException $e) {
+            Db::rollback();
+            $this->error($e->getMessage());
+        } catch (\PDOException $e) {
+            Db::rollback();
+            $this->error($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollback();
+            $this->error($e->getMessage());
+        }
+
+    }
+
+    /**
+     * 开通贵族后效果
+     */
+    private function onNobleEffect($noblelevelInfo,$user_id,$user_nickname) {
+
+        $serviceNotice = "";
+        $serviceSvga = "";
+        $partyNotice = "";
+        // 全服通知
+        if($noblelevelInfo["qftz"] == 1) {
+            $serviceNotice = "恭喜,玩家:".$user_nickname." 成功升级:".$noblelevelInfo["name"]."贵族特权!";
+        }
+        //全服动画
+        if($noblelevelInfo["qfdh"]) {
+            $serviceSvga = $noblelevelInfo["qfdh"];
+        }
+        // 公屏通知
+        if($noblelevelInfo["gptz"] == 1) {
+            $partyNotice = "恭喜,玩家:".$user_nickname." 成功升级:".$noblelevelInfo["name"]."贵族特权!";
+        }
+
+        $tcpArr = [];
+        $tcpArr['type'] = "userBeNoble";
+        $tcpArr['data'] = [
+            'user_id' => $user_id,
+            'nickname' => $user_nickname,
+            'serviceNotice' => $serviceNotice,
+            'serviceSvga' => $serviceSvga,
+            'partyNotice' => $partyNotice,
+        ];
+        $tcpJson = json_encode($tcpArr);
+        Gateway::sendToAll($tcpJson);
+
+    }
+
+    /**
+     * 开通贵族后获得专属座驾
+     */
+    private function onNobleAttire($noblelevelInfo,$user_id,$nextMonth,$time) {
+        // 获取贵族专属座驾信息
+        $nobleAttireInfo = \app\common\model\NobleAttire::where(["noble_id"=>$noblelevelInfo["id"]])->find();
+        if($nobleAttireInfo) {
+            Db::startTrans();
+            try{
+                // 更新当前用户背包使用状态
+                $res1 = \app\common\model\AttireBack::update(["is_using"=>0],["user_id"=>$user_id]);
+                // 保存用户背包信息
+                $data = [];
+                $data["user_id"] = $user_id;
+                $data["attire_id"] = 0;
+                $data["type"] = 1;
+                $data["attire_name"] = $nobleAttireInfo["attire_name"];
+                $data["price"] = $nobleAttireInfo["price"];
+                $data["file_image"] = $nobleAttireInfo["file_image"];
+                $data["android_image"] = $nobleAttireInfo["file_image"];
+                $data["gif_image"] = $nobleAttireInfo["gif_image"];
+                $data["limit_day"] = round(($nextMonth-$time)/86400);
+                $data["duetime"] = $nextMonth;
+                $data["is_use"] = 1;
+                $data["is_using"] = 1;
+                $data["createtime"] = time();
+                $res2 = \app\common\model\AttireBack::insert($data);
+                if($res1 && $res2) {
+                    Db::commit();
+                }
+
+            }catch (ValidateException $e) {
+                Db::rollback();
+                $this->error($e->getMessage());
+            } catch (PDOException $e) {
+                Db::rollback();
+                $this->error($e->getMessage());
+            } catch (Exception $e) {
+                Db::rollback();
+                $this->error($e->getMessage());
+            }
+        }
+    }
+
+    public function aa() {
+        Gateway::sendToAll("aaaaaa");
+    }
+}

+ 2 - 1
application/api/controller/Party.php

@@ -265,7 +265,8 @@ class Party extends Common
         $index = $this->request->request('index',0); // 全部分类0=否1=是
 
         //更新ip,设备id
-        if($is_recommend == 1) controller('api/User')->changeDeviceIp();
+        //非原创,注释
+        //if($is_recommend == 1) controller('api/User')->changeDeviceIp();
 
         $start = ($thispage-1)*$pagenum;
         $end = $start+($pagenum-1);

+ 0 - 0
application/index/controller/Tenim.php → application/api/controller/Tenim.php


+ 42 - 0
application/api/controller/User.php

@@ -11,6 +11,7 @@ use think\Validate;
 
 use app\common\library\Token;
 use think\Db;
+use app\common\model\UserDeviceInfo;
 
 /**
  * 会员接口,登录,注册,修改资料等
@@ -508,4 +509,45 @@ class User extends Api
             $this->error($this->auth->getError());
         }
     }
+
+    /**
+     * 记录当前登陆的设备ID,设备信息,IP等
+     */
+    public function changeDeviceIp()
+    {
+        // 接口防并发
+        if (!$this->apiLimit(1, 5000)) {
+            return ;
+        }
+
+        $user = $this->auth->getUser();
+        $ip = request()->ip();
+        $deviceId = $this->request->request('device_id','');
+        $phoneModel = $this->request->request('phone_model','');
+        $brand = $this->request->request('brand','');
+        $apiVersion = $this->request->request('api_version','');
+        $deviceOs = $this->request->request('device_os','');
+
+        if ($ip !== $user->loginip){
+            $update = [];
+            $update['id'] = $user->id;
+            $update['loginip'] = $ip;
+            \app\common\model\User::update($update);
+        }
+
+        $userDeviceInfo = UserDeviceInfo::get(['user_id'=>$user->u_id]);
+        if (empty($userDeviceInfo)){
+            $userDeviceInfo = new UserDeviceInfo();
+            $userDeviceInfo->user_id = $user->u_id;
+        }
+        $userDeviceInfo->device_os = $deviceOs;
+        $userDeviceInfo->device_id = $deviceId;
+        $userDeviceInfo->phone_model = $phoneModel;
+        $userDeviceInfo->brand = $brand;
+        $userDeviceInfo->api_version = $apiVersion;
+        $userDeviceInfo->save();
+
+        //首页接口调用,这里不反回信息
+//        $this->success("更新成功!");
+    }
 }

+ 34 - 0
application/common/controller/Api.php

@@ -368,4 +368,38 @@ class Api
             db('api_request_log')->where('id',API_REQUEST_ID)->update(['result'=>json_encode($log_result)]);
         }
     }
+
+    /**
+     * 接口请求限制
+     * @param int $apiLimit
+     * @param int $apiLimitTime
+     * @param string $key
+     * @return bool | true:通过 false:拒绝
+     */
+    public function apiLimit($apiLimit = 1, $apiLimitTime = 1000, $key = '')
+    {
+        $userId = $this->auth->id;
+        $controller = request()->controller();
+        $action = request()->action();
+
+        if (!$key) {
+            $key = strtolower($controller) . '_' . strtolower($action) . '_' . $userId;
+        }
+
+        $redis = new Redis();
+        $redisconfig = config("redis");
+        $redis->connect($redisconfig["host"], $redisconfig["port"]);
+        $check = $redis->exists($key);
+        if ($check) {
+            $redis->incr($key);
+            $count = $redis->get($key);
+            if ($count > $apiLimit) {
+                return false;
+            }
+        } else {
+            $redis->incr($key);
+            $redis->pExpire($key, $apiLimitTime);
+        }
+        return true;
+    }
 }

+ 101 - 0
application/common/controller/RedisLeaderboard.php

@@ -0,0 +1,101 @@
+<?php
+namespace app\common\controller;
+
+use Redis;
+
+/**
+ * 使用rediszset的排行榜
+ * @author harry.lv
+ *
+ */
+class RedisLeaderboard
+{
+
+    /**
+     *
+     * @var object redis client
+     */
+    private $redis;
+    /**
+     *
+     * @var string 放置排行榜的key
+     */
+    private $leaderboard;
+
+    /**
+     * 构造函数
+     * @param object $redis 已连接redis的phpredis的对象
+     * @param string $leaderboard 字符串,排行榜的key名
+     */
+    public function __construct($leaderboard = '') {
+
+        $this->redis = new \Redis();
+        $this->redis->connect('127.0.0.1');
+        $this->leaderboard = $leaderboard;
+    }
+    /**
+     * 获取当前的排行榜的key名
+     * @return string
+     */
+    public function getLeaderboard()
+    {
+        return $this->leaderboard;
+    }
+    /**
+     * 将对应的值填入到排行榜中
+     * @param  $node 对应的需要填入的值(比如用户的id)
+     * @param number $count 对应的值,默认值为1
+     * @return Long 1 if the element is added. 0 otherwise.
+     */
+    public function addLeaderboard($node, $count = 1)
+    {
+        return $this->redis->zAdd($this->leaderboard, $count, $node);
+    }
+    /**
+     * 给出对应的排行榜
+     * @param int $number 需要给出排行榜数目
+     * @param bool $asc 排序顺序 true为按照高分为第0
+     * @param bool $withscores 是否需要分数
+     * @param callback $callback 用于处理排行榜的回调函数
+     * @return [] 对应排行榜
+     */
+    public function getLeadboard($number, $asc = true, $withscores = false,$callback = null)
+    {
+        if ($asc) {
+            $nowLeadboard =  $this->redis->zRevRange($this->leaderboard, 0, $number -1, $withscores);//按照高分数顺序排行;
+        } else {
+            $nowLeadboard =  $this->redis->zRange($this->leaderboard, 0, $number -1, $withscores);//按照低分数顺序排行;
+        }
+
+
+        if ($callback) {
+            //使用回调处理
+            return $callback($nowLeadboard);
+        } else {
+            return $nowLeadboard;
+        }
+    }
+    /**
+     * 获取给定节点的排名
+     * @param string $node 对应的节点的key名
+     * @param string $asc 是否按照分数大小正序排名, true的情况下分数越大,排名越高
+     * @return 节点排名,根据$asc排序,true的话,第一高分为0,false的话第一低分为0
+     */
+    public function getNodeRank($node, $asc = true)
+    {
+        if ($asc) {
+            //zRevRank 分数最高的排行为0,所以需要加1位
+            return $this->redis->zRevRank($this->leaderboard, $node);
+        } else {
+            return $this->redis->zRank($this->leaderboard, $node);
+        }
+    }
+
+    /**
+     * 计算给定的一个或多个有序集的并集
+     */
+    public function getZunionstore() {
+        $this->redis->zUnionStore();
+    }
+
+}

+ 17 - 0
application/common/model/Gift.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class Gift extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+}

+ 17 - 0
application/common/model/GiftBack.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class GiftBack extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+}

+ 22 - 0
application/common/model/GiftBox.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+use Redis;
+/**
+ * 模型
+ */
+class GiftBox extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+
+    public function getOnlySpecialAttr($value)
+    {
+        $url = config('cos')['url'];
+        return $url.$value;
+    }
+
+}

+ 54 - 0
application/common/model/GiftUserParty.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace app\common\model;
+
+use addons\faqueue\library\QueueApi;
+use think\Model;
+
+/**
+ * 赠送礼物模型
+ */
+class GiftUserParty extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+
+    protected static function init()
+    {
+        GiftUserParty::afterInsert(function ($giftUserParty) {
+            if ($giftUserParty->party_id > 0) {
+                $giftNotice = config("site.giftNotice");
+                $bigGiftNotice = config("site.bigGiftNotice");
+                $partyInfo = $giftUserParty->party;
+                $money = $giftUserParty->value / 100;
+
+                $type = 0;
+                if ($money >= $bigGiftNotice) {
+                    $type = 72;
+                }elseif ($money >= $giftNotice){
+                    $type = 71;
+                }
+
+                $type > 0 and QueueApi::sendGroupMessage($type, $giftUserParty->user->nickname, $giftUserParty->toUser->nickname, $partyInfo, $giftUserParty);
+            }
+        });
+    }
+
+    public function user()
+    {
+        return $this->belongsTo('app\common\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
+    }
+
+    public function toUser()
+    {
+        return $this->belongsTo('app\common\model\User', 'user_to_id', 'id', [], 'LEFT')->setEagerlyType(0);
+    }
+
+    public function party()
+    {
+        return $this->belongsTo('app\common\model\Party', 'party_id', 'id', [], 'LEFT')->setEagerlyType(0);
+    }
+}

+ 77 - 0
application/common/model/Guild.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+use think\Db;
+use fast\Random;
+
+/**
+ * 模型
+ */
+class Guild extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+
+    /**
+     * 创建公会
+     */
+    public static function createGuild($party_id,$party_name,$user_id) {
+        Db::startTrans();
+        try{
+            // 获取g_id
+            $ids = self::column("g_id");
+            $data = [
+                "g_id" => self::getUinqueId(4,$ids),
+                "user_id" => $user_id,
+                "party_id" => $party_id,
+                "name" => $party_name."的公会",
+                "image" => "/assets/img/guild_image.jpeg",
+                "desc" => "请编辑公会简介内容!",
+                "notice" => "请编辑公会公告内容!",
+                "createtime" => time()
+            ];
+            $guild_id = self::insertGetId($data);
+            // 添加工会长
+            $data = [
+                "guild_id" => $guild_id,
+                "user_id" => $user_id,
+                "role" => 2,
+                "sign_type" => 3,
+                "status" => 1,
+                "sign_time" => 4070880000,
+                "createtime" => time()
+            ];
+            $res2 = \app\common\model\GuildMember::insert($data);
+            // 更新用户公会ID
+            $res3 = \app\common\model\User::update(["guild_id"=>$guild_id],["id"=>$user_id]);
+
+            if($guild_id && $res2 && $res3) {
+                Db::commit();
+            }
+        }catch (ValidateException $e) {
+            Db::rollback();
+        } catch (PDOException $e) {
+            Db::rollback();
+        } catch (Exception $e) {
+            Db::rollback();
+        }
+
+    }
+
+    /**
+     * 生成不重复的随机数字
+     */
+    public static function getUinqueId($length = 4,$ids = []) {
+        $newid = Random::build("nozero",$length);
+        if(in_array($newid,$ids)) {
+            self::getUinqueId(4,$ids);
+        }
+        return $newid;
+    }
+
+}

+ 17 - 0
application/common/model/GuildApply.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+/**
+ * 模型
+ */
+class GuildApply extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+
+}

+ 17 - 0
application/common/model/GuildMember.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+/**
+ * 模型
+ */
+class GuildMember extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+
+}

+ 34 - 0
application/common/model/Message.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 系统消息模型
+ */
+class Message extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+
+
+    /**
+     * 添加系统消息
+     */
+    public static function addMessage($user_id,$title,$content) {
+        if(!$user_id || !$title || !$content) {
+            return false;
+        }
+        $data = [];
+        $data["user_id"] = $user_id;
+        $data["title"] = $title;
+        $data["content"] = $content;
+        $data["createtime"] = time();
+        return self::insert($data);
+    }
+
+}

+ 15 - 0
application/common/model/Music.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class Music extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+}

+ 17 - 0
application/common/model/NobleLevel.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class NobleLevel extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+}

+ 106 - 0
application/common/model/Party.php

@@ -0,0 +1,106 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+use Redis;
+/**
+ * 模型
+ */
+class Party extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+    protected $updateTime = 'updatetime';
+
+
+    /**
+     * 根据partyid 获取 party 信息
+     */
+    public function getPatyInfoByPartyId($party_id,$room_type,$type_id,$is_recommend,$all,$start = 0,$end = 9,$index) {
+        if(!$party_id) return false;
+        // 判断派对是否存在
+        $redis = new Redis();
+        $redisconfig = config("redis");
+        $redis->connect($redisconfig["host"], $redisconfig["port"]);
+        if(!is_array($party_id)) {
+            return [];
+        }
+        $redisPartyInfo = [];
+        foreach($party_id as $k => $v) {
+            $getredisPartyInfo = $redis->get($room_type.'_'.$k);
+
+            $foreachData = json_decode($getredisPartyInfo,true);
+
+            if(!$foreachData || $foreachData["is_close"] == 1) continue;
+            if(!$foreachData || $foreachData["is_online"] == 0) continue;
+            if(!$foreachData || $foreachData["party_pass"] != '') continue;
+            $mod = isset($foreachData["party_type"])?intval($foreachData["party_type"])%5:1;
+            if(isset($foreachData["type_name"]) && $foreachData["type_name"]) {
+                $type_name = $foreachData["type_name"];
+            } else {
+                $type_name = "普通房";
+            }
+
+            $hasdata = false;
+            if($all == 1) {
+                if($is_recommend == 1) {
+                    if($foreachData["is_recommend"] == 1) $hasdata = true;
+                } else {
+                    $hasdata = true;
+                }
+            } elseif($type_id > 0) {
+                if($type_id == $foreachData["party_type"]) $hasdata = true;
+            }
+            if($foreachData["status"] != 1) $hasdata = false;
+            $hasdata && $redisPartyInfo[] = [
+                "id" => $foreachData["id"],
+                "party_id" => $foreachData["party_id"],
+                "r_id" => $foreachData["party_id"],
+                "party_name" => $foreachData["party_name"],
+                "party_pass" => $foreachData["party_pass"]?$foreachData["party_pass"]:"",
+                "party_hot" => $v,
+                "party_logo" => $this->httpurl($foreachData["party_logo"]),
+                "party_type" => $type_name,
+                "avatar" => $room_type == 2 ? $foreachData["avatar"]:"",
+                "party_type_color" => $mod == 0?5:$mod,
+                "party_user" => isset($foreachData["party_user"]) ? array_values($foreachData["party_user"]) : [] // 当前麦位人头像
+            ];
+
+        }
+
+        $resdata = [];
+        if($index == 1) {
+            $num = $end - $start + 1;
+            $countData = count($redisPartyInfo);
+            if($num > $countData) $num = $countData;
+            if($redisPartyInfo) {
+                $dataRand = array_rand($redisPartyInfo,$num);
+                $dataRand = is_array($dataRand)?$dataRand:[$dataRand];
+                if($redisPartyInfo) foreach($redisPartyInfo as $k => $v) if(in_array($k,$dataRand)) $resdata[] = $v;
+            }
+
+        } else {
+            if($redisPartyInfo) foreach($redisPartyInfo as $k => $v) if($k >= $start && $k <= $end) $resdata[] = $v;
+        }
+
+        return $resdata;
+    }
+
+    /**
+     * 判断当前url是否为全路径,并返回全路径
+     */
+    protected function httpurl($path) {
+        // 获取当前域名
+        if(strpos($path,'http://') === false && strpos($path,'https://') === false) {
+            $host = config("cos")['url'];
+            $url = $host.$path;
+        } else {
+            $url = $path;
+        }
+        return $url;
+    }
+}

+ 17 - 0
application/common/model/PartyBackground.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class PartyBackground extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+}

+ 17 - 0
application/common/model/PartyCellection.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class PartyCellection extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+}

+ 15 - 0
application/common/model/PartyGif.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class partyGif extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+}

+ 15 - 0
application/common/model/PartyGifType.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class PartyGifType extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+}

+ 15 - 0
application/common/model/PartyHeadgif.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class PartyHeadgif extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+}

+ 16 - 0
application/common/model/PartyHot.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+use Redis;
+/**
+ * 模型
+ */
+class PartyHot extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+
+}

+ 17 - 0
application/common/model/PartyJoin.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class PartyJoin extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+}

+ 17 - 0
application/common/model/PartyType.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class PartyType extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+}

+ 19 - 0
application/common/model/RedisTops.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+use Redis;
+/**
+ * 模型
+ */
+class RedisTops extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+
+
+}

+ 79 - 0
application/common/model/TaskLog.php

@@ -0,0 +1,79 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class TaskLog extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+//    protected $updateTime = 'updatetime';
+
+    /**
+     * 增加任务完成进度
+     */
+    public static function tofinish($user_id,$task_no,$number) {
+        if(!$user_id || !$task_no || !$number) {
+            return false;
+        }
+        // 查询任务明细
+        $taskModel = new \app\common\model\Task();
+        $tasklogModel = new \app\common\model\TaskLog();
+        $where = [];
+        $where["task_no"] = $task_no;
+        $where["is_show"] = 1;
+        $taskInfo = $taskModel->where($where)->find();
+        if(!$taskInfo) {
+            return false;
+        }
+        // 添加/修改任务日志
+        $where = [];
+        $where["user_id"] = $user_id;
+        $where["task_id"] = $taskInfo["id"];
+        $taskInfo["type_id"] == 2 && $where["finish_date"] = date("Ymd");
+        $tasklogInfo = $tasklogModel->where($where)->find();
+        if($tasklogInfo) {
+            if($tasklogInfo["finish_number"] >= $taskInfo["number"] || $tasklogInfo["is_finish"] == 1) {
+                if($tasklogInfo["finish_number"] >= $taskInfo["number"]) {
+                    $tasklogInfo->is_finish = 1;
+                    $tasklogInfo->save();
+                } else {
+                    return false;
+                }
+            }
+            $finish_number = $tasklogInfo["finish_number"]+$number;
+            $where = [];
+            $where["id"] = $tasklogInfo["id"];
+            $data = [];
+            $data["finish_number"] = $finish_number;
+            $data["pace"] = round($finish_number/$taskInfo["number"],2)*100;
+            $data["finish_date"] = date("Ymd");
+            if($data["pace"]>=100) {
+                $data["is_finish"] = 1;
+                $data["finish_time"] = time();
+            }
+            $res = $tasklogModel->update($data,$where);
+        } else {
+            $data = [];
+            $data["user_id"] = $user_id;
+            $data["task_id"] = $taskInfo["id"];
+            $data["finish_number"] = $number;
+            $data["pace"] = round($number/$taskInfo["number"],2)*100;
+            $data["finish_date"] = date("Ymd");
+            if($data["pace"]==100) {
+                $data["is_finish"] = 1;
+                $data["finish_time"] = time();
+            }
+            $data["createtime"] = time();
+            $res = $tasklogModel->insertGetId($data);
+        }
+        return $res;
+    }
+}

+ 170 - 0
application/common/model/User.php

@@ -148,4 +148,174 @@ class User extends Model
         }
         return $level;
     }
+
+    /**
+     * 根据排行信息获取用户信息
+     * @param $getweek
+     * @return array|bool
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function rankList($data) {
+        if(!$data) return [];
+
+        // 获取用户id
+        $ids = array_keys($data);
+        // 获取指定用户信息
+        $where = [];
+        $where["id"] = ["in",$ids];
+        $userList = $this->where($where)->select();
+        if($userList) {
+            // 用户ID作为下标
+            $userIdKeyList = [];
+            foreach($userList as $k => $v) {
+                $userIdKeyList[$v["id"]] = $v;
+            }
+            // 执行等量替换
+            $userrankList = [];$rank = 1;
+            foreach($data as $k => $v) {
+                $userrankList[] = [
+                    "rank" => $rank,
+                    "user_id" => $userIdKeyList[$k]["id"],
+                    "avatar" => $userIdKeyList[$k]["avatar"],
+                    "nickname" => $userIdKeyList[$k]["nickname"],
+                    "gender" => $userIdKeyList[$k]["gender"], // 性别
+                    "level" => $userIdKeyList[$k]["level"], // 积分等级
+                    "jewel" => $v, // 财富数
+                ];
+                $rank ++;
+            }
+        }
+        return $userrankList;
+    }
+
+    /**
+     * 根据手机号查询账户信息
+     * @param   string $value
+     * @return string
+     */
+    public static function getByMobile($value,$field = "*")
+    {
+        if ($value) {
+
+            $value = self::field($field)->where('mobile',$value)->find();
+        }
+        return $value;
+    }
+
+    /**
+     * 获取用户贵族信息
+     */
+    public static function getUserNoble($user_id) {
+        $result = [];
+        $result["noble_on"] = 0;
+        $nobleInfo = self::alias("a")
+            ->field("a.noble,n.level_no,a.noble_duetime,n.explain")
+            ->join("hx_noble_level n","a.noble = n.id")
+            ->where(["a.id"=>$user_id])->find();
+
+        if($nobleInfo && $nobleInfo["noble_duetime"] > time()) {
+            $result["noble_on"] = 1;
+            $result["noble"] = $nobleInfo["noble"];
+            $result["explain"] = $nobleInfo["explain"];
+            $result["level_no"] = $nobleInfo["level_no"] ? $nobleInfo["level_no"] : "";
+            $result["noble_duetime"] = date("Y-m-d H:i:s", $nobleInfo["noble_duetime"]);
+        }
+
+        return $result;
+    }
+
+    /**
+     * 获取用户贵族开通信息
+     */
+    public function getUserNobleInfo($user_id) {
+        $result = [];
+        $result["noble_on"] = 0;
+        $result["noble"] = 0;
+        $result["noble_txt"] = "";
+        $result["noble_duetime"] = 0;
+        $nobleInfo = $this->alias("a")
+            ->field("a.noble,n.level_no,a.noble_duetime,n.name,n.back_image,n.icon_image,n.jctx,n.tqgq,n.lxrys,n.zlys,n.diylw,n.fjft,n.zdych")
+            ->join("hx_noble_level n","a.noble = n.id")
+            ->where(["a.id"=>$user_id])->find();
+        if($nobleInfo) {
+            if($nobleInfo["noble_duetime"] > time()) {
+                $result["noble_on"] = 1;
+                $result["noble"] = $nobleInfo["noble"];
+                $result["level_no"] = $nobleInfo["level_no"]?$nobleInfo["level_no"]:"";
+                $result["noble_txt"] = $nobleInfo["name"]?$nobleInfo["name"]:"";
+//                $result["noble_back_image"] = $nobleInfo["back_image"];
+                $result["noble_icon_image"] = $nobleInfo["icon_image"]?$nobleInfo["icon_image"]:"";
+                $result["noble_jctx"] = $nobleInfo["jctx"]?$nobleInfo["jctx"]:"";
+//                $result["noble_tqgq"] = $nobleInfo["tqgq"];
+                $result["noble_lxrys"] = $nobleInfo["lxrys"]?$nobleInfo["lxrys"]:"";
+                $result["noble_zlys"] = $nobleInfo["zlys"]?$nobleInfo["zlys"]:"";
+                $result["noble_diylw"] = $nobleInfo["diylw"]?$nobleInfo["diylw"]:"";
+                $result["noble_fjft"] = $nobleInfo["fjft"]?$nobleInfo["fjft"]:"";
+                $result["noble_zdych"] = $nobleInfo["zdych"]?$nobleInfo["zdych"]:"";
+                $result["noble_duetime"] = date("Y-m-d H:i:s",$nobleInfo["noble_duetime"]);
+            } else {
+                $result["noble"] = $nobleInfo["noble"];
+                $result["noble_txt"] = $nobleInfo["name"]?$nobleInfo["name"]:"";
+                $nobleInfo["noble"] > 0 && $result["noble_duetime"] = -1; // 已到期
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * 增加经验值
+     */
+    public static function addEmpirical($user_id,$empirical) {
+        if($empirical <= 0) return false;
+        // 获取用户经验值
+        $userInfo = \app\common\model\User::field("id,level,empirical")->where(["id"=>$user_id])->find();
+        if(!$userInfo) return false;
+        $userempirical = $userInfo["empirical"];
+
+        // 增加之后的经验值
+        $empirical = $userempirical + $empirical;
+        // 查询等级配置信息
+        $levelconfigModel = new \app\common\model\UserLevelConfig();
+        $where = [];
+        $where["empirical"] = ["elt",$empirical];
+        $userexplainstart = $levelconfigModel->where($where)->order("empirical","desc")->limit(1)->select();
+
+        if(!$userexplainstart)  {
+            $userexplainlevel = 0;
+        } else {
+            $userexplainlevel = $userexplainstart[0]["level"];
+        }
+
+        // 更新用户等级信息和经验值
+        $data = [];
+        $data["level"] = $userexplainlevel;
+        $data["empirical"] = $empirical;
+        $where = [];
+        $where["id"] = $user_id;
+        $res = \app\common\model\User::update($data,$where);
+
+        // 获取任务信息
+        $taskList = \app\common\model\Task::where(["is_show"=>1])->select();
+        $taskArr = [];
+        if($taskList) foreach($taskList as $k => $v) {
+            $taskArr[$v["task_no"]] = $v["number"];
+        }
+        // 提升等级后 添加经验值任务  +exp
+        $levelup = intval($userexplainlevel)-intval($userInfo["level"]);
+//        echo $userexplainlevel;
+//        print_r($taskArr);exit;
+        isset($taskArr["IbehRkoF"]) && \app\common\model\TaskLog::tofinish($user_id,"IbehRkoF",$levelup);
+        isset($taskArr["CD2Vtv0W"]) && \app\common\model\TaskLog::tofinish($user_id,"CD2Vtv0W",$levelup);
+        isset($taskArr["TL0m4wnf"]) && \app\common\model\TaskLog::tofinish($user_id,"TL0m4wnf",$levelup);
+        isset($taskArr["SHcIn8pz"]) && \app\common\model\TaskLog::tofinish($user_id,"SHcIn8pz",$levelup);
+        isset($taskArr["Y3XZQDGk"]) && \app\common\model\TaskLog::tofinish($user_id,"Y3XZQDGk",$levelup);
+        isset($taskArr["1NBgxLP3"]) && \app\common\model\TaskLog::tofinish($user_id,"1NBgxLP3",$levelup);
+        isset($taskArr["ai5l2QkD"]) && \app\common\model\TaskLog::tofinish($user_id,"ai5l2QkD",$levelup);
+
+        return $res;
+    }
+
+
 }

+ 17 - 0
application/common/model/UserAnchor.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class UserAnchor extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+}

+ 17 - 0
application/common/model/UserAuth.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class UserAuth extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+}

+ 15 - 0
application/common/model/UserChangeLog.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class UserChangeLog extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+}

+ 16 - 0
application/common/model/UserCharmRank.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+use Redis;
+/**
+ * 模型
+ */
+class UserCharmRank extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+
+}

+ 40 - 0
application/common/model/UserJewelLog.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 用户钻石流水记录模型
+ */
+class UserJewelLog extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+
+    /**
+     * 用户钻石余额变更
+     */
+    public function addUserJewelLog($user_id, $money, $mode, $before, $detail, $type = 1)
+    {
+        if ($mode == "+") {
+            $balance = $before + $money;
+        } else {
+            $balance = $before - $money;
+        }
+        // 添加当前用户钻石流水记录
+        $data = [];
+        $data["user_id"] = $user_id;
+        $data['type'] = $type;
+        $data["value"] = $money;
+        $data["mode"] = $mode;
+        $data["before"] = $before;
+        $data["balance"] = $balance;
+        $data["detail"] = $detail;
+        $data["createtime"] = time();
+        return $this->insertGetId($data);
+    }
+}

+ 15 - 0
application/common/model/UserOnsiteTime.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class UserOnsiteTime extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+}

+ 15 - 0
application/common/model/UserProfitLog.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class UserProfitLog extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+}

+ 41 - 0
application/common/model/UserSoundcoinLog.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 用户声币流水记录模型
+ */
+class UserSoundcoinLog extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+
+    /**
+     * 用户声币余额变更
+     */
+    public function addUserSoundcoinLog($user_id, $money, $mode, $before, $detail, $type = 1, $objId = 0)
+    {
+        if ($mode == "+") {
+            $balance = $before + $money;
+        } else {
+            $balance = $before - $money;
+        }
+        // 添加当前用户钻石流水记录
+        $data = [];
+        $data["user_id"] = $user_id;
+        $data['type'] = $type;
+        $data['obj_id'] = $objId;
+        $data["value"] = $money;
+        $data["mode"] = $mode;
+        $data["before"] = $before;
+        $data["balance"] = $balance;
+        $data["detail"] = $detail;
+        $data["createtime"] = time();
+        return $this->insertGetId($data);
+    }
+}

+ 33 - 0
application/common/model/ViewUserSkill.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+/**
+ * 模型
+ */
+class ViewUserSkill extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+
+    /**
+     * 根据用户ID获取该用户所有技能-只做显示
+     */
+    public function getSkillInfo($user_id) {
+        $where = [];
+        $where["user_id"] = $user_id;
+        return Model("ViewUserSkill")->where($where)->column("skill_name");
+    }
+    /**
+     * 根据用户ID获取该用户所有技能-带ID
+     */
+    public function getSkillInfoId($user_id) {
+        $where = [];
+        $where["user_id"] = $user_id;
+        return Model("ViewUserSkill")->where($where)->select();
+    }
+
+}

+ 34 - 0
application/config.php

@@ -306,4 +306,38 @@ return [
         'SecretId' => 'AKIDd070nmKyAFSP6WHQTEJ1UfeGgquspZ1C',
         'SecretKey' => '9qLbjaDcvn0yg6HE0JRhjU6TcV4V5QUI',
     ],
+    //腾讯cos
+    'cos'                  => [
+        // 链接
+        "url"         => 'https://bansheng-1304213176.file.myqcloud.com',
+        //"url"         => 'https://meet-1251365327.cos.ap-beijing.myqcloud.com',
+        // 固定密钥
+        'secretId'     => 'AKIDd070nmKyAFSP6WHQTEJ1UfeGgquspZ1C',
+        // 固定密钥
+        'secretKey'      => '9qLbjaDcvn0yg6HE0JRhjU6TcV4V5QUI',
+        // 存储桶
+        'bucket'      => 'bansheng-1304213176',
+        // bucket 所在园区
+        'region'      => 'ap-guangzhou',
+        // 密钥有效期
+        'durationSeconds'      => 1800,
+        // 允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
+        'allowPrefix'      => '*',
+
+    ],
+    //    'redis'                  => [
+//        // 主机
+//        'host'     => '172.16.0.12',
+//        // 密码
+//        'password'     => 'bans9543',
+//        // 端口
+//        'port'      => 6379,
+//    ],
+    'redis'                  => [
+        // 主机
+        'host'     => '127.0.0.1',
+        // 端口
+        'port'      => 6379,
+    ],
+
 ];

+ 2 - 0
application/extra/site.php

@@ -28,6 +28,7 @@ return array (
     'user' => '会员配置',
     'example' => '示例分组',
     'website' => '金钱变量',
+    'party' => '语聊变量',
   ),
   'mail_type' => '1',
   'mail_smtp_host' => 'smtp.qq.com',
@@ -53,4 +54,5 @@ return array (
   'typing_min_price' => '6',
   'vip_price_discount' => '95',
   'user_sign_gift_vipdays' => '4',
+  'roomLimit' => '100',
 );