376 lines
15 KiB
PHP
376 lines
15 KiB
PHP
<?php
|
||
|
||
|
||
|
||
namespace app\common\repositories\user;
|
||
|
||
|
||
use app\common\dao\user\UserBrokerageDao;
|
||
use app\common\model\store\order\StoreOrder;
|
||
use app\common\model\store\order\StoreOrderProduct;
|
||
use app\common\model\store\product\Spu;
|
||
use app\common\model\user\User;
|
||
use app\common\model\user\UserBrokerage;
|
||
use app\common\repositories\BaseRepository;
|
||
use app\common\repositories\system\CacheRepository;
|
||
use FormBuilder\Factory\Elm;
|
||
use think\exception\ValidateException;
|
||
use think\facade\Db;
|
||
use think\facade\Log;
|
||
use think\facade\Route;
|
||
|
||
/**
|
||
* @mixin UserBrokerageDao
|
||
*/
|
||
class UserBrokerageRepository extends BaseRepository
|
||
{
|
||
|
||
// 基本升级条件 所有内容走基本升级条件流程统一处理,未添加到该数组中的升级条件为特殊升级条件,全部单独处理
|
||
public const BROKERAGE_RULE_TYPE = ['spread_user', 'pay_money', 'pay_num', 'spread_money', 'spread_pay_num'];
|
||
|
||
public function __construct(UserBrokerageDao $dao)
|
||
{
|
||
$this->dao = $dao;
|
||
}
|
||
|
||
public function getList(array $where, $page, $limit)
|
||
{
|
||
$query = $this->dao->search($where)->order('brokerage_level ASC,create_time DESC');
|
||
$count = $query->count();
|
||
$list = $query->page($page, $limit)->select();
|
||
return compact('list', 'count');
|
||
}
|
||
|
||
public function getNextLevel($level,$type = 0)
|
||
{
|
||
return $this->search(['next_level' => $level,'type' => $type])->order('brokerage_level ASC,create_time DESC')->find();
|
||
}
|
||
|
||
public function options(array $where)
|
||
{
|
||
return $this->dao->search($where)->field('brokerage_level as value,brokerage_name as label')->order('brokerage_level ASC,create_time DESC')->select();
|
||
}
|
||
|
||
public function all(int $type)
|
||
{
|
||
return $this->dao->search(['type' => $type])->order('brokerage_level ASC,create_time DESC')->select();
|
||
}
|
||
|
||
|
||
public function inc(User $user, $type, $inc)
|
||
{
|
||
$nextLevel = $this->getNextLevel($user->brokerage_level);
|
||
if (!$nextLevel) return false;
|
||
$make = app()->make(UserBillRepository::class);
|
||
$bill = $make->getWhere(['uid' => $user->uid, 'link_id' => $nextLevel->user_brokerage_id, 'category' => 'sys_brokerage', 'type' => $type]);
|
||
if ($bill) {
|
||
$bill->number = bcadd($bill->number, $inc, 2);
|
||
$bill->save();
|
||
} else {
|
||
$make->incBill($user->uid, 'sys_brokerage', $type, [
|
||
'number' => $inc,
|
||
'title' => $type,
|
||
'balance' => 0,
|
||
'status' => 0,
|
||
'link_id' => $nextLevel->user_brokerage_id
|
||
]);
|
||
}
|
||
|
||
return $this->checkLevel($user, $nextLevel);
|
||
}
|
||
public function checkLevel(User $user, UserBrokerage $nextLevel)
|
||
{
|
||
$info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id])
|
||
->column('number', 'type');
|
||
foreach ($nextLevel['brokerage_rule'] as $k => $rule) {
|
||
if (!isset($info[$k]) && $rule['num'] > 0) return false;
|
||
if ($rule['num'] > 0 && $rule['num'] > $info[$k]) return false;
|
||
}
|
||
$nextLevel->user_num++;
|
||
Db::transaction(function () use ($nextLevel, $user) {
|
||
$nextLevel->save();
|
||
if ($user->brokerage && $user->brokerage->user_num > 0) {
|
||
$user->brokerage->user_num--;
|
||
$user->brokerage->save();
|
||
}
|
||
$user->brokerage_level = $nextLevel->brokerage_level;
|
||
$user->save();
|
||
|
||
$key = 'notice_brokerage_level_' . $user->uid;
|
||
app()->make(CacheRepository::class)->save($key,$nextLevel->brokerage_level);
|
||
});
|
||
return true;
|
||
}
|
||
/**
|
||
* Common: 分销商升级 - 流程开始
|
||
* Author: wu-hui
|
||
* Time: 2023/12/26 14:20
|
||
* @param User $user
|
||
* @param $data
|
||
* @return bool|void
|
||
*/
|
||
public function incV2(User $user, $data){
|
||
$type = $data['type'] ?? '';
|
||
$inc = $data['inc'] ?? 0;
|
||
// 判断:不存在下一级 升级失败
|
||
$nextLevel = $this->getNextLevel($user->brokerage_level);
|
||
if (!$nextLevel) return false;
|
||
// 判断:是否为基本升级条件 是则进行统一账单处理
|
||
if(in_array($type,self::BROKERAGE_RULE_TYPE)){
|
||
$make = app()->make(UserBillRepository::class);
|
||
$bill = $make->getWhere(['uid' => $user->uid, 'link_id' => $nextLevel->user_brokerage_id, 'category' => 'sys_brokerage', 'type' => $type]);
|
||
if ($bill) {
|
||
$bill->number = bcadd($bill->number, $inc, 2);
|
||
$bill->save();
|
||
} else {
|
||
$make->incBill($user->uid, 'sys_brokerage', $type, [
|
||
'number' => $inc,
|
||
'title' => $type,
|
||
'balance' => 0,
|
||
'status' => 0,
|
||
'link_id' => $nextLevel->user_brokerage_id
|
||
]);
|
||
}
|
||
}
|
||
|
||
// 升级判断流程开始
|
||
return $this->checkLevelV2($user, $nextLevel, $data);
|
||
}
|
||
/**
|
||
* Common: 分销商升级 - 升级判断及修改等级信息
|
||
* Author: wu-hui
|
||
* Time: 2023/12/26 14:20
|
||
* @param User $user
|
||
* @param UserBrokerage $nextLevel
|
||
* @param $data
|
||
* @return bool|void
|
||
*/
|
||
public function checkLevelV2(User $user, UserBrokerage $nextLevel, $data){
|
||
// 分销商升级条件判断
|
||
try{
|
||
// 循环判断是否达成所有升级条件 全部达成为true-成功升级,未全部达成为false-升级失败;为空则未设置升级条件-不允许升级
|
||
$info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id])->column('number', 'type');
|
||
$completeResult = [];// 每个条件达成情况:达成=true;未达成=false;未开启=空
|
||
foreach ($nextLevel['brokerage_rule'] as $upgradeKey => $rule) {
|
||
// 是否开启
|
||
if($rule['is_open'] != 1) continue;
|
||
// 根据类型进行对应的处理
|
||
if(in_array($upgradeKey,self::BROKERAGE_RULE_TYPE)){
|
||
// 基本升级条件 统一处理
|
||
if((float)$rule['num'] <= 0) continue;// 条件无效
|
||
// 判断:条件是否达标
|
||
$num = $info[$upgradeKey] ?? 0;
|
||
$completeResult[$upgradeKey] = (float)$rule['num'] >= (float)$num;
|
||
}else{
|
||
// 特殊升级条件 全部单独处理
|
||
$funName = 'upgradeJudge'.ucfirst(camelize($upgradeKey));
|
||
$judgeResult = $this->$funName($rule,$data);
|
||
if(gettype($judgeResult) == 'boolean') $completeResult[$upgradeKey] = $judgeResult;
|
||
}
|
||
}
|
||
// 判断:是否成功升级
|
||
if(array_sum($completeResult) != count($completeResult)) return false;// 结果为空,无有效升级条件;禁止升级
|
||
// 升级成功
|
||
$nextLevel->user_num++;
|
||
Db::transaction(function () use ($nextLevel, $user) {
|
||
$nextLevel->save();
|
||
if ($user->brokerage && $user->brokerage->user_num > 0) {
|
||
$user->brokerage->user_num--;
|
||
$user->brokerage->save();
|
||
}
|
||
// 不是推广员 开启推广员身份
|
||
if((int)$user->is_promoter != 1){
|
||
$user->is_promoter = 1;
|
||
$user->promoter_time = date('Y-m-d H:i:s');
|
||
}
|
||
$user->brokerage_level = $nextLevel->brokerage_level;
|
||
$user->save();
|
||
|
||
$key = 'notice_brokerage_level_' . $user->uid;
|
||
app()->make(CacheRepository::class)->save($key,$nextLevel->brokerage_level);
|
||
});
|
||
return true;
|
||
}catch(\Exception $e){
|
||
Log::info('分销商升级 - 错误: '.var_export([
|
||
'uid' => $user->uid,
|
||
'type' => $data['type'],
|
||
'msg' => $e->getMessage(),
|
||
],1));
|
||
}
|
||
}
|
||
/**
|
||
* Common: 分销商升级 - 升级条件判断 - 购买某个商品之一
|
||
* Author: wu-hui
|
||
* Time: 2023/12/26 14:35
|
||
* @param $rule
|
||
* @param $data
|
||
* @return bool|string
|
||
*/
|
||
private function upgradeJudgeManyGoods($rule,$data){
|
||
// 判断:条件是否有效
|
||
if(count($rule['ids']) <= 0) return '';// 条件无效 未设置商品
|
||
// 判断:是否存在订单信息 不存在直接返回false
|
||
if(!array_key_exists('group_order_id',$data)) return false;
|
||
// 处理订单信息
|
||
$orderIds = StoreOrder::where('group_order_id',$data['group_order_id'])->column('order_id');// 获取订单id
|
||
$productIds = StoreOrderProduct::whereIn('order_id',$orderIds)->column('product_id');// 获取当前订单中所有商品ID
|
||
$setNeedProductIds = Spu::whereIn('spu_id',$rule['ids'])->column('product_id');// 设置的需求商品ID
|
||
$intersectData = array_intersect($productIds,$setNeedProductIds);
|
||
return count($intersectData) > 0;
|
||
}
|
||
|
||
|
||
|
||
public function getLevelRate(User $user, UserBrokerage $nextLevel)
|
||
{
|
||
$info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id])
|
||
->column('number', 'type');
|
||
$brokerage_rule = $nextLevel['brokerage_rule'];
|
||
foreach ($nextLevel['brokerage_rule'] as $k => $rule) {
|
||
if ($rule['num'] <= 0) {
|
||
unset($brokerage_rule[$k]);
|
||
continue;
|
||
}
|
||
if (!isset($info[$k])) {
|
||
$rate = 0;
|
||
} else if ($rule['num'] > $info[$k]) {
|
||
$rate = bcdiv($info[$k], $rule['num'], 2) * 100;
|
||
} else {
|
||
$rate = 100;
|
||
}
|
||
$brokerage_rule[$k]['rate'] = $rate;
|
||
$brokerage_rule[$k]['task'] = (float)(min($info[$k] ?? 0, $rule['num']));
|
||
}
|
||
return $brokerage_rule;
|
||
}
|
||
|
||
public function form(?int $id = null)
|
||
{
|
||
$formData = [];
|
||
if ($id) {
|
||
$form = Elm::createForm(Route::buildUrl('systemUserMemberUpdate', ['id' => $id])->build());
|
||
$data = $this->dao->get($id);
|
||
if (!$data) throw new ValidateException('数据不存在');
|
||
$formData = $data->toArray();
|
||
|
||
} else {
|
||
$form = Elm::createForm(Route::buildUrl('systemUserMemberCreate')->build());
|
||
}
|
||
|
||
$rules = [
|
||
Elm::number('brokerage_level', '会员等级')->required(),
|
||
Elm::input('brokerage_name', '会员名称')->required(),
|
||
Elm::frameImage('brokerage_icon', '会员图标', '/' . config('admin.admin_prefix') . '/setting/uploadPicture?field=brokerage_icon&type=1')
|
||
->required()
|
||
->value($formData['brokerage_icon'] ?? '')
|
||
->modal(['modal' => false])
|
||
->width('1000px')
|
||
->height('600px'),
|
||
Elm::number('value', ' 所需成长值',$formData['brokerage_rule']['value'] ?? 0)->required(),
|
||
Elm::frameImage('image', '背景图', '/' . config('admin.admin_prefix') . '/setting/uploadPicture?field=image&type=1')
|
||
->value($formData['brokerage_rule']['image']??'')
|
||
->required()
|
||
->modal(['modal' => false])
|
||
->width('1000px')
|
||
->height('600px'),
|
||
];
|
||
$form->setRule($rules);
|
||
return $form->setTitle(is_null($id) ? '添加会员等级' : '编辑会员等级')->formData($formData);
|
||
}
|
||
|
||
public function incMemberValue(int $uid, string $type, int $id)
|
||
{
|
||
if (!systemConfig('member_status')) return ;
|
||
$make = app()->make(UserBillRepository::class);
|
||
$count = $make->getWhereCount(['type' => $type, 'link_id' => $id]);
|
||
if ($count) return ;
|
||
$config = [
|
||
'member_pay_num' => '下单获得成长值',
|
||
'member_sign_num' => '签到获得成长值',
|
||
'member_reply_num' => '评价获得成长值',
|
||
'member_share_num' => '邀请获得成长值',
|
||
'member_community_num' => '种草图文获得成长值',
|
||
];
|
||
$inc = systemConfig($type) > 0 ? systemConfig($type) : 0;
|
||
$user = app()->make(UserRepository::class)->getWhere(['uid' => $uid],'*',['member']);
|
||
$svip_status = $user->is_svip > 0 && systemConfig('svip_switch_status') == '1';
|
||
if ($svip_status) {
|
||
$svipRate = app()->make(MemberinterestsRepository::class)->getSvipInterestVal(MemberinterestsRepository::HAS_TYPE_MEMBER);
|
||
if ($svipRate > 0) {
|
||
$inc = bcmul($svipRate, $inc, 0);
|
||
}
|
||
}
|
||
$this->checkMemberValue($user, $inc);
|
||
$make->incBill($user->uid, 'sys_members', $type, [
|
||
'number' => $inc,
|
||
'title' => $config[$type],
|
||
'balance' => $user->member_value,
|
||
'status' => 0,
|
||
'link_id' => $id,
|
||
'mark' => $config[$type].':'.$inc,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* TODO 连续升级
|
||
* @param $nextLevel
|
||
* @param $num
|
||
* @return array
|
||
* @author Qinii
|
||
* @day 1/11/22
|
||
*/
|
||
public function upUp($nextLevel, $num)
|
||
{
|
||
$newLevel = $this->getNextLevel($nextLevel->brokerage_level, 1);
|
||
if ($newLevel) {
|
||
$newNum = $num - $newLevel->brokerage_rule['value'];
|
||
if ($newNum > 0) {
|
||
[$nextLevel,$num] = $this->upUp($newLevel, $newNum);
|
||
}
|
||
}
|
||
return [$nextLevel,$num];
|
||
}
|
||
|
||
/**
|
||
* TODO 升级操作
|
||
* @param User $user
|
||
* @param int $inc
|
||
* @author Qinii
|
||
* @day 1/11/22
|
||
*/
|
||
public function checkMemberValue(User $user, int $inc)
|
||
{
|
||
/**
|
||
* 下一级所需经验值
|
||
* 当前的经验值加上增加经验值是否够升级
|
||
*/
|
||
Db::transaction(function () use ($inc, $user) {
|
||
$nextLevel = $this->getNextLevel($user->member_level, 1);
|
||
if (!$nextLevel) return ;
|
||
if (($user->member_value + $inc) >= $nextLevel->brokerage_rule['value']) {
|
||
|
||
$num = ($user->member_value + $inc) - $nextLevel->brokerage_rule['value'];
|
||
if ($num > 0) {
|
||
[$nextLevel,$num] = $this->upUp($nextLevel, $num);
|
||
}
|
||
if ($user->member) {
|
||
$user->member->user_num--;
|
||
$user->member->save();
|
||
}
|
||
|
||
$nextLevel->user_num++;
|
||
$nextLevel->save();
|
||
|
||
$user->member_level = $nextLevel->brokerage_level;
|
||
|
||
$key = 'notice_member_level_' . $user->uid;
|
||
app()->make(CacheRepository::class)->save($key,$nextLevel->brokerage_level);
|
||
} else {
|
||
$num = ($user->member_value + $inc);
|
||
}
|
||
$user->member_value = $num;
|
||
$user->save();
|
||
});
|
||
}
|
||
}
|