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

View File

@ -3,26 +3,18 @@
namespace app\controller\api;
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\UserPhoneLog;
use app\model\UserReward;
use hg\apidoc\annotation as Apidoc;
use App\Utils\ApiResponseApp;
use Carbon\Carbon;
use support\Db;
use support\Log;
use Carbon\Carbon;
use Exception;
use hg\apidoc\annotation as Apidoc;
/**
* @Apidoc\Title("自用测试?")
* @Apidoc\Title("自用测试")
*/
class TextController
{
protected $noNeedLogin = ['classifyPhoneOnlineHistory', 'get_projectdetailed', 'get_mechanism_list'];
@ -34,40 +26,62 @@ class TextController
*/
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')
->where('created_at', '<=', $threeDaysAgo)
->where('created_at', '<', $threeDaysAgo)
->groupByRaw('DATE(created_at)')
->orderBy('date')
->get();
foreach ($date as $v) {
// var_dump($v->date);
// 遍历每个日期
foreach ($dates as $v) {
$date = $v->date;
// 使用 Carbon 格式化日期为一天的开始和结束
// 使用 Carbon 获取当天的开始和结束时间
$startOfDay = Carbon::parse($date)->startOfDay();
$endOfDay = Carbon::parse($date)->endOfDay();
// 查询指定日期的记录
// 查询当天的日志记录,并按手机号汇总在线时间
$logs = UserPhoneLog::whereBetween('created_at', [$startOfDay, $endOfDay])
->selectRaw('phone, SUM(time) AS total_time') // 按照手机号分组,统计总时长
->selectRaw('phone, SUM(time) AS total_time')
->groupBy('phone')
->get();
var_dump($date);
// 处理每个手机的在线时长
// 准备批量插入的数据
$batchData = [];
foreach ($logs as $log) {
// 在这里可以处理每个手机的在线时长,如记录日志、更新数据库等
echo "Phone: {$log->phone}, Total Time: {$log->total_time}" . PHP_EOL;
$UserPhoneDayLog=new UserPhoneDayLog();
$UserPhoneDayLog->phone=$log->phone;
$UserPhoneDayLog->created_at=$startOfDay;
$UserPhoneDayLog->updated_at=$startOfDay;
$UserPhoneDayLog->time=$log->total_time;
$UserPhoneDayLog->save();
$batchData[] = [
'phone' => $log->phone,
'created_at' => $startOfDay,
'updated_at' => $startOfDay,
'time' => $log->total_time,
];
}
// 开始数据库事务
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) {
return ApiResponseApp::error(null, '提现积分不足');
}
if ($money_no < 4500) {
return ApiResponseApp::error(null, '提现积分不足');
}
// 获取当前时间的 3 分钟前
$threeMinutesAgo = Carbon::now()->subMinutes(3);
@ -140,11 +143,11 @@ class WithdrawController
'createtime2' => date('Y-m-d H:i:s'),
'username' => $user->username,
'status_text' => '申请中',
'accumulated'=>$money_no,
'fee'=>self::$handlingFee,
'account'=>$userbank->account,
'bank_name'=>$userbank->bank_name,
'bank_username'=>$userbank->bank_username
'accumulated' => $money_no,
'fee' => self::$handlingFee,
'account' => $userbank->account,
'bank_name' => $userbank->bank_name,
'bank_username' => $userbank->bank_username
]);
//大于1000积分等待管理员审核
if ($money_no >= 100000) {
@ -155,47 +158,19 @@ class WithdrawController
//用户积分减少$money
UserRewardDao::base($user_id, 1, - ($money_no + self::$handlingFee), '提现');
//获取刚刚存入数据库的id(订单号)
$orderId = $withdraw->id;
$res = PaymentNew::pushMoney($money, $userbank->bank_username, $userbank->account, $userbank->bank_name, $orderId);
// //逻辑错误需要修改
//逻辑错误需要修改
if ($res->Success) {
$withdraw->update([
'status' => 4, //
'status_text' => trans('等待银行打款'),
'order_number' => $res->TrackingNumber ?? null,
'order_number' => $res->TrackingNumber,
]);
return ApiResponseApp::success(null, '转账成功');
} 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([
'status' => 5, //
'status_text' => trans('支付错误:') . $res->ErrorMessage
@ -219,13 +194,14 @@ class WithdrawController
$callbackData = $request->all();
// 记录回调数据以便调试
Log::info('Payment Callback Received:', $callbackData);
$orderId = $callbackData['TrackingNumber'] ?? null;
$failedMessage = $callbackData['FailedMessage'] ?? null;
$amount = $callbackData['Amount'] ?? null;
$orderId = $callbackData['TrackingNumber'];
$failedMessage = $callbackData['FailedMessage'] ;
$amount = $callbackData['Amount'];
$withdraw = Withdraw::where('order_number', $orderId)->first();
//$failedMessage为null就是成功
if ($failedMessage != null) {
//解决多次回调
if ($withdraw->status == 5) {
return;
}
@ -241,5 +217,6 @@ class WithdrawController
'status_text' => trans('已到账'),
]);
}
return 'ok';
}
}

View File

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

View File

@ -5,13 +5,13 @@ namespace app\model;
use support\Model;
/**
* 用户WS信息表模型
* 用户WS信息归档表模型
*
* @property int $id 用户记录的唯一标识符
* @property string $phone 用户手机号WS手机号
* @property string $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $time 在线时间
* @property int $time 在线时间(单位:秒)
*/
class UserPhoneDayLog extends Model
{
@ -36,5 +36,11 @@ class UserPhoneDayLog extends Model
*/
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;
/**
* @property integer $id VIP级别的唯一标识符
* @property integer $user_id 用户id
* @property integer $amount 金额
* @property integer $status 1申请中 2 已到账 3已驳回 4等待银行打款 5支付失败
* @property integer $gift_amount 赠送积分
* @property integer $createtime 创建时间(时间戳)
* @property integer $accumulated 提现积分
* @property integer $fee 提现手续费
* @property string $account 提现银行账户
* @property string $bank_name 提现银行
* Withdraw - 用户提现记录模型
*
* @property int $id 用户提现记录唯一标识符
* @property int $user_id 用户 ID
* @property float $amount 转账金额
* @property string|null $status 状态码 1申请中 2 已到账 3已驳回 4等待银行打款 5支付失败
* @property string|null $createtime2 创建时间
* @property string|null $username 账号
* @property string|null $status_text 状态解释
* @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 int $accumulated 积分
* @property int $fee 手续费
*/
class Withdraw extends Model
{
@ -42,10 +48,11 @@ class Withdraw extends Model
'createtime2',
'username',
'status_text',
'accumulated',
'fee',
'order_number',
'account',
'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 = () => {
if ("" === X.value) return b(E("请输入金额"));
if (2 == C.value.id || 3 == C.value.id || 6 == C.value.id) {
if (X.value / 1 > j.userInfo.money - 300) return b(E("余额不足"));
if (X.value / 1 < 1e3) return b(E("最低提现金额") + 1e3);
} 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))
if (X.value / 1 < 4500) return b(E("最低提现金额") + 4500);
// if (X.value / 1 > j.userInfo.money - parseInt(j.config.brl_fee))
if (X.value / 1 > j.userInfo.money )
return b(E("余额不足"));
}
if (!Xe.value[C.value.id]) return b(C.value.errorMsg);
I({ forbidClick: !0, duration: 0 }),
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|null $baseUri 动态设置 baseUri可选
* @param string $contentType 数据格式json/form
* @param string|null $token 认证 token可选
* @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);
try {
$options = [];
// 设置请求头,支持动态传入 token
$headers = [
'Accept' => 'application/json',
];
if ($token) {
// 如果提供了 token则将其加入到 Authorization 头
$headers['Authorization'] = 'Bearer ' . $token;
}
// 添加请求头
$options['headers'] = $headers;
if (strtoupper($method) === 'GET') {
// GET 请求将数据作为查询参数
$options['query'] = $data;
@ -73,16 +87,14 @@ class HttpBase
$body = $response->getBody()->getContents();
return json_decode($body, true);
} catch (RequestException $e) {
// echo "HTTP 请求失败: " . $e->getMessage() . "\n";
// 捕获请求异常
if ($e->hasResponse()) {
$response = $e->getResponse();
$statusCode = $response->getStatusCode(); // 获取 HTTP 状态码
$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);
}
}