2026-05-29 19:54:56 +08:00

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());
}
}