1210 lines
40 KiB
PHP
1210 lines
40 KiB
PHP
<?php
|
||
namespace app\common\service;
|
||
|
||
use app\common\model\finance\{UserFinance,RechargeRecord};
|
||
use app\common\model\user\{User,UserRelation,UserRelationAgent,UserRewardRecord,UserNotice};
|
||
use app\common\model\article\Article;
|
||
use app\common\model\member\{UserMember,UserMemberRecord};
|
||
use app\common\model\setting\Language;
|
||
use app\common\model\mall\{MallGoods,MallGoodsRecord};
|
||
use app\common\model\item\{ItemRecord};
|
||
use app\common\service\{ConfigService};
|
||
use think\facade\Db;
|
||
use Exception;
|
||
|
||
//二维码
|
||
use Endroid\QrCode\Color\Color;
|
||
use Endroid\QrCode\Encoding\Encoding;
|
||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelLow;
|
||
use Endroid\QrCode\QrCode;
|
||
use Endroid\QrCode\Label\Label;
|
||
use Endroid\QrCode\Logo\Logo;
|
||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
|
||
use Endroid\QrCode\Writer\PngWriter;
|
||
//优盾
|
||
use Udun\Dispatch\UdunDispatch;
|
||
//PHPMailer
|
||
use PHPMailer\PHPMailer\PHPMailer;
|
||
use PHPMailer\PHPMailer\SMTP;
|
||
//Google Authenticator
|
||
use PragmaRX\Google2FA\Google2FA;
|
||
|
||
|
||
class UtilsService
|
||
{
|
||
/**
|
||
* @notes 获取语言首选项
|
||
* @return string
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_first_lang()
|
||
{
|
||
$language = Language::order('sort desc')->findOrEmpty();
|
||
return $language;
|
||
}
|
||
|
||
/**
|
||
* @notes 创建用户关系
|
||
* @param int $user_id 用户id
|
||
* @param int $parent_id 上级id
|
||
* @param int $level 分销级别
|
||
* @return bool
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function create_user_relation($user_id,$parent_id,$level) : bool
|
||
{
|
||
Db::startTrans();
|
||
try {
|
||
//查询上级关系网
|
||
$topRelation = UserRelation::field(['id,user_id,parent_id,level'])
|
||
->where(['user_id' => $parent_id])
|
||
->order(['id' => 'asc'])
|
||
->select()->toArray();
|
||
|
||
UserRelation::create([
|
||
'user_id' => $user_id,
|
||
'parent_id' => $parent_id,
|
||
'level' => 1,
|
||
]);
|
||
|
||
//更新上级会员等级
|
||
UtilsService::set_user_member($parent_id);
|
||
|
||
//创建上级关系
|
||
foreach ($topRelation as $key => $top) {
|
||
//当达到分销级别时,跳出循环
|
||
if($key >= $level-1){
|
||
break;
|
||
}
|
||
|
||
UserRelation::create([
|
||
'user_id' => $user_id,
|
||
'parent_id' => $top['parent_id'],
|
||
'level' => $top['level'] + 1,
|
||
]);
|
||
}
|
||
//创建代理用户关系
|
||
UtilsService::create_agent_user_relation($user_id,$parent_id);
|
||
|
||
Db::commit();
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
throw new \Exception($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @notes 创建代理用户关系
|
||
* @param int $user_id 用户id
|
||
* @param int $parent_id 上级id
|
||
* @param int $level 分销级别
|
||
* @return bool
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function create_agent_user_relation($user_id,$parent_id) : bool
|
||
{
|
||
Db::startTrans();
|
||
try {
|
||
//查询上级关系网
|
||
$topRelation = UserRelationAgent::field(['id,user_id,parent_id,top_id,level'])
|
||
->where(['user_id' => $parent_id])
|
||
->order(['id' => 'asc'])
|
||
->select()->toArray();
|
||
|
||
//查询直接上级ID的顶级ID
|
||
$top_id = $parent_id;
|
||
$topUser = UserRelationAgent::field(['id,user_id,parent_id,top_id,level'])
|
||
->where(['user_id' => $parent_id])
|
||
->order(['level' => 'desc'])
|
||
->findOrEmpty();
|
||
|
||
if(!$topUser->isEmpty()) {
|
||
$top_id = $topUser['parent_id'];
|
||
}
|
||
|
||
UserRelationAgent::create([
|
||
'user_id' => $user_id,
|
||
'parent_id' => $parent_id,
|
||
'top_id' => $top_id,
|
||
'level' => 1,
|
||
]);
|
||
|
||
//创建上级关系
|
||
foreach ($topRelation as $key => $top) {
|
||
UserRelationAgent::create([
|
||
'user_id' => $user_id,
|
||
'parent_id' => $top['parent_id'],
|
||
'top_id' => $top['top_id'],
|
||
'level' => $top['level'] + 1,
|
||
]);
|
||
}
|
||
Db::commit();
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
throw new \Exception($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @notes 创建系统消息记录
|
||
* @param int $user_id 用户id
|
||
* @return bool
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function create_user_notice($user_id) : bool
|
||
{
|
||
Db::startTrans();
|
||
try {
|
||
$notices = Article::where(['is_show' => 1,'is_sys_notice' => 1,'cid' => 5])
|
||
->order(['sort' => 'desc', 'id' => 'desc'])
|
||
->select()
|
||
->toArray();
|
||
|
||
foreach ($notices as &$notice) {
|
||
UserNotice::create([
|
||
'user_id' => $user_id,
|
||
'article_id' => $notice['id'],
|
||
'title' => $notice['title'],
|
||
'content' => $notice['content'] ?? '',
|
||
'langs' => $notice['langs'],
|
||
]);
|
||
}
|
||
|
||
Db::commit();
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
throw new \Exception($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @notes 资金明细记录
|
||
* @param $userId
|
||
* @param $changeType
|
||
* @param $action
|
||
* @param $changeAmount
|
||
* @param string $sourceSn
|
||
* @param string $remark
|
||
* @param array $extra
|
||
* @return UserFinance|false|\think\Model
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function user_finance_add($userId, $changeType, $action, $changeAmount, string $sourceSn = '', string $remark = '',int $frozen = 0, string $changeObject = '', array $extra = [])
|
||
{
|
||
Db::startTrans();
|
||
try {
|
||
$user = User::findOrEmpty($userId);
|
||
if($user->isEmpty()) {
|
||
return false;
|
||
}
|
||
$thaw_time = 0;//解冻时间
|
||
if($frozen == 1){
|
||
$config = ConfigService::get('website', 'trade');
|
||
if($config['release_time'] <= 0){
|
||
$frozen = 0;
|
||
}else{
|
||
$thaw_time = UtilsService::get_finance_traw_time($changeType);
|
||
}
|
||
}
|
||
|
||
|
||
$data = [
|
||
'sn' => generate_sn(UserFinance::class, 'sn', 20),
|
||
'user_id' => $userId,
|
||
'change_object' => $changeObject,
|
||
'change_type' => $changeType,
|
||
'action' => $action,
|
||
'left_amount' => $user->user_money,
|
||
'change_amount' => $changeAmount,
|
||
'source_sn' => $sourceSn,
|
||
'remark' => $remark,
|
||
'frozen' => $frozen,
|
||
'thaw_time' => $thaw_time,
|
||
'extra' => $extra ? json_encode($extra, JSON_UNESCAPED_UNICODE) : '',
|
||
];
|
||
UserFinance::create($data);
|
||
Db::commit();
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
throw new \Exception($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @notes 获取资金解冻时间
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_finance_traw_time($changeType)
|
||
{
|
||
$config = ConfigService::get('website', 'trade');
|
||
|
||
$release_time = $config['release_time'];
|
||
|
||
$is_open_release = $config['is_open_release'];//是否独立冻结
|
||
$release_list = $config['release_list'];//冻结类型明细
|
||
$return_time = time() + ($release_time * 60 * 60);
|
||
|
||
if($is_open_release == 1){
|
||
foreach ($release_list as $item) {
|
||
if($changeType - $item['type'] == 0){
|
||
$return_time = time() + ($item['time'] * 60 * 60);
|
||
}
|
||
}
|
||
}
|
||
|
||
return $return_time;
|
||
}
|
||
|
||
/**
|
||
* @notes 用户资金变更
|
||
* @param $userId
|
||
* @param $action 1增加 2减少
|
||
* @param $change 变更数值
|
||
* @param $field 变更字段
|
||
* @return User|false|\think\Model
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function user_money_change($userId, $action, $change, $field)
|
||
{
|
||
Db::startTrans();
|
||
try {
|
||
|
||
$user = User::findOrEmpty($userId);
|
||
if($user->isEmpty()) {
|
||
return false;
|
||
}
|
||
$new = $user[$field];
|
||
if($action ==1 ){
|
||
$new += $change;
|
||
}else{
|
||
$new -= $change;
|
||
}
|
||
User::update([
|
||
'id' => $userId,
|
||
$field => $new
|
||
]);
|
||
|
||
Db::commit();
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
throw new \Exception($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @notes 获取用户可用金额 (用户余额 - 待释放金额 + 投资支出)
|
||
* @param $userId
|
||
* @return num
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_used_money($userId)
|
||
{
|
||
$user = User::findOrEmpty($userId);
|
||
|
||
$frozen_money = UserFinance::where(['user_id' => $userId,'frozen' => 1])->sum('change_amount');
|
||
if($frozen_money > 0){
|
||
//查询最早冻结记录后的支出金额
|
||
$frozen_first = UserFinance::where(['user_id' => $userId,'frozen' => 1])->order('create_time asc') -> findOrEmpty();
|
||
$first_time = strtotime($frozen_first['create_time']);
|
||
|
||
$out_money = UserFinance::where(['user_id' => $userId,'action' => 2])->where(" create_time > $first_time AND change_type IN (16) ")->sum('change_amount');
|
||
$frozen_money = $frozen_money - $out_money;
|
||
}
|
||
|
||
if($frozen_money < 0) $frozen_money = 0;
|
||
|
||
|
||
return $user['user_money'] - $frozen_money;
|
||
}
|
||
|
||
/**
|
||
* @notes 任务奖励
|
||
* @param $userId
|
||
* @return bool
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function mission_reward_add($userId)
|
||
{
|
||
|
||
Db::startTrans();
|
||
try {
|
||
$reward = ConfigService::get('website', 'reward');
|
||
$list = $reward['tasks'];
|
||
|
||
foreach ($list as $key => $item) {
|
||
if($list[$key]['is_show'] == 0){
|
||
unset($list[$key]);
|
||
}
|
||
}
|
||
|
||
foreach ($list as $item) {
|
||
$insert_record = 0;
|
||
$next_user_id = 0;
|
||
|
||
//type 1升级VIP 2邀请下级首充 3累积邀请
|
||
switch ($item['type']) {
|
||
case 1:
|
||
|
||
$member = UserMember::where(['id' => $item['member_id']])->findOrEmpty();
|
||
|
||
//查询会员等级
|
||
$member_id = UtilsService::get_user_member_id($userId);
|
||
$userMember = UserMember::where(['id' => $member_id])->findOrEmpty();
|
||
|
||
$rewardRecord = UserRewardRecord::where(['user_id' => $userId,'top_id' => $item['id'],'type' => 2])->findOrEmpty();
|
||
|
||
//判断是否满足条件
|
||
if($userMember['money'] >= $member['money'] && $rewardRecord->isEmpty()){
|
||
$insert_record = 1;
|
||
}
|
||
break;
|
||
case 2:
|
||
//查询所有直接下级关系网
|
||
$relations = UserRelation::field(['id,user_id,parent_id'])
|
||
->where(['parent_id' => $userId,'level' => 1])
|
||
->order(['id' => 'asc'])
|
||
->select()
|
||
->toArray();
|
||
|
||
//查询首充金额
|
||
foreach ($relations as $relation) {
|
||
|
||
$next_user_id = $relation['user_id'];
|
||
|
||
$rechargeRecord = RechargeRecord::where(['user_id' => $relation['user_id'],'status' => 1])->order(['id' => 'asc'])->findOrEmpty();
|
||
|
||
|
||
//判断首充金额是否满足
|
||
if(!$rechargeRecord->isEmpty() && $rechargeRecord['amount'] >= $item['recharge_money']){
|
||
|
||
//查询记录
|
||
$rewardRecord = UserRewardRecord::where(['user_id' => $userId,'next_user_id' => $relation['user_id'],'top_id' => $item['id'],'type' => 2])->findOrEmpty();
|
||
if($rewardRecord->isEmpty()){
|
||
|
||
//添加奖励记录
|
||
UserRewardRecord::create([
|
||
'user_id' => $userId,
|
||
'next_user_id' => $next_user_id,
|
||
'top_id' => $item['id'],
|
||
'reward' => $item['money'],
|
||
'type' => 2,
|
||
'status' => 0,
|
||
]);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
break;
|
||
case 3:
|
||
$recharge_money = $item['recharge_money'];
|
||
$invite_num = UserRelation::alias('ur')
|
||
->join('user u', 'u.id = ur.user_id')
|
||
->where(['ur.parent_id' => $userId,'ur.level' => 1])
|
||
->where("u.total_recharge >= $recharge_money")
|
||
->count();
|
||
//is_repeat 1可重复领取0不可重复
|
||
if($item['is_repeat'] == 0){
|
||
$rewardRecord = UserRewardRecord::where(['user_id' => $userId,'top_id' => $item['id'],'type' => 2])->findOrEmpty();
|
||
//判断是否满足条件
|
||
if($invite_num >= $item['invite_num'] && $rewardRecord->isEmpty()){
|
||
$insert_record = 1;
|
||
}
|
||
}else{
|
||
$count = UserRewardRecord::where(['user_id' => $userId,'top_id' => $item['id'],'type' => 2])->count();
|
||
$used_invite_num = $count * $item['invite_num'];
|
||
|
||
//判断是否满足条件
|
||
if($invite_num - $used_invite_num >= $item['invite_num']){
|
||
//添加奖励记录
|
||
UserRewardRecord::create([
|
||
'user_id' => $userId,
|
||
'top_id' => $item['id'],
|
||
'reward' => $item['money'],
|
||
'type' => 2,
|
||
'status' => 0,
|
||
]);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
|
||
if($insert_record == 1){
|
||
//添加奖励记录
|
||
UserRewardRecord::create([
|
||
'user_id' => $userId,
|
||
'next_user_id' => $next_user_id,
|
||
'top_id' => $item['id'],
|
||
'reward' => $item['money'],
|
||
'type' => 2,
|
||
'status' => 0,
|
||
]);
|
||
}
|
||
}
|
||
|
||
Db::commit();
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
throw new \Exception($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @notes 充值活动奖励
|
||
* @param $userId
|
||
* @param $money 充值金额
|
||
* @return bool
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function activity_reward_add($userId, $money)
|
||
{
|
||
|
||
Db::startTrans();
|
||
try {
|
||
|
||
$user = User::findOrEmpty($userId);
|
||
if($user->isEmpty()) {
|
||
return false;
|
||
}
|
||
|
||
$reward = ConfigService::get('website', 'reward');
|
||
$activities = array_reverse($reward['activity']);
|
||
|
||
foreach ($activities as $key => $activity) {
|
||
if($activities[$key]['is_show'] == 0){
|
||
unset($activities[$key]);
|
||
}
|
||
}
|
||
|
||
foreach ($activities as $activity) {
|
||
if($money >= $activity['recharge_money'] && $activity['money'] >= 0.01){
|
||
//记录日志
|
||
UtilsService::user_finance_add(
|
||
$userId,
|
||
14,
|
||
1,
|
||
$activity['money'],
|
||
'',
|
||
'',
|
||
1//冻结
|
||
);
|
||
|
||
//用户资金修改
|
||
UtilsService::user_money_change($userId, 1, $activity['money'],'user_money');
|
||
|
||
//添加奖励活动记录
|
||
UserRewardRecord::create([
|
||
'user_id' => $userId,
|
||
'top_id' => $activity['id'],
|
||
'money' => $money,
|
||
'reward' => $activity['money'],
|
||
'type' => 1,
|
||
]);
|
||
|
||
break;
|
||
}else{
|
||
continue;
|
||
}
|
||
}
|
||
|
||
Db::commit();
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
throw new \Exception($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 团队奖励(充值,收益)
|
||
* @param $userId
|
||
* @param $money
|
||
* @param $rewardObject 1充值奖励2收益奖励
|
||
* @return bool
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function team_reward_add($userId, $money, $rewardObject = 1)
|
||
{
|
||
|
||
Db::startTrans();
|
||
try {
|
||
|
||
$user = User::findOrEmpty($userId);
|
||
if($user->isEmpty()) {
|
||
return false;
|
||
}
|
||
|
||
$distributes = ConfigService::get('website', 'distribute');
|
||
//查询上级关系网
|
||
$relations = UserRelation::field(['id,user_id,parent_id,level'])
|
||
->where(['user_id' => $userId])
|
||
->order(['id' => 'asc'])
|
||
->select()
|
||
->toArray();
|
||
|
||
foreach ($relations as $relation) {
|
||
foreach ($distributes as $distribute) {
|
||
if($relation['level'] == $distribute['level']){
|
||
//判断奖励方式 1充值奖励2收益奖励
|
||
$rewardObjectVal = "recharge_rate";
|
||
$changeType = 12;
|
||
|
||
if($rewardObject == 2){
|
||
$rewardObjectVal = "item_rate";
|
||
$changeType = 11;
|
||
}
|
||
//奖励金额
|
||
$rewardMoney = round($money * $distribute[$rewardObjectVal] / 100 , 2);
|
||
|
||
if($rewardMoney >= 0.01){
|
||
//记录日志
|
||
UtilsService::user_finance_add(
|
||
$relation['parent_id'],
|
||
$changeType,
|
||
1,
|
||
$rewardMoney,
|
||
'',
|
||
'',
|
||
1//冻结
|
||
);
|
||
|
||
//用户资金修改
|
||
UtilsService::user_money_change($relation['parent_id'], 1, $rewardMoney,'user_money');
|
||
UtilsService::user_money_change($relation['parent_id'], 1, $rewardMoney,'total_income_team');
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
Db::commit();
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
throw new \Exception($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @notes 获取多语言数据
|
||
* @param $langs 多语言数据
|
||
* @param $lang 语言
|
||
* @return array
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_langs_data($langsStr,$lang)
|
||
{
|
||
//多语言替换
|
||
$langs = json_decode($langsStr, true);
|
||
// 使用array_filter筛选数组
|
||
$data = array_filter($langs, function ($item) use ($lang) {
|
||
return $item['lang'] === $lang;
|
||
});
|
||
$keys = array_keys($data);
|
||
if(count($keys) <= 0){
|
||
return [];
|
||
}
|
||
return $data[$keys[0]];
|
||
}
|
||
|
||
/**
|
||
* @notes 获取用户会员等级id
|
||
* @param $user_id 用户id
|
||
* @return string
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_user_member_id($user_id)
|
||
{
|
||
//查询会员等级记录
|
||
$userMemberRecord = UserMemberRecord::where(['user_id' => $user_id])
|
||
->order('id', 'desc')
|
||
->findOrEmpty();
|
||
//如果不存在开通记录,则默认为id为1
|
||
$member_id = 1;
|
||
if(!$userMemberRecord->isEmpty()) {
|
||
$member_id = $userMemberRecord['member_id'];
|
||
}
|
||
return $member_id;
|
||
}
|
||
|
||
/**
|
||
* @notes 设置用户会员等级
|
||
* @param $userId 用户id
|
||
* @return string
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function set_user_member($userId)
|
||
{
|
||
$user = User::findOrEmpty($userId);
|
||
|
||
//会员等级更新,根据用户累积质押金额,(自动升级条件)
|
||
if($user['auto_member'] == 1){
|
||
$member_id = 1;
|
||
|
||
//会员升级条件: 累积质押金额、1代推荐人数 start------------------------------------------------
|
||
$total_invest = ItemRecord::where(['user_id' => $userId])->sum('money');
|
||
|
||
$userMembers = UserMember::where(" money <= $total_invest ")
|
||
->where(['is_show' => 1])
|
||
->order('money', 'desc')
|
||
->select()
|
||
->toArray();
|
||
foreach ($userMembers as &$userMember) {
|
||
$invite_count = UserRelation::where(['parent_id' => $userId,'level' => 1])->count();
|
||
|
||
if($invite_count - $userMember['level1_num'] >= 0){
|
||
$member_id = $userMember['id'];
|
||
break;
|
||
}
|
||
}
|
||
//会员升级条件: 累积质押金额、1代推荐人数 end------------------------------------------------
|
||
|
||
|
||
$data = [
|
||
'user_id' => $userId,
|
||
'member_id' => $member_id,
|
||
];
|
||
|
||
//查询会员等级记录
|
||
$userMemberRecord = UserMemberRecord::where(['user_id' => $userId])
|
||
->order('id', 'desc')
|
||
->findOrEmpty();
|
||
//如果不存在则创建,存在则更新
|
||
if(!$userMemberRecord->isEmpty()) {
|
||
UserMemberRecord::where('id', $userMemberRecord['id'])->update($data);
|
||
}else{
|
||
UserMemberRecord::create($data);
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* @notes 获取分销级别
|
||
* @return num
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_distribute_level()
|
||
{
|
||
$distribute = ConfigService::get('website', 'distribute');
|
||
|
||
return count($distribute);
|
||
}
|
||
|
||
/**
|
||
* @notes 抽奖
|
||
* @return $prizeIndex
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_draw_rand($prizeList,$lists,$user_id,$point)
|
||
{
|
||
$prizeIndex = '';
|
||
//概率数组的总概率精度
|
||
$proSum = array_sum($lists);
|
||
//概率数组循环
|
||
foreach ($lists as $key => $proCur) {
|
||
$goods_temp = $prizeList[$key];
|
||
if($goods_temp['num'] <=0 ){
|
||
$proSum -= $proCur;
|
||
continue;
|
||
}
|
||
|
||
$randNum = mt_rand(1, $proSum);
|
||
if ($randNum <= $proCur) {
|
||
$prizeIndex = $key;
|
||
break;
|
||
} else {
|
||
$proSum -= $proCur;
|
||
}
|
||
}
|
||
unset ($lists);
|
||
|
||
$goods = $prizeList[$prizeIndex];
|
||
|
||
$data = [
|
||
'sn' => generate_sn(MallGoodsRecord::class, 'sn'),
|
||
'user_id' => $user_id,
|
||
'm_goods_id' => $goods['id'],
|
||
'm_goods_title' => $goods['title'],
|
||
'm_goods_image' => FileService::setFileUrl($goods['image']),
|
||
'm_goods_langs' => $goods['langs'],
|
||
'price' => $point,
|
||
'money' => $goods['money'],
|
||
'point' => $goods['point'],
|
||
'type' => $goods['type'],
|
||
'type2' => $goods['type2'],
|
||
'status' => 1,//状态0进行中1已完成
|
||
];
|
||
$order = MallGoodsRecord::create($data);
|
||
|
||
//剩余数量-1
|
||
$mallGoods = MallGoods::find($goods['id']);
|
||
if (!$mallGoods->isEmpty()) {
|
||
MallGoods::update([
|
||
'id' => $mallGoods['id'],
|
||
'num' => $mallGoods['num'] - 1
|
||
]);
|
||
}
|
||
|
||
|
||
//扣除积分
|
||
if($point > 0){
|
||
//用户积分修改
|
||
UtilsService::user_money_change($user_id, 2, $point,'user_point');
|
||
}
|
||
|
||
//类型1现金2积分
|
||
switch ($goods['type2']) {
|
||
case 1:
|
||
if($goods['money'] > 0.01){
|
||
//记录日志
|
||
UtilsService::user_finance_add(
|
||
$user_id,
|
||
22,
|
||
1,
|
||
$goods['money'],
|
||
$order['sn'],
|
||
'',
|
||
1//冻结
|
||
);
|
||
|
||
//用户资金修改
|
||
UtilsService::user_money_change($user_id, 1, $goods['money'],'user_money');
|
||
|
||
}
|
||
break;
|
||
case 2:
|
||
//赠送积分
|
||
if($goods['point'] > 0){
|
||
UtilsService::user_money_change($user_id, 1, $goods['point'],'user_point');
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
return $prizeIndex;
|
||
}
|
||
|
||
/**
|
||
* @notes Google Authenticator密钥
|
||
* @return $secretKey
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_google_secretKey()
|
||
{
|
||
$google2fa = new Google2FA();
|
||
|
||
return $google2fa->generateSecretKey();
|
||
}
|
||
|
||
/**
|
||
* @notes Google Authenticator二维码
|
||
* @return $secretKey
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_google_qrcode($email,$name,$secretKey)
|
||
{
|
||
$google2fa = new Google2FA();
|
||
$qrCodeUrl = $google2fa->getQRCodeUrl(
|
||
$name,
|
||
$email,
|
||
$secretKey
|
||
);
|
||
return UtilsService::get_qrcode($qrCodeUrl);
|
||
}
|
||
|
||
/**
|
||
* @notes Google Authenticator校验
|
||
* @return $secretKey
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_google_verify($secretKey,$code)
|
||
{
|
||
$google2fa = new Google2FA();
|
||
$valid = $google2fa->verifyKey($secretKey, $code);
|
||
$result = false;
|
||
if($valid == 1) $result = true;
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* @notes 生成二维码
|
||
* @param $url
|
||
* @return $dataUri
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_qrcode(string $url = '')
|
||
{
|
||
$writer = new PngWriter();
|
||
$qrCode = QrCode::create($url)//跳转的url地址
|
||
->setEncoding(new Encoding('UTF-8')) //设置编码格式
|
||
->setErrorCorrectionLevel(new ErrorCorrectionLevelLow()) //设置纠错级别为低
|
||
->setSize(300) //大小
|
||
->setMargin(20) //边距
|
||
->setRoundBlockSizeMode(new RoundBlockSizeModeMargin()) //设置圆轮大小边距
|
||
->setForegroundColor(new Color(0, 0, 0)) //前景色
|
||
->setBackgroundColor(new Color(255, 255, 255)); //背景色
|
||
$result = $writer->write($qrCode);
|
||
header('Content-Type: '.$result->getMimeType());
|
||
$result->getString();
|
||
$dataUri = $result->getDataUri(); //DATA-URI 是指可以在Web 页面中包含图片但无需任何额外的HTTP 请求的一类URI.
|
||
return $dataUri;
|
||
}
|
||
|
||
/**
|
||
* @notes 发送邮件
|
||
* @param $url
|
||
* @return $dataUri
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function send_mail($to,$subject,$content)
|
||
{
|
||
$email = ConfigService::get('website', 'email');
|
||
|
||
$mail = new PHPMailer(true);
|
||
|
||
//Server settings
|
||
$mail->SMTPDebug = SMTP::DEBUG_OFF; //Enable verbose debug output DEBUG_OFF = 0 DEBUG_CLIENT = 1 DEBUG_SERVER = 2
|
||
$mail->isSMTP(); //Send using SMTP
|
||
$mail->Host = $email['host']; //Set the SMTP server to send through
|
||
$mail->SMTPAuth = true; //Enable SMTP authentication
|
||
$mail->Username = $email['username']; //SMTP username
|
||
$mail->Password = $email['password']; //SMTP password
|
||
$mail->SMTPSecure = $email['smtp']; //Enable implicit TLS encryption
|
||
$mail->Port = $email['port']; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
|
||
// $mail->Timeout = 3600;
|
||
$mail->CharSet = $email['charset'];
|
||
|
||
//Recipients
|
||
$mail->setFrom($email['username'],$email['nickname']);
|
||
$mail->addAddress($to); //Add a recipient
|
||
|
||
|
||
//Content
|
||
$mail->isHTML(true); //Set email format to HTML
|
||
$mail->Subject = $subject;
|
||
$mail->Body = $content;
|
||
$mail->AltBody = $content;
|
||
// 发送邮件
|
||
if ($mail->send()) {
|
||
return true;
|
||
}else{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @notes 获取优盾
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function get_udunDispatch()
|
||
{
|
||
$udun = ConfigService::get('website', 'udun');
|
||
return $udunDispatch = new UdunDispatch([
|
||
'merchant_no' => $udun['merchant_no'], //商户号
|
||
'api_key' => $udun['api_key'],//apikey
|
||
'gateway_address'=>$udun['gateway_address'], //节点
|
||
'callUrl'=>$udun['callUrl'],//回调地址
|
||
'debug' => $udun['debug'], //调试模式
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* @notes 优盾签名
|
||
* @author BD
|
||
* @date 2024/03/07 13:10
|
||
*/
|
||
public static function udun_signature($body,$timestamp,$nonce)
|
||
{
|
||
$udun = ConfigService::get('website', 'udun');
|
||
return strtolower(md5($body.$udun['api_key'].$nonce.$timestamp));
|
||
}
|
||
|
||
//有道翻译 start------------------------------------------------------------------------------------
|
||
|
||
public static function do_translate($q,$from,$to)
|
||
{
|
||
$translation = ConfigService::get('website', 'translation');
|
||
|
||
$APP_KEY = $translation['app_key'];
|
||
$SEC_KEY = $translation['sec_key'];
|
||
$URL = $translation['url'];
|
||
|
||
$salt = UtilsService::create_guid();
|
||
$args = array(
|
||
'q' => $q,
|
||
'appKey' => $APP_KEY,
|
||
'salt' => $salt,
|
||
);
|
||
$args['from'] = $from;
|
||
$args['to'] = $to;
|
||
$args['signType'] = 'v3';
|
||
$curtime = strtotime("now");
|
||
$args['curtime'] = $curtime;
|
||
$signStr = $APP_KEY . UtilsService::truncate(implode("", $q)) . $salt . $curtime . $SEC_KEY;
|
||
$args['sign'] = hash("sha256", $signStr);
|
||
$args['vocabId'] = '0';
|
||
$ret = UtilsService::call($URL, $args);
|
||
return $ret;
|
||
}
|
||
|
||
// 发起网络请求
|
||
public static function call($url, $args=null, $method="post", $testflag = 0, $timeout = 2000, $headers=array())
|
||
{
|
||
$ret = false;
|
||
$i = 0;
|
||
while($ret === false)
|
||
{
|
||
if($i > 1)
|
||
break;
|
||
if($i > 0)
|
||
{
|
||
sleep(1);
|
||
}
|
||
$ret = UtilsService::callOnce($url, $args, $method, false, $timeout, $headers);
|
||
$i++;
|
||
}
|
||
return $ret;
|
||
}
|
||
|
||
public static function callOnce($url, $args=null, $method="post", $withCookie = false, $timeout = 2000, $headers=array())
|
||
{
|
||
$ch = curl_init();
|
||
if($method == "post")
|
||
{
|
||
$data = UtilsService::convert($args);
|
||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||
curl_setopt($ch, CURLOPT_POST, 1);
|
||
}
|
||
else
|
||
{
|
||
$data = UtilsService::convert($args);
|
||
if($data)
|
||
{
|
||
if(stripos($url, "?") > 0)
|
||
{
|
||
$url .= "&$data";
|
||
}
|
||
else
|
||
{
|
||
$url .= "?$data";
|
||
}
|
||
}
|
||
}
|
||
curl_setopt($ch, CURLOPT_URL, $url);
|
||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||
if(!empty($headers))
|
||
{
|
||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||
}
|
||
if($withCookie)
|
||
{
|
||
curl_setopt($ch, CURLOPT_COOKIEJAR, $_COOKIE);
|
||
}
|
||
$r = curl_exec($ch);
|
||
curl_close($ch);
|
||
return $r;
|
||
}
|
||
|
||
public static function convert(&$args)
|
||
{
|
||
$data = '';
|
||
if (is_array($args))
|
||
{
|
||
foreach ($args as $key=>$val)
|
||
{
|
||
if (is_array($val))
|
||
{
|
||
foreach ($val as $k=>$v)
|
||
{
|
||
$data .= 'q='.rawurlencode($v).'&';
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$data .="$key=".rawurlencode($val)."&";
|
||
}
|
||
}
|
||
return trim($data, "&");
|
||
}
|
||
return $args;
|
||
}
|
||
|
||
// uuid generator
|
||
public static function create_guid(){
|
||
$microTime = microtime();
|
||
list($a_dec, $a_sec) = explode(" ", $microTime);
|
||
$dec_hex = dechex($a_dec* 1000000);
|
||
$sec_hex = dechex($a_sec);
|
||
UtilsService::ensure_length($dec_hex, 5);
|
||
UtilsService::ensure_length($sec_hex, 6);
|
||
$guid = "";
|
||
$guid .= $dec_hex;
|
||
$guid .= UtilsService::create_guid_section(3);
|
||
$guid .= '-';
|
||
$guid .= UtilsService::create_guid_section(4);
|
||
$guid .= '-';
|
||
$guid .= UtilsService::create_guid_section(4);
|
||
$guid .= '-';
|
||
$guid .= UtilsService::create_guid_section(4);
|
||
$guid .= '-';
|
||
$guid .= $sec_hex;
|
||
$guid .= UtilsService::create_guid_section(6);
|
||
return $guid;
|
||
}
|
||
|
||
public static function create_guid_section($characters){
|
||
$return = "";
|
||
for($i = 0; $i < $characters; $i++)
|
||
{
|
||
$return .= dechex(mt_rand(0,15));
|
||
}
|
||
return $return;
|
||
}
|
||
|
||
public static function truncate($q) {
|
||
$len = UtilsService::abslength($q);
|
||
return $len <= 20 ? $q : (mb_substr($q, 0, 10) . $len . mb_substr($q, $len - 10, $len));
|
||
}
|
||
|
||
public static function abslength($str)
|
||
{
|
||
if(empty($str)){
|
||
return 0;
|
||
}
|
||
if(function_exists('mb_strlen')){
|
||
return mb_strlen($str,'utf-8');
|
||
}
|
||
else {
|
||
preg_match_all("/./u", $str, $ar);
|
||
return count($ar[0]);
|
||
}
|
||
}
|
||
|
||
public static function ensure_length(&$string, $length){
|
||
$strlen = strlen($string);
|
||
if($strlen < $length)
|
||
{
|
||
$string = str_pad($string, $length, "0");
|
||
}
|
||
else if($strlen > $length)
|
||
{
|
||
$string = substr($string, 0, $length);
|
||
}
|
||
}
|
||
|
||
//有道翻译 end------------------------------------------------------------------------------------
|
||
|
||
|
||
//波场USDT HTTP请求
|
||
public static function usdt_request($data = [], $method = 'GET')
|
||
{
|
||
$tron = ConfigService::get('website', 'tron');
|
||
|
||
$data['api_key'] = $tron['api_key'];
|
||
|
||
return UtilsService::curl_request($tron['url'], $data, $method);
|
||
}
|
||
|
||
|
||
//根据IP获取国家
|
||
public static function get_country_by_ip($ip,$method = 1)
|
||
{
|
||
try {
|
||
$country = '';
|
||
|
||
switch ($method) {
|
||
case 1:
|
||
$data['ip'] = $ip;
|
||
$url = 'https://searchplugin.csdn.net/api/v1/ip/get';
|
||
|
||
$response = UtilsService::curl_request($url, $data);
|
||
$response = json_decode($response, true);
|
||
if($response['code'] == 200){
|
||
$country = $response['data']['address'];
|
||
}
|
||
|
||
break;
|
||
case 2:
|
||
$data['lang'] ='zh-CN';
|
||
$url = 'http://ip-api.com/json/'.$ip;
|
||
$response = UtilsService::curl_request($url, $data);
|
||
$response = json_decode($response, true);
|
||
if($response['status'] == 'success'){
|
||
$country = $response['country'].$response['city'];
|
||
}
|
||
|
||
break;
|
||
}
|
||
return $country;
|
||
} catch (\Exception $e) {
|
||
return '';
|
||
}
|
||
}
|
||
|
||
|
||
// 发送HTTP请求
|
||
public static function curl_request($url, $data = [], $method = 'GET')
|
||
{
|
||
$ch = curl_init();
|
||
|
||
if ($method == 'GET' && count($data)) {
|
||
$url .= '?' . http_build_query($data);
|
||
}
|
||
|
||
curl_setopt($ch, CURLOPT_URL, $url);
|
||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||
|
||
if ($method == 'POST') {
|
||
curl_setopt($ch, CURLOPT_POST, true);
|
||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||
}
|
||
|
||
$result = curl_exec($ch);
|
||
curl_close($ch);
|
||
|
||
return $result;
|
||
}
|
||
} |