功能:聊天获取魅力值(方案 B)

- 对指定用户发言时根据性别给魅力:异性 +2,同性 +1(后台可配)
- Redis 每小时上限 20(后台可配 charm_hourly_limit)
- 系统用户、对'大家'发言、悄悄话不触发
- 新增 sysparam:charm_cross_sex / charm_same_sex / charm_hourly_limit
This commit is contained in:
2026-02-27 01:14:24 +08:00
parent b72e2a5936
commit f745db3990
2 changed files with 115 additions and 0 deletions

View File

@@ -135,6 +135,13 @@ class ChatController extends Controller
$user->save();
}
// 7. 聊天给魅力值(仅对指定用户的非悄悄话公开发言有效)
$toUser = $data['to_user'] ?? '大家';
$isSecret = $data['is_secret'] ?? false;
if ($toUser !== '大家' && ! $isSecret) {
$this->grantChatCharm($user, $toUser);
}
return response()->json(['status' => 'success']);
}
@@ -528,6 +535,63 @@ class ChatController extends Controller
]);
}
/**
* 聊天获取魅力值(方案 B每条消息触发Redis 每小时上限控制)
*
* 异性聊天给更多魅力,同性少一些。
* 系统用户(如 AI小助手不触发魅力奖励。
* 发送者和接收者都会获得对应魅力值。
*
* @param mixed $sender 发送消息的用户模型
* @param string $toUsername 接收消息的用户名
*/
private function grantChatCharm(mixed $sender, string $toUsername): void
{
// 系统用户不参与魅力计算
$systemNames = ['大家', '系统传音', '系统公告', '钓鱼播报', '星海小博士', 'AI小助手', '送花播报'];
if (in_array($toUsername, $systemNames)) {
return;
}
// 查找接收者
$receiver = User::where('username', $toUsername)->first();
if (! $receiver) {
return;
}
// 检查发送者每小时魅力上限Redis 自动过期)
$capKey = "charm_cap:{$sender->username}:".date('YmdH');
$hourlyLimit = (int) Sysparam::getValue('charm_hourly_limit', '20');
$currentGained = (int) Redis::get($capKey);
if ($currentGained >= $hourlyLimit) {
return; // 已达本小时上限
}
// 根据性别关系计算魅力增量
$senderSex = $sender->sex ?? '';
$receiverSex = $receiver->sex ?? '';
$isCrossSex = ($senderSex !== $receiverSex) && $senderSex !== '' && $receiverSex !== '';
$charmSame = (int) Sysparam::getValue('charm_same_sex', '1');
$charmCross = (int) Sysparam::getValue('charm_cross_sex', '2');
$charmGain = $isCrossSex ? $charmCross : $charmSame;
// 不超过本小时剩余额度
$remaining = $hourlyLimit - $currentGained;
$charmGain = min($charmGain, $remaining);
if ($charmGain <= 0) {
return;
}
// 发送者获得魅力
$sender->meili = ($sender->meili ?? 0) + $charmGain;
$sender->save();
// 更新 Redis 计数器1 小时过期)
Redis::incrby($capKey, $charmGain);
Redis::expire($capKey, 3600);
}
/**
* 解析奖励数值配置(支持固定值或范围格式)
*

View File

@@ -0,0 +1,51 @@
<?php
/**
* 文件功能:填充聊天魅力值相关的系统参数
*
* 包括:异性聊天魅力值、同性聊天魅力值、每小时魅力上限
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* 插入聊天魅力相关的 sysparam 配置项
*/
public function up(): void
{
DB::table('sysparam')->insert([
[
'varname' => 'charm_cross_sex',
'varvalue' => '2',
'guidetxt' => '异性聊天每条消息增加的魅力值(男→女 或 女→男)',
],
[
'varname' => 'charm_same_sex',
'varvalue' => '1',
'guidetxt' => '同性聊天每条消息增加的魅力值(男→男 或 女→女)',
],
[
'varname' => 'charm_hourly_limit',
'varvalue' => '20',
'guidetxt' => '每小时通过聊天获取的魅力值上限(防刷屏)',
],
]);
}
/**
* 回滚:删除聊天魅力相关配置
*/
public function down(): void
{
DB::table('sysparam')
->whereIn('varname', ['charm_cross_sex', 'charm_same_sex', 'charm_hourly_limit'])
->delete();
}
};