Step 4 - MarriageConfigService: - 带60min Cache 的配置读取/写入 - 支持单项/分组/全量读取,管理员保存后自动清缓存 Step 5 - MarriageIntimacyService: - 亲密度增加 + 日志写入 + 等级自动更新 - Redis 每日上限计数器(各来源独立控制) - onFlowerSent/onPrivateChat/onlineTick 接入点方法 - dailyBatch 批量处理(Horizon Job 用) Step 6 - MarriageService(核心业务): - propose/accept/reject/divorce/confirmDivorce/forceDissolve - 所有金币魅力通过 UserCurrencyService 统一记账 - 冷静期检查/超时处理/强制离婚金币全转对方 Models 改良(Marriage/MarriageConfig/MarriageIntimacyLog)
173 lines
4.8 KiB
PHP
173 lines
4.8 KiB
PHP
<?php
|
||
|
||
/**
|
||
* 文件功能:婚姻关系模型(改良版)
|
||
*
|
||
* 对应 marriages 表,管理配对双方的婚姻状态、亲密度、等级及离婚信息。
|
||
* 原 ASP 字段(hyname/hyname1/hytime 等)保留向后兼容,新业务使用 user_id/partner_id。
|
||
*
|
||
* @author ChatRoom Laravel
|
||
*
|
||
* @version 2.0.0
|
||
*/
|
||
|
||
namespace App\Models;
|
||
|
||
use Illuminate\Database\Eloquent\Builder;
|
||
use Illuminate\Database\Eloquent\Model;
|
||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||
|
||
class Marriage extends Model
|
||
{
|
||
/** @var list<string> */
|
||
protected $fillable = [
|
||
// 旧字段(兼容保留)
|
||
'hyname', 'hyname1', 'hytime', 'hygb', 'hyjb', 'i',
|
||
// 新字段
|
||
'user_id', 'partner_id',
|
||
'ring_item_id', 'ring_purchase_id',
|
||
'status',
|
||
'proposed_at', 'expires_at', 'married_at', 'divorced_at',
|
||
'divorce_type', 'divorcer_id', 'divorce_requested_at',
|
||
'intimacy', 'level',
|
||
'online_minutes', 'flower_count', 'chat_count',
|
||
'admin_note',
|
||
];
|
||
|
||
/**
|
||
* 字段类型转换。
|
||
*
|
||
* @return array<string, string>
|
||
*/
|
||
protected function casts(): array
|
||
{
|
||
return [
|
||
'hytime' => 'datetime',
|
||
'proposed_at' => 'datetime',
|
||
'expires_at' => 'datetime',
|
||
'married_at' => 'datetime',
|
||
'divorced_at' => 'datetime',
|
||
'divorce_requested_at' => 'datetime',
|
||
'intimacy' => 'integer',
|
||
'level' => 'integer',
|
||
'online_minutes' => 'integer',
|
||
'flower_count' => 'integer',
|
||
'chat_count' => 'integer',
|
||
];
|
||
}
|
||
|
||
// ──────────────────────────── 关联关系 ────────────────────────────
|
||
|
||
/**
|
||
* 发起方用户。
|
||
*/
|
||
public function user(): BelongsTo
|
||
{
|
||
return $this->belongsTo(User::class, 'user_id');
|
||
}
|
||
|
||
/**
|
||
* 被求婚方用户。
|
||
*/
|
||
public function partner(): BelongsTo
|
||
{
|
||
return $this->belongsTo(User::class, 'partner_id');
|
||
}
|
||
|
||
/**
|
||
* 使用的戒指道具。
|
||
*/
|
||
public function ringItem(): BelongsTo
|
||
{
|
||
return $this->belongsTo(ShopItem::class, 'ring_item_id');
|
||
}
|
||
|
||
/**
|
||
* 亲密度变更日志。
|
||
*/
|
||
public function intimacyLogs(): HasMany
|
||
{
|
||
return $this->hasMany(MarriageIntimacyLog::class);
|
||
}
|
||
|
||
/**
|
||
* 婚礼仪式记录。
|
||
*/
|
||
public function ceremonies(): HasMany
|
||
{
|
||
return $this->hasMany(WeddingCeremony::class);
|
||
}
|
||
|
||
/**
|
||
* 最新一场婚礼。
|
||
*/
|
||
public function latestCeremony(): HasOne
|
||
{
|
||
return $this->hasOne(WeddingCeremony::class)->latestOfMany();
|
||
}
|
||
|
||
// ──────────────────────────── 查询 Scope ──────────────────────────
|
||
|
||
/**
|
||
* 仅返回已婚记录。
|
||
*/
|
||
public function scopeMarried(Builder $query): Builder
|
||
{
|
||
return $query->where('status', 'married');
|
||
}
|
||
|
||
/**
|
||
* 仅返回求婚中记录。
|
||
*/
|
||
public function scopePending(Builder $query): Builder
|
||
{
|
||
return $query->where('status', 'pending');
|
||
}
|
||
|
||
// ──────────────────────────── 业务方法 ────────────────────────────
|
||
|
||
/**
|
||
* 判断指定用户是否为婚姻一方。
|
||
*
|
||
* @param int $userId 用户 ID
|
||
*/
|
||
public function involves(int $userId): bool
|
||
{
|
||
return $this->user_id === $userId || $this->partner_id === $userId;
|
||
}
|
||
|
||
/**
|
||
* 判断两人是否已婚(静态工厂方法)。
|
||
*
|
||
* @param int $userA 用户A ID
|
||
* @param int $userB 用户B ID
|
||
*/
|
||
public static function areMárried(int $userA, int $userB): bool
|
||
{
|
||
return static::query()
|
||
->where('status', 'married')
|
||
->where(function (Builder $q) use ($userA, $userB) {
|
||
$q->where(fn ($q) => $q->where('user_id', $userA)->where('partner_id', $userB))
|
||
->orWhere(fn ($q) => $q->where('user_id', $userB)->where('partner_id', $userA));
|
||
})
|
||
->exists();
|
||
}
|
||
|
||
/**
|
||
* 获取用户当前有效婚姻(pending 或 married 状态)。
|
||
*
|
||
* @param int $userId 用户 ID
|
||
*/
|
||
public static function currentFor(int $userId): ?static
|
||
{
|
||
return static::query()
|
||
->whereIn('status', ['pending', 'married'])
|
||
->where(function (Builder $q) use ($userId) {
|
||
$q->where('user_id', $userId)->orWhere('partner_id', $userId);
|
||
})
|
||
->first();
|
||
}
|
||
}
|