no message

This commit is contained in:
hellcat 2025-04-29 20:52:48 +08:00
parent 5d9e2f3053
commit 7c7e9513b1
3 changed files with 206 additions and 27 deletions

View File

@ -22,6 +22,7 @@ use App\Models\Ducks;
use App\Models\Visitor;
use App\Models\CountVisitor;
use App\Models\CountUser;
use App\Models\Product;
use App\Services\TomTool\TgSendFormat;
use App\Services\IM\Telegram;
use App\Services\Tg\ReportUser;
@ -74,7 +75,6 @@ final class Cron
$sPrevTimeStart = strtotime($sPrevDateStart);
$sPrevTimeEnd = strtotime($sPrevDateEnd);
$sPrevDate30 = date("Y-m-d", strtotime("-30 day"));
// echo "<pre>";
//// 访客统计 start
$aVisitorCount = Visitor::select('from', DB::raw('count(*) as count'))
@ -322,6 +322,7 @@ final class Cron
}
// todo 反水
// 这里返水的话,等于是直接覆盖的用户不返水,自然过期的用户返水,这到合理,自然过期的才是好用户
try {
Notification::notifyUser($user, $_ENV['appName'] . '-您的套餐已经过期', $text);
@ -336,30 +337,52 @@ final class Cron
$user->save();
}
//// 流量到期处理
//// 流量到期处理 不重置了,默认暂停就行
// 这里只重置付费用户不重置免费用户。那么假如免费用户领了60g流量他就真的能用到没。付费用户则会连带套餐一起重置掉。
// 应该问题不大,赠送流量有关时,区分免费付费用户,对付费大方(陷阱),对免费抠门。
// 其实压根就不叠加,套餐流量直接覆盖免费流量。
// 再者,免费流量
// 总之,免费流量就是零头,无所谓重置的。
$ud = $user->u + $user->d;
if ($ud >= $user->transfer_enable && $user->class > 0) {
$sText = "你好,系统发现您的流量已用完,已转为免费体验帐户,可用每日签到获取免费流量。";
try {
Notification::notifyUser($user, $_ENV['appName'] . '-您的流量已用完', $sText);
} catch (GuzzleException|ClientExceptionInterface|TelegramSDKException $e) {
echo $e->getMessage() . PHP_EOL;
}
$user->u = 0;
$user->d = 0;
$user->transfer_today = 0;
$user->class = 0;
$user->save();
}
// 用户流量用光,或者用户等级到期,就重置。
// 流量用光时顺便标记订单。在这里标记不容易埋坑。
// $ud = $user->u + $user->d;
// if ($ud >= $user->transfer_enable) {
//
// // 订单标记为过期
// // 既然class大于0就说明肯定有激活的套餐对吧
// $activated_order = (new Order())->where('user_id', $user->id)
// ->where('status', 'activated')
// ->where('product_type', 'tabp')
// ->orderBy('id')
// ->first();
//
// // 以防万一,判断一下
// if (!$activated_order) {
// $activated_order->status = 'expired';
// $activated_order->update_time = time();
// $activated_order->save();
// }
//
//// tomd($activated_order, 1);
// // 用户流量重置
// $user->u = 0;
// $user->d = 0;
// $user->class = 0;
// $user->transfer_today = 0;
// $user->transfer_enable = 0;
// $user->class_expire = date("Y-m-d H:i:s"); // 用户等级时间到当前,注意订单没变,应该合理
// $user->save();
//
// $sText = "你好,系统发现您的流量已用完,已转为免费体验帐户,可用每日签到获取免费流量。";
//
// try {
// Notification::notifyUser($user, $_ENV['appName'] . '-您的流量已用完', $sText);
// } catch (GuzzleException|ClientExceptionInterface|TelegramSDKException $e) {
// echo $e->getMessage() . PHP_EOL;
// }
//
// }
//// end
}
@ -418,6 +441,20 @@ final class Cron
}
}
// 激活订单
/**
逻辑:
查询,遍历所有用户
根据uid找待激活订单
根据uid找已激活订单
判断:当有待激活订单时:
判断:无已激活订单,激活
判断:此用户流量满了,激活。就加了这个。
无待激活订单时,确定不激活
流量没满时,走原来的逻辑,无已激活时激活
判断:有已激活订单
判断:订单的等级时间过期,标记过期
*/
public static function processTabpOrderActivation(): void
{
$users = User::all();
@ -436,12 +473,129 @@ final class Cron
->where('product_type', 'tabp')
->orderBy('id')
->first();
/*
添加条件,当流量用满时,可以直接激活新套餐。
那如果,没有新套餐,就等于旧套餐被暂停了,等到用户等级过期时,走原有的重置,没错。
那如果,有新套餐,那就是直接覆盖,刷新。
也就是说,用户流量不满时,就是当前套餐到期再激活新套餐。
而用户流量满时,就是直接激活新套餐。
这里是有点怪,两个玩法。何不直接叠加?
如果都直接叠加,会怎样?
连充12个月会员直接是一年好像没问题之前为什么否了
好像是因为续流量比较亏,因为时间是虚的而流量是实的。
但这其实没办法,不管用什么方案,流量满了总得允许人家续,没得变。
根本区别就是,叠加有粘性,不叠加省成本。
用户流量满了,他就叠流量,最后时间剩很多,流量没有,套餐就成了流量包。
“我套餐还没到期,但是流量已经没了,无所谓”,所以这里不是留住客户的理由。
用户时间到了,他就叠时间,最后流量用不完,时间快到期了。
那基本上他会狂用看4k被。
“我流量还没用完呢,续一下”
“这么多流量,看高清”
理想情况,时间叠褶叠着,流量用不完,然后时间到期,一下清空。
这种情况,应该不会太多,他流量多自然就不会省着用了。
所以,还是别叠加,留住客户可以返水之类的,而不是在这里暗着给他们实惠。
不叠加指的是时间不叠加,流量还是要叠的,这没有其他办法。
顶多是流量满了直接重置时间,但这想想没必要。时间是虚的,重置不重置没什么区别,倒是产生业务上的混乱感。
完全没必要,流量满了其实就暂停了,再买套餐就覆盖。重置也相当于暂停,再买套餐也是覆盖,都一样。
之前的逻辑怪圈,就是他原本用户等级到期会重置,我就想当然的做成流量满了也重置。
首先他为什么原本到期重置
因为订单function只影响订单状态不影响用户状态他俩是独立的。
if订单到期修改。if用户等级到期修改。代码上是各玩各的只是刚好订单和用户等级的时间是一致的所以会同时处理。
你被误导的地方是有可激活订单时,会去覆盖用户。就仿佛他俩是直接关联的。
但要是没有可激活订单呢?用户就一直不重置了,到流量用完暂停。这就是要有用户重置的原因。
用户重置是基础,订单的重置是补偿。
那流量为什么不能重置
因为没必要,反而导致业务逻辑奇怪。
为什么奇怪用户原本是20号到期流量用光变成了10号到期他会迷茫。
用户10号到期也就算了订单状态也跟着变了提前到期了。就很怪。
所以就不重置它,保持暂停就行了。等待时间到期走原本的重置。
还有一个点webapi那边会判断流量满了暂停而不会判断等级到期暂停所以要有用户时间重置不然就会跑到流量用光为止。
所以流量满了可以不重置,会自然暂停。
最后确定一下,到底行不行,别又弄错了。
现在就是说,只要流量满了,就直接激活待激活套餐,即便还存在已激活订单。
就会同时会出现两个激活套餐,这倒没事,只要代码没有要求只读一个激活套餐。到时检查一下。
其他地方都不用动,爱加就加个流量提醒(本来就有)。对吗?
对,就是这样,流量满了就允许直接激活覆盖新套餐,就这个逻辑。
实在不放心,就把当前订单标记成过期。
没问题,确实没问题,就这么干。
再缕一次
起初,发现流量满了不能激活套餐(原本是用流量包续)
我最初是重置了套餐满了的用户流量但没重置订单状态。幸亏是只重置class大于0不会有大的损失。
然后想到应该标记订单,当前订单标记成过期,下一个订单就能激活了。
至于用户function那边应该不用重置它自然暂停即可。
然后又想到,那会导致业务逻辑怪异,所以就在这加个判断,流量满时直接激活下一个订单,不考虑是否有已激活。这个问题也就解决了。
所以就是说,我要解决《用户流量满了不能激活新套餐的问题》,我就在这里加个判断,逻辑是《流量满了直接激活新套餐,即便存在已激活订单》。
订单状态有几种?
待激活 - 必须条件
已激活 - 附加条件A反向
取消 - 不相关,必然不进
等待付款 - 不相关,必然不进
也就是
如果有待激活,就直接激活,不管是否有已激活
如果没有待激活,不管。自然暂停,自然重置。
没有其他情况,对吗?
两种条件会激活:
没有已激活订单,只有待激活订单
有激活订单,用户流量满了
其他条件不会激活?
那如果,没有已激活订单,同时用户流量满了呢?
也会走进来
那无所谓,是按原有逻辑激活
没有待激活是肯定不会进来的
换个说法就是,有待激活,并且没有已激活或者用户流量满了,就进来
激活的必须条件是有待激活订单
然后没有已激活,或者用户流量满了
可能的条件(情况):
有待激活订单,用户流量满 - 已测试
有待激活订单,无已激活订单 - 已测试
假如用户没有已激活套餐,却有等级流量呢
当然是不用管他,活动获取的呗
有待激活订单,用户流量满,无已激活订单
没问题,等于走原来的逻辑
不可能的情况:
有待激活套餐,有激活套餐,用户流量不满 - 已测试
没有待激活套餐 - 不可能
*/
// 如果用户账户中没有已激活的TABP订单且有等待激活的TABP订单则激活最早的等待激活TABP订单
if ($activated_order === null && count($pending_activation_orders) > 0) {
// * 如果用户流量已满,就直接激活待激活订单,不考虑是否有已激活。(之前想的是流量满时把订单标记成过期,这虽然也可以,但是业务逻辑会显得奇怪)
$ud = $user->u + $user->d;
// 待激活订单 > 0 && (没有已激活订单 || 用户流量满)
if (count($pending_activation_orders) > 0 && ($activated_order === null || $ud >= $user->transfer_enable)) {
// if ($activated_order === null && count($pending_activation_orders) > 0) {
// if (($activated_order === null && count($pending_activation_orders) > 0) || ($ud > $user->transfer_enable && count($pending_activation_orders) > 0)) {
$order = $pending_activation_orders[0];
// 获取TABP订单内容准备激活
$content = json_decode($order->product_content);
//// * 是用户流量满时,主动标记订单过期
// 按理说可以有多个已激活,但是以防万一,标记掉
// 假如等级还过期了,就是标记两次,无所谓
if ($ud >= $user->transfer_enable) {
$activated_order->status = 'expired';
$activated_order->update_time = time();
$activated_order->save();
echo "TABP订单 #{$activated_order->id} 已过期(流量满了)。\n";
// tomd($activated_order->status);
}
//// end
//// * 特别活动追加,季套餐赠月套餐,年套餐赠季套餐
// if ($order->huodong_class && $order->huodong_class == "A") {
//
// $oProduct = Product::where("name", $order->product_name)
// ->where("type_by_time", "<", $content->class_time)
// ->orderBy("type_by_time", "desc")
// ->first();
// $oProductContent = json_decode($oProduct->content);
//
// $content->class_time += $oProductContent->class_time;
// $content->bandwidth += $oProductContent->bandwidth;
//
// }
//// end
// 激活TABP
// 等级时间,流量,都是覆盖刷新,不是叠加
$user->u = 0;
$user->d = 0;
$user->transfer_today = 0;
@ -449,7 +603,7 @@ final class Cron
$user->class = $content->class;
$old_class_expire = new DateTime();
$user->class_expire = $old_class_expire
->modify('+' . $content->class_time . ' days')->format('Y-m-d H:i:s');
->modify('+' . $content->class_time . ' days')->format('Y-m-d H:i:s'); // 当前时间+订单等级时间
$user->node_group = $content->node_group;
$user->node_speedlimit = $content->speed_limit;
$user->node_iplimit = $content->ip_limit;
@ -464,12 +618,14 @@ final class Cron
if ($activated_order !== null) {
$content = json_decode($activated_order->product_content);
// 原来用的是$content->time
if ($activated_order->update_time + $content->class_time * 86400 < time()) {
$activated_order->status = 'expired';
$activated_order->update_time = time();
$activated_order->save();
echo "TABP订单 #{$activated_order->id} 已过期。\n";
}
}
}
@ -546,6 +702,7 @@ final class Cron
echo Tools::toDateTime(time()) . ' 时间包订单激活处理完成' . PHP_EOL;
}
// 标记订单
public static function processPendingOrder(): void
{
$pending_payment_orders = (new Order())->where('status', 'pending_payment')->get();

View File

@ -10,6 +10,31 @@ use App\Services\DB;
final class Order
{
private function format($v)
{
$v['create_time'] = date("Y-m-d H:i:m", $v['create_time']);
$v['update_time'] = date("Y-m-d H:i:m", $v['update_time']);
$v['product_content'] = json_decode($v['product_content']);
return $v;
}
public function Limit($aParam)
{
$iLimit = $aParam['aArg'][1] ?? 1;
$aOrder = Order::orderBy('id', 'desc')->limit($iLimit)->get()->toArray();
foreach ($aOrder as $v) {
$aOrderSingle = $this->format($v);
$sMsg = json_encode($aOrderSingle, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
$this->oTGHttp->sendToTG($sMsg);
}
$this->oHttp::response(200, 'ok');
}
public function Find($aParam)
{
@ -20,10 +45,7 @@ final class Order
if ($aOrder) {
$aOrderNew = [];
foreach ($aOrder as $k => $v) {
$v['create_time'] = date("Y-m-d H:i:m", $v['create_time']);
$v['update_time'] = date("Y-m-d H:i:m", $v['update_time']);
$v['product_content'] = json_decode($v['product_content']);
$aOrderNew[] = $v;
$aOrderNew[] = $this->format($v);
}
} else {
$aOrderNew = ["not have id" => $iUserId];

View File

@ -39,7 +39,7 @@ final class User extends Base
public function Limit($aParam)
{
// $sField = $aParam['aOption'][1];
$iLimit = $aParam['aArg'][1] ?? 5; // 默认五条
$iLimit = $aParam['aArg'][1] ?? 1; // 默认五条
$aUser = ModelUser::where("class", '>', 0)->orderBy("id", "desc")->limit($iLimit)->get()->toArray();