316 lines
9.0 KiB
PHP
316 lines
9.0 KiB
PHP
<?php
|
|
|
|
namespace common\modules\arena\vo;
|
|
|
|
use common\modules\arena\ArenaUtil;
|
|
use common\services\ResultStatusServices;
|
|
use common\services\StatusException;
|
|
use common\utils\CommUtil;
|
|
use Yii;
|
|
use yii\behaviors\TimestampBehavior;
|
|
use yii\db\ActiveRecord;
|
|
|
|
/**
|
|
*
|
|
* CREATE TABLE `arena` (
|
|
* `id` int(11) NOT NULL AUTO_INCREMENT,
|
|
* `user_id` int(11) NOT NULL,
|
|
* `nickname` varchar(45) NOT NULL COMMENT '玩家昵称',
|
|
* `avatar` varchar(500) NOT NULL COMMENT '玩家头像',
|
|
* `score` int(11) NOT NULL COMMENT '分数',
|
|
* `fighting_capacity` int(11) NOT NULL COMMENT '战斗力',
|
|
* `pet_id` int(11) NOT NULL COMMENT '宠物ID',
|
|
* `win_count` int(11) NOT NULL COMMENT '胜利几场',
|
|
* `fail_count` int(11) NOT NULL COMMENT '失败几场',
|
|
* `remaining_challenges_count` int(11) NOT NULL COMMENT '本周剩余挑战次数',
|
|
* `last_challenge_time` int(11) NOT NULL COMMENT '上次挑战时间',
|
|
* `is_get_gift` int(11) NOT NULL COMMENT '是否领取上周奖励',
|
|
* `last_get_gift_time` int(11) NOT NULL COMMENT '奖励上周时间',
|
|
* `last_index` int(11) NOT NULL COMMENT '当前排名',
|
|
* `last_update_index_time` int(11) NOT NULL COMMENT '更新排名时间',
|
|
* `last_week_index` int(11) NOT NULL COMMENT '上周排名',
|
|
* `created_at` int(11) NOT NULL,
|
|
* `updated_at` int(11) NOT NULL,
|
|
* PRIMARY KEY (`id`),
|
|
* UNIQUE KEY `user_id_UNIQUE` (`user_id`),
|
|
* KEY `score` (`score`),
|
|
* KEY `fighting_capacity` (`fighting_capacity`)
|
|
* ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COMMENT='竞技场原始表'
|
|
*/
|
|
|
|
/**
|
|
* 竞技场
|
|
* @property int $id
|
|
* @property int $user_id
|
|
* @property string $nickname //玩家昵称
|
|
* @property string $avatar //玩家头像
|
|
* @property int $index //排名
|
|
* @property int $score //分数
|
|
* @property int $fighting_capacity //战斗力
|
|
* @property int $pet_id //宠物ID
|
|
* @property int $win_count //胜利几场
|
|
* @property int $fail_count //失败几场
|
|
* @property int $remaining_challenges_count //本周剩余挑战次数
|
|
* @property int $last_challenge_time //上次挑战时间
|
|
* @property int $is_get_gift //是否领取上周奖励
|
|
* @property int $last_get_gift_time //奖励上周时间
|
|
* @property int $last_index //上次排名
|
|
* @property int $last_update_index_time //更新排名时间
|
|
* @property int $last_week_index //上周排名
|
|
* @property int $created_at
|
|
* @property int $updated_at
|
|
*/
|
|
class Arena extends ActiveRecord
|
|
{
|
|
public $index = 0; //排名
|
|
|
|
public function behaviors()
|
|
{
|
|
return [
|
|
TimestampBehavior::className(),
|
|
];
|
|
}
|
|
|
|
public function rules()
|
|
{
|
|
return [
|
|
['id', 'default', 'value' => 0],
|
|
|
|
['user_id', 'required'],
|
|
['user_id', 'exist', 'targetClass' => '\common\models\User', 'targetAttribute' => 'id'],
|
|
|
|
['nickname', 'default', 'value' => ''],
|
|
['avatar', 'default', 'value' => ''],
|
|
|
|
['score', 'default', 'value' => 0],
|
|
|
|
['fighting_capacity', 'default', 'value' => 0],
|
|
|
|
['pet_id', 'required'],
|
|
['pet_id', 'exist', 'targetClass' => '\common\modules\pet\vo\Pet', 'targetAttribute' => 'id'],
|
|
|
|
['win_count', 'default', 'value' => 0],
|
|
['fail_count', 'default', 'value' => 0],
|
|
|
|
['remaining_challenges_count', 'default', 'value' => 0],
|
|
['last_challenge_time', 'default', 'value' => 0],
|
|
|
|
['is_get_gift', 'default', 'value' => ArenaUtil::GIFT_NOT_GET],
|
|
['is_get_gift', 'in', 'range' => ArenaUtil::GIFT_GET_LIST],
|
|
|
|
['last_get_gift_time', 'default', 'value' => 0],
|
|
|
|
['last_index', 'default', 'value' => 0],
|
|
['last_update_index_time', 'default', 'value' => 0],
|
|
['last_week_index', 'default', 'value' => 0],
|
|
|
|
['created_at', 'default', 'value' => 0],
|
|
['updated_at', 'default', 'value' => 0],
|
|
];
|
|
}
|
|
|
|
public function toClient()
|
|
{
|
|
$data = $this->toArray();
|
|
$data['index'] = $this->index;
|
|
return $data;
|
|
}
|
|
|
|
public static function findRankList($count = 5)
|
|
{
|
|
$count = (int)$count;
|
|
|
|
$mysql = 'SELECT
|
|
*
|
|
FROM
|
|
(SELECT
|
|
@index:=@index + 1 AS `index`, o.*
|
|
FROM
|
|
(SELECT @index:=0) i, arena o
|
|
ORDER BY score DESC limit 0,:len) AS r';
|
|
|
|
$findList = Yii::$app->db->createCommand($mysql)
|
|
->bindValue(':len', $count)
|
|
->queryAll();
|
|
|
|
$list = [];
|
|
foreach ($findList as $item) {
|
|
$arena = new Arena();
|
|
$arena->setAttributes($item);
|
|
$arena->setIsNewRecord(false);
|
|
$arena->index = $item['index'];
|
|
$arena->saveCurrentIndex();
|
|
|
|
array_push($list, $arena->toClient());
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
public static function findByUserID($userID)
|
|
{
|
|
$mysql = 'SELECT
|
|
*
|
|
FROM
|
|
(SELECT
|
|
@index:=@index + 1 AS `index`, o.*
|
|
FROM
|
|
(SELECT @index:=0) i, arena o
|
|
ORDER BY score DESC) AS r
|
|
WHERE
|
|
user_id = :user_id';
|
|
|
|
$find = Yii::$app->db->createCommand($mysql)
|
|
->bindValue(':user_id', $userID)
|
|
->queryOne();
|
|
if (empty($find)) return null;
|
|
|
|
$arena = new Arena();
|
|
$arena->setAttributes($find);
|
|
$arena->setIsNewRecord(false);
|
|
$arena->index = $find['index'];
|
|
$arena->saveCurrentIndex();
|
|
|
|
return $arena;
|
|
}
|
|
|
|
public static function my_sort($a, $b)
|
|
{
|
|
if ($a->index == $b->index) return 0;
|
|
return ($a->index < $b->index) ? -1 : 1;
|
|
}
|
|
|
|
/**
|
|
* 寻找战力相近的玩家
|
|
* @param $fightingCapacity
|
|
* @return array|null
|
|
*/
|
|
public static function findAllByFightingCapacity($userID, $fightingCapacity, $score)
|
|
{
|
|
|
|
//战力排行
|
|
$fightingCapacity = (int)$fightingCapacity;
|
|
|
|
$mysql = 'SELECT
|
|
*
|
|
FROM
|
|
arena
|
|
WHERE
|
|
fighting_capacity > :fighting_capacity
|
|
LIMIT 0 , 3';
|
|
|
|
$findList = Yii::$app->db->createCommand($mysql)
|
|
->bindValue(':fighting_capacity', $fightingCapacity)
|
|
->queryAll();
|
|
|
|
$userIDList = [];
|
|
$list = [];
|
|
foreach ($findList as $item) {
|
|
$arena = self::findByUserID($item['user_id']);
|
|
if ($arena->user_id == $userID) continue;
|
|
|
|
array_push($userIDList, $arena->user_id);
|
|
array_push($list, $arena);
|
|
}
|
|
|
|
$rList = $list;
|
|
if (count($list) < 3) {
|
|
$topList = self::findRankList();
|
|
foreach ($topList as $item) {
|
|
if (count($rList) == 3 || $item['user_id'] == $userID) continue;
|
|
if (!in_array($item['user_id'], $userIDList)) {
|
|
array_push($rList, $item);
|
|
}
|
|
}
|
|
}
|
|
|
|
//等级排行
|
|
|
|
$levelMysql = 'SELECT
|
|
*
|
|
FROM
|
|
(SELECT
|
|
@index:=@index + 1 AS `index`, o.*
|
|
FROM
|
|
(SELECT @index:=0) i, arena o
|
|
ORDER BY score DESC) AS r
|
|
WHERE
|
|
score > :score
|
|
ORDER BY r.index DESC
|
|
LIMIT 1 , 3';
|
|
|
|
$levelFindList = Yii::$app->db->createCommand($levelMysql)
|
|
->bindValue(':score', $score)
|
|
->queryAll();
|
|
|
|
foreach ($levelFindList as $item) {
|
|
if ($item['user_id'] == $userID) continue;
|
|
|
|
if (!in_array($item['user_id'], $userIDList)) {
|
|
array_push($rList, self::findByUserID($item['user_id']));
|
|
}
|
|
}
|
|
usort($rList, array('common\modules\arena\vo\Arena', 'my_sort'));
|
|
$rList = array_slice($rList, 0, 3);
|
|
|
|
$list=[];
|
|
for ($i = 0; $i < count($rList); $i++) {
|
|
array_push($list,$rList[$i]->toClient());
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* 获取参战宠物战力排行
|
|
* @param $userID
|
|
* @param $fight
|
|
* @return Arena|null
|
|
*/
|
|
public static function findPetFightRankingByUserID($userID, $fight)
|
|
{
|
|
$mysql = 'SELECT
|
|
*
|
|
FROM
|
|
(SELECT
|
|
@index:=@index + 1 AS `index`, o.*
|
|
FROM
|
|
(SELECT @index:=0) i, arena o
|
|
ORDER BY fighting_capacity DESC) AS r
|
|
WHERE
|
|
user_id = :user_id';
|
|
|
|
$find = Yii::$app->db->createCommand($mysql)
|
|
->bindValue(':user_id', $userID)
|
|
->queryOne();
|
|
if (empty($find)) return null;
|
|
|
|
$arena = new Arena();
|
|
$arena->setAttributes($find);
|
|
$arena->setIsNewRecord(false);
|
|
$arena->index = $find['index'];
|
|
$arena->saveCurrentIndex();
|
|
|
|
return $arena;
|
|
}
|
|
|
|
public function saveCurrentIndex()
|
|
{
|
|
//记录上周排名
|
|
$change = false;
|
|
if ($this->last_update_index_time == CommUtil::getWeekTime(time() - 3600 * 24 * 7)) {
|
|
$this->last_week_index = $this->last_index;
|
|
$change = true;
|
|
}
|
|
|
|
//记录当前排名
|
|
if ($this->index != $this->last_index) {
|
|
$this->last_index = $this->index;
|
|
$this->last_update_index_time = CommUtil::getWeekTime(time());
|
|
$change = true;
|
|
}
|
|
|
|
if ($change && !$this->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR, $this->getErrors());
|
|
}
|
|
}
|