Compare commits

...

7 Commits

10 changed files with 188 additions and 115 deletions

View File

@ -3,6 +3,7 @@
namespace app\controller\admin\api\v1; namespace app\controller\admin\api\v1;
use app\dao\UserDao; use app\dao\UserDao;
use app\model\UserPhoneDayLog;
use app\dao\UserRewardDao; use app\dao\UserRewardDao;
use support\Request; use support\Request;
use App\Utils\ApiResponse; use App\Utils\ApiResponse;
@ -210,10 +211,11 @@ class JobuserController
// 遍历每个手机号,查询该手机号的在线时间总和 // 遍历每个手机号,查询该手机号的在线时间总和
foreach ($UserPhone as $v) { foreach ($UserPhone as $v) {
$time = UserPhoneLog::where('phone', $v->phone)->sum('time'); $time = UserPhoneLog::where('phone', $v->phone)->sum('time');
$time2 = UserPhoneDayLog::where('phone', $v->phone)->sum('time');
// 将手机号和总时间添加到结果数组中 // 将手机号和总时间添加到结果数组中
$userPhonesWithTime[] = [ $userPhonesWithTime[] = [
'phone' => $v->phone, 'phone' => $v->phone,
'total_time' => floor($time / 60) 'total_time' => floor(($time+$time2) / 60)
]; ];
} }
$res['user'] = $user; $res['user'] = $user;

View File

@ -3,26 +3,18 @@
namespace app\controller\api; namespace app\controller\api;
use support\Request; use support\Request;
use App\Utils\ApiResponseApp;
use App\model\Dictionary;
use App\model\Message;
use App\model\ExchangeRate;
use app\model\User;
use app\model\UserPhoneDayLog; use app\model\UserPhoneDayLog;
use app\model\UserPhoneLog; use app\model\UserPhoneLog;
use app\model\UserReward; use App\Utils\ApiResponseApp;
use hg\apidoc\annotation as Apidoc; use Carbon\Carbon;
use support\Db; use support\Db;
use support\Log; use support\Log;
use Carbon\Carbon; use Exception;
use hg\apidoc\annotation as Apidoc;
/** /**
* @Apidoc\Title("自用测试?") * @Apidoc\Title("自用测试")
*/ */
class TextController class TextController
{ {
protected $noNeedLogin = ['classifyPhoneOnlineHistory', 'get_projectdetailed', 'get_mechanism_list']; protected $noNeedLogin = ['classifyPhoneOnlineHistory', 'get_projectdetailed', 'get_mechanism_list'];
@ -34,40 +26,62 @@ class TextController
*/ */
public function classifyPhoneOnlineHistory(Request $request) public function classifyPhoneOnlineHistory(Request $request)
{ {
$threeDaysAgo = Carbon::now()->subDays(3)->startOfDay(); // 三天前的开始时间 // 计算三天前的日期
$date = Db::table('user_phone_log') $threeDaysAgo = Carbon::now()->subDays(3)->startOfDay();
// 查询三天前的日期列表
$dates = Db::table('user_phone_log')
->selectRaw('DATE(created_at) AS date') ->selectRaw('DATE(created_at) AS date')
->where('created_at', '<=', $threeDaysAgo) ->where('created_at', '<', $threeDaysAgo)
->groupByRaw('DATE(created_at)') ->groupByRaw('DATE(created_at)')
->orderBy('date') ->orderBy('date')
->get(); ->get();
foreach ($date as $v) {
// var_dump($v->date);
// 遍历每个日期
foreach ($dates as $v) {
$date = $v->date; $date = $v->date;
// 使用 Carbon 格式化日期为一天的开始和结束 // 使用 Carbon 获取当天的开始和结束时间
$startOfDay = Carbon::parse($date)->startOfDay(); $startOfDay = Carbon::parse($date)->startOfDay();
$endOfDay = Carbon::parse($date)->endOfDay(); $endOfDay = Carbon::parse($date)->endOfDay();
// 查询指定日期的记录 // 查询当天的日志记录,并按手机号汇总在线时间
$logs = UserPhoneLog::whereBetween('created_at', [$startOfDay, $endOfDay]) $logs = UserPhoneLog::whereBetween('created_at', [$startOfDay, $endOfDay])
->selectRaw('phone, SUM(time) AS total_time') // 按照手机号分组,统计总时长 ->selectRaw('phone, SUM(time) AS total_time')
->groupBy('phone') ->groupBy('phone')
->get(); ->get();
var_dump($date);
// 处理每个手机的在线时长 // 准备批量插入的数据
$batchData = [];
foreach ($logs as $log) { foreach ($logs as $log) {
// 在这里可以处理每个手机的在线时长,如记录日志、更新数据库等 $batchData[] = [
echo "Phone: {$log->phone}, Total Time: {$log->total_time}" . PHP_EOL; 'phone' => $log->phone,
$UserPhoneDayLog=new UserPhoneDayLog(); 'created_at' => $startOfDay,
$UserPhoneDayLog->phone=$log->phone; 'updated_at' => $startOfDay,
$UserPhoneDayLog->created_at=$startOfDay; 'time' => $log->total_time,
$UserPhoneDayLog->updated_at=$startOfDay; ];
$UserPhoneDayLog->time=$log->total_time; }
$UserPhoneDayLog->save();
// 开始数据库事务
Db::beginTransaction();
try {
// 批量插入数据到 user_phone_day_log 表
if (!empty($batchData)) {
UserPhoneDayLog::insert($batchData);
}
// 删除已处理的日志记录
UserPhoneLog::whereBetween('created_at', [$startOfDay, $endOfDay])->delete();
// 提交事务
Db::commit();
} catch (Exception $e) {
// 发生异常,回滚事务
Db::rollBack();
// 记录错误日志
Log::error("Error processing date {$date}: " . $e->getMessage());
} }
UserPhoneLog::whereBetween('created_at', [$startOfDay, $endOfDay])->delete();
} }
return ApiResponseApp::success([]);
} }
} }

View File

@ -118,6 +118,9 @@ class WithdrawController
if ($money_no > $user->money) { if ($money_no > $user->money) {
return ApiResponseApp::error(null, '提现积分不足'); return ApiResponseApp::error(null, '提现积分不足');
} }
if ($money_no < 4500) {
return ApiResponseApp::error(null, '提现积分不足');
}
// 获取当前时间的 3 分钟前 // 获取当前时间的 3 分钟前
$threeMinutesAgo = Carbon::now()->subMinutes(3); $threeMinutesAgo = Carbon::now()->subMinutes(3);
@ -140,11 +143,11 @@ class WithdrawController
'createtime2' => date('Y-m-d H:i:s'), 'createtime2' => date('Y-m-d H:i:s'),
'username' => $user->username, 'username' => $user->username,
'status_text' => '申请中', 'status_text' => '申请中',
'accumulated'=>$money_no, 'accumulated' => $money_no,
'fee'=>self::$handlingFee, 'fee' => self::$handlingFee,
'account'=>$userbank->account, 'account' => $userbank->account,
'bank_name'=>$userbank->bank_name, 'bank_name' => $userbank->bank_name,
'bank_username'=>$userbank->bank_username 'bank_username' => $userbank->bank_username
]); ]);
//大于1000积分等待管理员审核 //大于1000积分等待管理员审核
if ($money_no >= 100000) { if ($money_no >= 100000) {
@ -155,47 +158,19 @@ class WithdrawController
//用户积分减少$money //用户积分减少$money
UserRewardDao::base($user_id, 1, - ($money_no + self::$handlingFee), '提现'); UserRewardDao::base($user_id, 1, - ($money_no + self::$handlingFee), '提现');
//获取刚刚存入数据库的id(订单号) //获取刚刚存入数据库的id(订单号)
$orderId = $withdraw->id; $orderId = $withdraw->id;
$res = PaymentNew::pushMoney($money, $userbank->bank_username, $userbank->account, $userbank->bank_name, $orderId); $res = PaymentNew::pushMoney($money, $userbank->bank_username, $userbank->account, $userbank->bank_name, $orderId);
// //逻辑错误需要修改 //逻辑错误需要修改
if ($res->Success) { if ($res->Success) {
$withdraw->update([ $withdraw->update([
'status' => 4, // 'status' => 4, //
'status_text' => trans('等待银行打款'), 'status_text' => trans('等待银行打款'),
'order_number' => $res->TrackingNumber ?? null, 'order_number' => $res->TrackingNumber,
]); ]);
return ApiResponseApp::success(null, '转账成功'); return ApiResponseApp::success(null, '转账成功');
} else { } else {
$errorMsg = '';
if ($res->ErrorMessage == "CheckIpAddressFailed") {
$errorMsg = 'IP 检查失败';
}
if ($res->ErrorMessage == "CheckEncryptValueFailed ") {
$errorMsg = '加密检查失败';
}
if ($res->ErrorMessage == "PaymentChannelClosed") {
$errorMsg = '平台休息中,暂不接单';
}
if ($res->ErrorMessage == "InsufficientBalance") {
$errorMsg = '余额不足';
}
if ($res->ErrorMessage == "TryAgainLater") {
$errorMsg = '系统忙碌中,请稍后再试';
}
if ($res->ErrorMessage == "DevError") {
$errorMsg = '程式错误,请联络开发人员';
}
if ($res->ErrorMessage == "PayeeAccountNameFormatError") {
$errorMsg = '收款人帐号格式错误';
}
if ($res->ErrorMessage == "PayeeAccountNumberFormatError") {
$errorMsg = '收款人卡号格式错误';
}
if ($errorMsg == '') {
$errorMsg = '未知错误';
}
$withdraw->update([ $withdraw->update([
'status' => 5, // 'status' => 5, //
'status_text' => trans('支付错误:') . $res->ErrorMessage 'status_text' => trans('支付错误:') . $res->ErrorMessage
@ -219,13 +194,14 @@ class WithdrawController
$callbackData = $request->all(); $callbackData = $request->all();
// 记录回调数据以便调试 // 记录回调数据以便调试
Log::info('Payment Callback Received:', $callbackData); Log::info('Payment Callback Received:', $callbackData);
$orderId = $callbackData['TrackingNumber'] ?? null; $orderId = $callbackData['TrackingNumber'];
$failedMessage = $callbackData['FailedMessage'] ?? null; $failedMessage = $callbackData['FailedMessage'] ;
$amount = $callbackData['Amount'] ?? null; $amount = $callbackData['Amount'];
$withdraw = Withdraw::where('order_number', $orderId)->first(); $withdraw = Withdraw::where('order_number', $orderId)->first();
//$failedMessage为null就是成功 //$failedMessage为null就是成功
if ($failedMessage != null) { if ($failedMessage != null) {
//解决多次回调
if ($withdraw->status == 5) { if ($withdraw->status == 5) {
return; return;
} }
@ -241,5 +217,6 @@ class WithdrawController
'status_text' => trans('已到账'), 'status_text' => trans('已到账'),
]); ]);
} }
return 'ok';
} }
} }

View File

@ -14,7 +14,7 @@ class Lang implements MiddlewareInterface
// 将 Accept-Language 中的语言与系统支持的语言进行匹配 // 将 Accept-Language 中的语言与系统支持的语言进行匹配
// 这里假设我们支持 'zh_CN' 和 'en_US',你可以根据实际需求扩展更多语言 // 这里假设我们支持 'zh_CN' 和 'en_US',你可以根据实际需求扩展更多语言
$lang = 'zh_CN'; // 默认语言 $lang = 'en'; // 默认语言
// 提取 Accept-Language 中的语言部分,如 'zh_CN' 或 'en_US' // 提取 Accept-Language 中的语言部分,如 'zh_CN' 或 'en_US'
if (strpos($acceptLanguage, 'zh') === 0) { if (strpos($acceptLanguage, 'zh') === 0) {

View File

@ -5,13 +5,13 @@ namespace app\model;
use support\Model; use support\Model;
/** /**
* 用户WS信息表模型 * 用户WS信息归档表模型
* *
* @property int $id 用户记录的唯一标识符 * @property int $id 用户记录的唯一标识符
* @property string $phone 用户手机号WS手机号 * @property string $phone 用户手机号WS手机号
* @property string $created_at 创建时间 * @property string $created_at 创建时间
* @property string $updated_at 更新时间 * @property string $updated_at 更新时间
* @property string $time 在线时间 * @property int $time 在线时间(单位:秒)
*/ */
class UserPhoneDayLog extends Model class UserPhoneDayLog extends Model
{ {
@ -36,5 +36,11 @@ class UserPhoneDayLog extends Model
*/ */
public $timestamps = true; public $timestamps = true;
/**
* 可批量赋值字段
*
* @var array
*/
protected $fillable = ['phone', 'created_at', 'updated_at', 'time'];
} }

View File

@ -5,17 +5,23 @@ namespace app\model;
use support\Model; use support\Model;
/** /**
* @property integer $id VIP级别的唯一标识符 * Withdraw - 用户提现记录模型
* @property integer $user_id 用户id *
* @property integer $amount 金额 * @property int $id 用户提现记录唯一标识符
* @property integer $status 1申请中 2 已到账 3已驳回 4等待银行打款 5支付失败 * @property int $user_id 用户 ID
* @property integer $gift_amount 赠送积分 * @property float $amount 转账金额
* @property integer $createtime 创建时间(时间戳) * @property string|null $status 状态码 1申请中 2 已到账 3已驳回 4等待银行打款 5支付失败
* @property integer $accumulated 提现积分 * @property string|null $createtime2 创建时间
* @property integer $fee 提现手续费 * @property string|null $username 账号
* @property string $account 提现银行账户 * @property string|null $status_text 状态解释
* @property string $bank_name 提现银行 * @property string|null $created_at 创建时间
* @property string|null $updated_at 更新时间
* @property string|null $order_number 订单编号
* @property string $account 提现银行账户
* @property string $bank_name 提现银行
* @property string $bank_username 提现银行用户名 * @property string $bank_username 提现银行用户名
* @property int $accumulated 积分
* @property int $fee 手续费
*/ */
class Withdraw extends Model class Withdraw extends Model
{ {
@ -42,10 +48,11 @@ class Withdraw extends Model
'createtime2', 'createtime2',
'username', 'username',
'status_text', 'status_text',
'accumulated', 'order_number',
'fee',
'account', 'account',
'bank_name', 'bank_name',
'bank_username' 'bank_username',
'accumulated',
'fee',
]; ];
} }

View File

@ -197,28 +197,10 @@ const X = (e) => (w("data-v-a74356d2"), (e = e()), E(), e),
), ),
Te = () => { Te = () => {
if ("" === X.value) return b(E("请输入金额")); if ("" === X.value) return b(E("请输入金额"));
if (2 == C.value.id || 3 == C.value.id || 6 == C.value.id) { if (X.value / 1 < 4500) return b(E("最低提现金额") + 4500);
if (X.value / 1 > j.userInfo.money - 300) return b(E("余额不足")); // if (X.value / 1 > j.userInfo.money - parseInt(j.config.brl_fee))
if (X.value / 1 < 1e3) return b(E("最低提现金额") + 1e3); if (X.value / 1 > j.userInfo.money )
} else if (1 == C.value.id) {
if (X.value / 1 < 2e4) return b(E("最低提现金额") + 2e4);
if (X.value / 1 > j.userInfo.money - 500) return b(E("余额不足"));
} else if (4 == C.value.id) {
if (X.value / 1 < 5e3) return b(E("最低提现金额") + 5e3);
if (X.value / 1 > j.userInfo.money - 300) return b(E("余额不足"));
} else if (5 == C.value.id) {
if (X.value / 1 <(4e3+500)) return b(E("最低提现金额") + (4e3+500));
if (X.value / 1 > j.userInfo.money - 300) return b(E("余额不足"));
// if (X.value / 1 < 7e3) return b(E("最低提现金额") + 7e3);
// if (X.value / 1 > j.userInfo.money - 500) return b(E("余额不足"));
} else if (7 == C.value.id) {
if (X.value / 1 < 5e3) return b(E("最低提现金额") + 5e3);
if (X.value / 1 > j.userInfo.money - 500) return b(E("余额不足"));
} else {
if (X.value / 1 < 5e3) return b(E("最低提现金额") + 5e3);
if (X.value / 1 > j.userInfo.money - parseInt(j.config.brl_fee))
return b(E("余额不足")); return b(E("余额不足"));
}
if (!Xe.value[C.value.id]) return b(C.value.errorMsg); if (!Xe.value[C.value.id]) return b(C.value.errorMsg);
I({ forbidClick: !0, duration: 0 }), I({ forbidClick: !0, duration: 0 }),
T({ money: X.value, bank_id: Xe.value[C.value.id].id }).then( T({ money: X.value, bank_id: Xe.value[C.value.id].id }).then(

View File

@ -44,15 +44,29 @@ class HttpBase
* @param string $method 请求方法GET/POST * @param string $method 请求方法GET/POST
* @param string|null $baseUri 动态设置 baseUri可选 * @param string|null $baseUri 动态设置 baseUri可选
* @param string $contentType 数据格式json/form * @param string $contentType 数据格式json/form
* @param string|null $token 认证 token可选
* @return array|false 响应的 JSON 数据或 false * @return array|false 响应的 JSON 数据或 false
*/ */
public static function httpclient($data, $url, $method = 'POST', $baseUri = null, $contentType = 'json') public static function httpclient($data, $url, $method = 'POST', $baseUri = null, $contentType = 'json', $token = null)
{ {
$client = self::get_client($baseUri); $client = self::get_client($baseUri);
try { try {
$options = []; $options = [];
// 设置请求头,支持动态传入 token
$headers = [
'Accept' => 'application/json',
];
if ($token) {
// 如果提供了 token则将其加入到 Authorization 头
$headers['Authorization'] = 'Bearer ' . $token;
}
// 添加请求头
$options['headers'] = $headers;
if (strtoupper($method) === 'GET') { if (strtoupper($method) === 'GET') {
// GET 请求将数据作为查询参数 // GET 请求将数据作为查询参数
$options['query'] = $data; $options['query'] = $data;
@ -73,16 +87,14 @@ class HttpBase
$body = $response->getBody()->getContents(); $body = $response->getBody()->getContents();
return json_decode($body, true); return json_decode($body, true);
} catch (RequestException $e) { } catch (RequestException $e) {
// echo "HTTP 请求失败: " . $e->getMessage() . "\n"; // 捕获请求异常
if ($e->hasResponse()) { if ($e->hasResponse()) {
$response = $e->getResponse(); $response = $e->getResponse();
$statusCode = $response->getStatusCode(); // 获取 HTTP 状态码 $statusCode = $response->getStatusCode(); // 获取 HTTP 状态码
$body = $response->getBody()->getContents(); // 获取响应体 $body = $response->getBody()->getContents(); // 获取响应体
// 这里可以根据需要打印响应信息
// echo "状态码: " . $statusCode . "\n";
// echo "响应体: " . $body . "\n";
} }
return $statusCode; return $statusCode; // 返回状态码
} }
} }
} }

18
tests/TestFunction.php Normal file
View File

@ -0,0 +1,18 @@
<?php
namespace Tests;
use App\Utils\API\Rocketgo;
use PHPUnit\Framework\TestCase;
/**
* 自用测试类
*/
class TestFunction extends TestCase
{
public function testPhone()
{
$res = HttpBase::httpclient([], '/api/text/classifyPhoneOnlineHistory', 'GET', null, 'form');
$this->assertEquals(1,$res['code']);
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Tests;
use App\Utils\API\Rocketgo;
use PHPUnit\Framework\TestCase;
/**
* 测试用户提现类
*/
class TestUserWithdraw extends TestCase
{
/**
* 存放用户登录token
*
* @var [type]
*/
private static $UserToken = null;
/**
* 测试用户登录功能
*
*/
public function testUserLogin()
{
$data = ['username' => '01930044627', 'password' => 'cCqQgG9koky^#uDFXllNUM46@jrI7KfsL77IIWwt'];
$res = HttpBase::httpclient($data, '/api/user/login', 'POST', null, 'form');
$token = $res['data']['userinfo']['token'];
$this->assertArrayHasKey('data', $res, "返回的数据应包含 'data' 键");
$this->assertArrayHasKey('userinfo', $res['data'], "返回的数据应包含 'userinfo' 键");
$this->assertArrayHasKey('token', $res['data']['userinfo'], "返回的 'userinfo' 应包含 'token' 键");
$this->assertNotEmpty($token, "token 应该是非空的");
// var_dump($res['data']['userinfo']['token']);
self::$UserToken = $token;
return $token;
}
/**
* 测试用户提款
* 依赖于 testUserLogin() 测试方法
*
* @depends testUserLogin
*/
public function testWithdrawSubmit($token)
{
$data = ['money' => '4500', 'bank_id' => '2923'];
$res = HttpBase::httpclient($data, '/api/withdraw/submit', 'POST', null, 'form',$token);
var_dump($res);
$res = HttpBase::httpclient($data, '/api/withdraw/submit', 'POST', null, 'form',$token);
var_dump($res);
$res = HttpBase::httpclient($data, '/api/withdraw/submit', 'POST', null, 'form',$token);
var_dump($res);
}
}