5a9d6090f3
- Updated `getProductInfo` method to return processed product information using `buildEffectiveProductInfo`. - Introduced new private methods for building effective product info, resolving software account levels, and checking special TikTok account status. - Refactored platform string handling with `appendPlatform` method to ensure unique and sorted platform entries. - Updated platform name mappings in `PlatformService` for consistency with new naming conventions.
298 lines
8.7 KiB
PHP
298 lines
8.7 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace app\api\model;
|
|
|
|
use think\Model;
|
|
|
|
/**
|
|
* 用户模型 (对应原系统 member 表)
|
|
* 数据库连接: dbmember (member库)
|
|
*/
|
|
class Member extends Model
|
|
{
|
|
// 设置连接名 (对应 config/database.php 中的 connections)
|
|
protected $connection = 'dbmember';
|
|
|
|
// 表名
|
|
protected $name = 'member';
|
|
|
|
// 主键
|
|
protected $pk = 'userid';
|
|
|
|
// 自动时间戳
|
|
protected $autoWriteTimestamp = false;
|
|
|
|
// 隐藏字段
|
|
protected $hidden = ['password'];
|
|
|
|
/**
|
|
* 根据用户名查找用户
|
|
* @param string $username
|
|
* @return Member|null
|
|
*/
|
|
public static function findByUsername(string $username): ?Member
|
|
{
|
|
return self::where('username', $username)->find();
|
|
}
|
|
|
|
/**
|
|
* 根据用户ID查找用户
|
|
* @param int $userid
|
|
* @return Member|null
|
|
*/
|
|
public static function findByUserid(int $userid): ?Member
|
|
{
|
|
return self::where('userid', $userid)->find();
|
|
}
|
|
|
|
/**
|
|
* 验证密码
|
|
* 当前项目统一使用双重 MD5。
|
|
*
|
|
* @param string $password 明文密码
|
|
* @return bool
|
|
*/
|
|
public function verifyPassword(string $password): bool
|
|
{
|
|
return self::makePassword($password) === $this->password;
|
|
}
|
|
|
|
/**
|
|
* 生成系统使用的密码摘要
|
|
* @param string $password 明文密码
|
|
* @return string
|
|
*/
|
|
public static function makePassword(string $password): string
|
|
{
|
|
return md5(md5($password));
|
|
}
|
|
|
|
/**
|
|
* 检查用户是否被禁用
|
|
* @return bool
|
|
*/
|
|
public function isDisabled(): bool
|
|
{
|
|
return $this->disabled == 1;
|
|
}
|
|
|
|
/**
|
|
* 检查账号是否过期
|
|
* @return bool
|
|
*/
|
|
public function isExpired(): bool
|
|
{
|
|
if (empty($this->endtime)) {
|
|
return false;
|
|
}
|
|
return $this->endtime < time();
|
|
}
|
|
|
|
/**
|
|
* 获取用户套餐信息
|
|
* @return array|null
|
|
*/
|
|
public function getProductInfo(): ?array
|
|
{
|
|
// 套餐配置改由模型统一封装,避免业务层散落裸表查询。
|
|
$product = ProductList::findByVType((int) $this->v_type);
|
|
|
|
if (!$product) {
|
|
return null;
|
|
}
|
|
|
|
return $this->buildEffectiveProductInfo($product->toArray());
|
|
}
|
|
|
|
/**
|
|
* 获取代理商信息
|
|
* @return array|null
|
|
*/
|
|
public function getAgentInfo(): ?array
|
|
{
|
|
if (empty($this->formtypeid)) {
|
|
return null;
|
|
}
|
|
|
|
return self::where('userid', $this->formtypeid)->find();
|
|
}
|
|
|
|
/**
|
|
* 记录登录日志
|
|
* @param bool $success
|
|
* @param string $loginType
|
|
* @return void
|
|
*/
|
|
public function logLogin(bool $success, string $loginType = 'password'): void
|
|
{
|
|
try {
|
|
MemberLoginLog::recordLogin([
|
|
'userid' => $this->userid,
|
|
'ip' => request()->ip(),
|
|
'time' => time(),
|
|
'succeed' => $success ? 1 : 0,
|
|
'diqu' => '',
|
|
'login_type' => $loginType,
|
|
'adminid' => 0,
|
|
'v_type' => $this->v_type ?? 0,
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
// 日志记录失败不影响登录
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 构建与 acgpmw `MemberController` 对齐后的套餐信息。
|
|
*
|
|
* 这里只补齐当前 tp 已实际用到的套餐二次加工逻辑:
|
|
* 1. 处理特定版本新增平台
|
|
* 2. 处理用户单独平台覆盖
|
|
* 3. 处理公众号/微信绑定等特殊额度
|
|
* 4. 处理内部账号临时补平台
|
|
*
|
|
* @param array $productInfo 原始套餐信息
|
|
* @return array
|
|
*/
|
|
private function buildEffectiveProductInfo(array $productInfo): array
|
|
{
|
|
$productInfo['platforms'] = (string) ($productInfo['platforms'] ?? '');
|
|
|
|
// 对齐 acgpmw:金钻/钻石新注册账号额外补充 B站 和 B家号。
|
|
if ((int) $this->regtime >= 1773158400
|
|
&& in_array((int) $this->v_type, [123, 124], true)
|
|
&& (int) ($productInfo['video_num'] ?? 0) > 0
|
|
) {
|
|
$productInfo['platforms'] = self::appendPlatform($productInfo['platforms'], 2);
|
|
$productInfo['platforms'] = self::appendPlatform($productInfo['platforms'], 5);
|
|
}
|
|
|
|
// 对齐 acgpmw:用户单独平台权限可直接覆盖套餐平台集合。
|
|
$specialPlatforms = DySpecialPlatforms::findActiveByUserid((int) $this->userid);
|
|
$productInfo['sora_turntable_type'] = (int) ($specialPlatforms->sora_turntable_type ?? 0);
|
|
if ($specialPlatforms) {
|
|
$specialPlatformsData = $specialPlatforms->toArray();
|
|
if (!empty($specialPlatformsData['platforms'])) {
|
|
$productInfo['platforms'] = (string) $specialPlatformsData['platforms'];
|
|
}
|
|
if (!empty($specialPlatformsData['kword_num'])) {
|
|
$productInfo['kword_num'] = $specialPlatformsData['kword_num'];
|
|
}
|
|
if (!empty($specialPlatformsData['is_video_num']) && (int) ($productInfo['video_num'] ?? 0) < 0) {
|
|
$productInfo['video_num'] = 1;
|
|
}
|
|
}
|
|
|
|
// 对齐 acgpmw:用户单独绑定额度可覆盖微信/公众号绑定数量。
|
|
$specialBinding = DySpecialBinding::findActiveByUserid((int) $this->userid);
|
|
if ($specialBinding) {
|
|
$specialBindingData = $specialBinding->toArray();
|
|
if ((int) ($specialBindingData['wx_num'] ?? 0) > 0) {
|
|
$productInfo['wx_num'] = (int) $specialBindingData['wx_num'];
|
|
}
|
|
if ((int) ($specialBindingData['wxgzh_num'] ?? 0) > 0) {
|
|
$productInfo['wxgzh_num'] = (int) $specialBindingData['wxgzh_num'];
|
|
}
|
|
}
|
|
|
|
$productInfo['soft_groups_auth'] = $this->resolveSoftGroupsAuth();
|
|
|
|
// 对齐 acgpmw:内部号在部分版本下临时追加 B家号、B站、公众号。
|
|
if ((int) $this->staff_type === 1
|
|
&& in_array((int) $productInfo['soft_groups_auth'], [0, 2], true)
|
|
&& !$this->hasTitkAuth()
|
|
) {
|
|
$productInfo['platforms'] = self::appendPlatform($productInfo['platforms'], 2);
|
|
$productInfo['platforms'] = self::appendPlatform($productInfo['platforms'], 5);
|
|
$productInfo['platforms'] = self::appendPlatform($productInfo['platforms'], 6);
|
|
}
|
|
|
|
return $productInfo;
|
|
}
|
|
|
|
/**
|
|
* 计算软件账号等级标识。
|
|
*
|
|
* 该规则直接按 acgpmw `MemberController` 中的 `soft_groups_auth` 判定对齐。
|
|
*
|
|
* @return int
|
|
*/
|
|
private function resolveSoftGroupsAuth(): int
|
|
{
|
|
$vType = (int) $this->v_type;
|
|
$softGroupsAuth = 0;
|
|
$softGroupVTypes = [144, 145, 146, 147, 156];
|
|
|
|
if (in_array($vType, $softGroupVTypes, true)) {
|
|
$softGroupsAuth = 1;
|
|
}
|
|
if (in_array($vType, [149, 152, 157], true)) {
|
|
$softGroupsAuth = 2;
|
|
}
|
|
if (in_array($vType, [161], true)) {
|
|
$softGroupsAuth = 3;
|
|
}
|
|
if (in_array($vType, [162], true)) {
|
|
$softGroupsAuth = 4;
|
|
}
|
|
if (in_array($vType, [169], true)) {
|
|
$softGroupsAuth = 6;
|
|
}
|
|
if (in_array($vType, [170], true)) {
|
|
$softGroupsAuth = 7;
|
|
}
|
|
if (in_array($vType, [171, 172, 173], true)) {
|
|
$softGroupsAuth = 8;
|
|
}
|
|
if (in_array($vType, [176, 177, 178, 179], true)) {
|
|
$softGroupsAuth = 9;
|
|
}
|
|
if (in_array($vType, [180], true)) {
|
|
$softGroupsAuth = 10;
|
|
}
|
|
|
|
return $softGroupsAuth;
|
|
}
|
|
|
|
/**
|
|
* 判断当前用户是否属于 TikTok 特殊账号版本。
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function hasTitkAuth(): bool
|
|
{
|
|
return in_array((int) $this->v_type, [158, 159, 160, 163, 164, 166], true);
|
|
}
|
|
|
|
/**
|
|
* 追加平台到逗号包裹的平台字符串中。
|
|
*
|
|
* @param string $platforms 平台字符串,如 `,0,1,6,`
|
|
* @param int $platform 平台编号
|
|
* @return string
|
|
*/
|
|
private static function appendPlatform(string $platforms, int $platform): string
|
|
{
|
|
if (strpos($platforms, ',' . $platform . ',') !== false) {
|
|
return $platforms;
|
|
}
|
|
|
|
$platformList = [];
|
|
$platformText = trim($platforms, ',');
|
|
if ($platformText !== '') {
|
|
foreach (explode(',', $platformText) as $item) {
|
|
if ($item === '') {
|
|
continue;
|
|
}
|
|
$platformList[] = (int) $item;
|
|
}
|
|
}
|
|
|
|
$platformList[] = $platform;
|
|
$platformList = array_values(array_unique($platformList));
|
|
sort($platformList);
|
|
|
|
return ',' . implode(',', $platformList) . ',';
|
|
}
|
|
}
|