Files
mini_tp/app/api/model/Member.php
T
nepiedg 5a9d6090f3 feat(member): enhance product info processing and add new utility methods
- 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.
2026-04-02 10:43:25 +00:00

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) . ',';
}
}