feat(commission): 支持计奖商品参与设置、独立分成与多规格规则,完善团队中心与微信快捷登录

这个提交包含在:
chen
2026-09-17 19:27:17 +08:00
父节点 3c7df9688b
当前提交 829e88cfa9
共有 54 个文件被更改,包括 3536 次插入 和 666 次删除

查看文件

@@ -6,6 +6,7 @@ use think\Db;
use app\admin\model\shopro\user\User as UserModel;
use app\admin\model\shopro\commission\Agent as AgentModel;
use app\admin\model\shopro\goods\Goods as GoodsModel;
use app\admin\model\shopro\partner\Reward as RewardModel;
use addons\shopro\service\Wallet;
@@ -268,11 +269,21 @@ class Agent extends Commission
$user->team_level = ($user->parent_user_id == $agentId) ? 1 : 2;
$rawMobile = $user->mobile ? (string) $user->mobile : '';
$maskedMobile = $rawMobile ? (strlen($rawMobile) == 11 ? substr_replace($rawMobile, '****', 3, 4) : $rawMobile) : '';
$user->mobile = $maskedMobile;
$user->mobile_hide = $maskedMobile;
$user->mobile_raw = $rawMobile;
$user->mobile_hide = $rawMobile ? (strlen($rawMobile) == 11 ? substr_replace($rawMobile, '****', 3, 4) : $rawMobile) : '';
// 间推所属推荐人手机号脱敏
if ($user->parentUser && $user->parentUser->mobile) {
$pMobile = (string) $user->parentUser->mobile;
$pMasked = strlen($pMobile) == 11 ? substr_replace($pMobile, '****', 3, 4) : $pMobile;
$user->parentUser->mobile = $pMasked;
$user->parentUser->mobile_hide = $pMasked;
}
});
// 9. 计算整体团队健康度统计
// 9. 计算整体团队健康度与综合收益业绩统计
$summary = $this->getTeamHealthSummary($agentId, $level1Ids, $windowStart, $expiringStart);
$result = $data->toArray();
@@ -282,7 +293,7 @@ class Agent extends Commission
}
/**
* 计算团队保活健康度统计
* 计算团队保活健康度与综合收益统计
*/
protected function getTeamHealthSummary($agentId, $level1Ids, $windowStart, $expiringStart)
{
@@ -298,6 +309,10 @@ class Agent extends Commission
'expiring_count' => 0,
'inactive_count' => 0,
'partner_count' => 0,
'team_total_consume' => '0.00',
'team_total_reward' => '0.00',
'team_month_reward' => '0.00',
'team_order_count' => 0,
];
}
@@ -306,6 +321,7 @@ class Agent extends Commission
$expiringCount = 0;
$inactiveCount = 0;
$partnerCount = 0;
$teamOrderCount = 0;
foreach ($agents as $ag) {
$level = intval($ag->level ?? 0);
@@ -323,6 +339,8 @@ class Agent extends Commission
} else {
$inactiveCount++;
}
$teamOrderCount += intval($ag->child_order_count_0 ?? 0);
}
$missingAgentCount = count($teamUserIds) - count($agents);
@@ -330,12 +348,31 @@ class Agent extends Commission
$inactiveCount += $missingAgentCount;
}
// 1. 团队累计自购总业绩
$teamTotalConsume = UserModel::whereIn('id', $teamUserIds)->sum('total_consume');
// 2. 团队成员为当前用户贡献的累计收益与本月收益
$monthStart = strtotime(date('Y-m-01 00:00:00'));
$teamTotalReward = RewardModel::where('user_id', $agentId)
->whereIn('buyer_id', $teamUserIds)
->where('status', 1)
->sum('amount');
$teamMonthReward = RewardModel::where('user_id', $agentId)
->whereIn('buyer_id', $teamUserIds)
->where('status', 1)
->where('createtime', '>=', $monthStart)
->sum('amount');
return [
'total_count' => count($teamUserIds),
'active_count' => $activeCount,
'expiring_count' => $expiringCount,
'inactive_count' => $inactiveCount,
'partner_count' => $partnerCount,
'team_total_consume' => \addons\shopro\service\partner\IdentityService::formatMoney($teamTotalConsume),
'team_total_reward' => \addons\shopro\service\partner\IdentityService::formatMoney($teamTotalReward),
'team_month_reward' => \addons\shopro\service\partner\IdentityService::formatMoney($teamMonthReward),
'team_order_count' => $teamOrderCount,
];
}

查看文件

@@ -40,6 +40,7 @@ class Index extends Commission
{
$userId = $this->service->user->id;
$tab = $this->request->param('tab', 'all');
$buyerId = intval($this->request->param('buyer_id', 0));
$query = RewardModel::where('user_id', $userId)->with(['buyer', 'order']);
$tabMap = [
@@ -52,6 +53,9 @@ class Index extends Commission
if ($tab !== 'all' && isset($tabMap[$tab])) {
$query->whereIn('reward_type', $tabMap[$tab]);
}
if ($buyerId > 0) {
$query->where('buyer_id', $buyerId);
}
$list = $query->order('id', 'desc')->paginate($this->request->param('list_rows', 10));
$rows = [];
@@ -74,11 +78,26 @@ class Index extends Commission
];
}
$buyerInfo = null;
if ($buyerId > 0) {
$buyerUser = \app\admin\model\shopro\user\User::get($buyerId);
if ($buyerUser) {
$rawMobile = (string) ($buyerUser->mobile ?? '');
$buyerInfo = [
'id' => $buyerUser->id,
'nickname' => $buyerUser->nickname,
'avatar' => $buyerUser->avatar,
'mobile' => $rawMobile ? (strlen($rawMobile) == 11 ? substr_replace($rawMobile, '****', 3, 4) : $rawMobile) : '',
];
}
}
$this->success('ok', [
'total' => $list->total(),
'per_page' => $list->listRows(),
'current_page' => $list->currentPage(),
'data' => $rows,
'buyer_info' => $buyerInfo,
]);
}

查看文件

@@ -44,7 +44,10 @@ class Wechat extends Common
});
if ($result) {
$this->success('登陆成功');
$auth = \app\common\library\Auth::instance();
$this->success('登陆成功', [
'token' => $auth->isLogin() ? $auth->getToken() : ''
]);
}
$this->error('登陆失败');
}

查看文件

@@ -39,9 +39,60 @@ class AgentFilter extends BaseFilter
if ($value === 'county') {
return $query->where('is_county', 1);
}
if ($value === 'partner') {
return $query->where('is_partner', 1);
}
return $query;
}
/**
* 等级筛选 (如 1 为品酒师)
*/
public function level($query, $data)
{
$value = $this->plainValue($data);
if ($value === '' || $value === null) {
return $query;
}
return $query->where('level', (int)$value);
}
/**
* 酒道馆筛选 (1 为酒道馆)
*/
public function isVenue($query, $data)
{
$value = $this->plainValue($data);
if ($value === '' || $value === null) {
return $query;
}
return $query->where('is_venue', (int)$value);
}
/**
* 区县代理筛选 (1 为区县代理)
*/
public function isCounty($query, $data)
{
$value = $this->plainValue($data);
if ($value === '' || $value === null) {
return $query;
}
return $query->where('is_county', (int)$value);
}
/**
* 合伙股东筛选 (1 为合伙股东)
*/
public function isPartner($query, $data)
{
$value = $this->plainValue($data);
if ($value === '' || $value === null) {
return $query;
}
return $query->where('is_partner', (int)$value);
}
public function active30d($query, $data)
{
$value = $this->plainValue($data);

查看文件

@@ -66,7 +66,7 @@ class OrderCreate
/**
* 用户选择的兑换券抵扣金额
*/
protected $voucher_fee = 0;
protected $voucher_fee = null;
/**
* 用户备注
@@ -158,7 +158,7 @@ class OrderCreate
$this->invoice_id = $params['invoice_id'] ?? 0;
$this->coupon_id = $params['coupon_id'] ?? 0;
$this->voucher_fee = isset($params['voucher_fee']) ? floatval($params['voucher_fee']) : 0;
$this->voucher_fee = (isset($params['voucher_fee']) && $params['voucher_fee'] !== '') ? floatval($params['voucher_fee']) : null;
$this->remark = $params['remark'] ?? '';
$this->money = (isset($params['money']) && $params['money'] > 0) ? $params['money'] : 0;
@@ -611,7 +611,14 @@ class OrderCreate
$available = (new \addons\shopro\service\partner\VoucherService())->available($this->user->id);
}
$this->orderData['voucher_available'] = $available;
$want = max(0, round((float) $this->voucher_fee, 2));
// 兑换商城订单:若未显式指定抵扣额度,默认自动全额应用可用兑换券
if ($this->voucher_fee === null) {
$want = $this->order_type == 'score' ? (float) $available : 0;
} else {
$want = max(0, round((float) $this->voucher_fee, 2));
}
$apply = min($want, (float) $available, (float) $this->orderData['pay_fee']);
$apply = $apply > 0 ? $apply : 0;
$this->orderData['voucher_fee'] = $apply;

查看文件

@@ -7,9 +7,11 @@ namespace addons\shopro\service\partner;
*/
class MakerDiffReward
{
public function run($order, $buyerId, $chain, ActiveService $active)
public function run($order, $buyerId, $chain, ActiveService $active, $rules = null)
{
$bonus = PartnerConfig::makerBonus();
$bonus = (!empty($rules['maker_bonus']) && is_array($rules['maker_bonus']))
? $rules['maker_bonus']
: PartnerConfig::makerBonus();
$seen = 0;
$paid = [];

查看文件

@@ -7,11 +7,17 @@ namespace addons\shopro\service\partner;
*/
class MakerPeerReward
{
public function run($order, $buyerId, $chain, $diffResult, ActiveService $active)
public function run($order, $buyerId, $chain, $diffResult, ActiveService $active, $rules = null)
{
$bonus = PartnerConfig::makerBonus();
$peerRate = (float) PartnerConfig::get('partner_maker_peer_rate', 0.10);
$overRate = (float) PartnerConfig::get('partner_maker_overtaken_rate', 0.05);
$bonus = (!empty($rules['maker_bonus']) && is_array($rules['maker_bonus']))
? $rules['maker_bonus']
: PartnerConfig::makerBonus();
$peerRate = (isset($rules['maker_peer_rate']) && is_numeric($rules['maker_peer_rate']))
? (float) $rules['maker_peer_rate']
: (float) PartnerConfig::get('partner_maker_peer_rate', 0.10);
$overRate = (isset($rules['maker_overtaken_rate']) && is_numeric($rules['maker_overtaken_rate']))
? (float) $rules['maker_overtaken_rate']
: (float) PartnerConfig::get('partner_maker_overtaken_rate', 0.05);
$minAmount = (float) PartnerConfig::get('partner_peer_min_amount', 0.10);
if ($minAmount <= 0) {
$minAmount = 0.10;

查看文件

@@ -167,8 +167,143 @@ class PartnerConfig
];
}
public static function dailyTypes()
public static function defaultRules()
{
return ['venue_share', 'county_share', 'madow_share', 'voucher_release'];
return [
'push3_amounts' => self::push3Amounts(),
'maker_bonus' => self::makerBonus(),
'maker_peer_rate' => (float) self::get('partner_maker_peer_rate', 0.10),
'maker_overtaken_rate' => (float) self::get('partner_maker_overtaken_rate', 0.05),
'venue_split' => (float) self::get('partner_venue_split', 50),
'county_full' => (float) self::get('partner_county_full', 100),
'venue_peer_rate' => (float) self::get('partner_venue_peer_rate', 0.10),
'county_peer_rate' => (float) self::get('partner_county_peer_rate', 0.10),
'voucher_times' => (float) self::get('partner_voucher_times', 1.5),
'voucher_days' => (int) self::get('partner_voucher_days', 365),
'venue_share' => (float) self::get('partner_venue_share_per_order', 100),
'county_share' => (float) self::get('partner_county_share_per_order', 50),
'is_custom' => false,
];
}
/**
* 获取指定商品/规格的生效分成规则(优先独立规则,未设置项回退默认规则)
*/
public static function getEffectiveRules($goodsId, $skuPriceId = 0)
{
$rules = self::defaultRules();
$goodsId = intval($goodsId);
if ($goodsId <= 0) {
return $rules;
}
try {
$cg = \think\Db::name('shopro_commission_goods')->where('goods_id', $goodsId)->find();
if (!$cg || intval($cg['status'] ?? 0) !== 1) {
// 未参与计奖
$rules['status'] = 0;
return $rules;
}
$rules['status'] = 1;
$rules['commission_order_status'] = intval($cg['commission_order_status'] ?? 1);
$selfRules = intval($cg['self_rules'] ?? 0);
$rules['self_rules'] = $selfRules;
if ($selfRules !== 1 && $selfRules !== 2) {
return $rules; // 默认规则
}
$raw = $cg['commission_rules'] ?? '';
$custom = is_array($raw) ? $raw : (json_decode($raw, true) ?: []);
if (empty($custom)) {
return $rules;
}
// 多规格支持:优先匹配特定规格配置
$skuKey = intval($skuPriceId);
if ($skuKey > 0 && isset($custom[$skuKey]) && is_array($custom[$skuKey])) {
$custom = $custom[$skuKey];
} elseif ($skuKey > 0 && isset($custom['sku_' . $skuKey]) && is_array($custom['sku_' . $skuKey])) {
$custom = $custom['sku_' . $skuKey];
}
if (isset($custom['push3_amounts']) && is_array($custom['push3_amounts']) && count($custom['push3_amounts']) >= 3) {
$rules['push3_amounts'] = array_map('floatval', array_values($custom['push3_amounts']));
}
if (isset($custom['maker_bonus']) && is_array($custom['maker_bonus'])) {
$mb = [];
foreach ($custom['maker_bonus'] as $lvl => $val) {
$mb[intval($lvl)] = floatval($val);
}
$rules['maker_bonus'] = $mb;
}
if (isset($custom['maker_peer_rate']) && is_numeric($custom['maker_peer_rate'])) {
$rules['maker_peer_rate'] = floatval($custom['maker_peer_rate']);
}
if (isset($custom['maker_overtaken_rate']) && is_numeric($custom['maker_overtaken_rate'])) {
$rules['maker_overtaken_rate'] = floatval($custom['maker_overtaken_rate']);
}
if (isset($custom['venue_split']) && is_numeric($custom['venue_split'])) {
$rules['venue_split'] = floatval($custom['venue_split']);
}
if (isset($custom['county_full']) && is_numeric($custom['county_full'])) {
$rules['county_full'] = floatval($custom['county_full']);
}
if (isset($custom['venue_peer_rate']) && is_numeric($custom['venue_peer_rate'])) {
$rules['venue_peer_rate'] = floatval($custom['venue_peer_rate']);
}
if (isset($custom['county_peer_rate']) && is_numeric($custom['county_peer_rate'])) {
$rules['county_peer_rate'] = floatval($custom['county_peer_rate']);
}
if (isset($custom['voucher_times']) && is_numeric($custom['voucher_times'])) {
$rules['voucher_times'] = floatval($custom['voucher_times']);
}
if (isset($custom['voucher_days']) && is_numeric($custom['voucher_days'])) {
$rules['voucher_days'] = intval($custom['voucher_days']);
}
if (isset($custom['venue_share']) && is_numeric($custom['venue_share'])) {
$rules['venue_share'] = floatval($custom['venue_share']);
}
if (isset($custom['county_share']) && is_numeric($custom['county_share'])) {
$rules['county_share'] = floatval($custom['county_share']);
}
$rules['is_custom'] = true;
return $rules;
} catch (\Exception $e) {
return $rules;
}
}
/**
* 解析订单中主计奖商品的生效分成规则
*/
public static function getOrderEffectiveRules($order)
{
$default = self::defaultRules();
$items = $order['items'] ?? [];
if (empty($items) && !empty($order['id'])) {
$fresh = \app\admin\model\shopro\order\Order::with(['items'])->where('id', $order['id'])->find();
if ($fresh) {
$items = $fresh['items'] ?? [];
}
}
// 优先寻找设置了独立分成规则的计奖商品
foreach ($items as $item) {
$ext = is_array($item['ext'] ?? null) ? $item['ext'] : (json_decode($item['ext'] ?? '', true) ?: []);
if (isset($ext['is_commission']) && !$ext['is_commission']) {
continue;
}
$goodsId = intval($item['goods_id'] ?? 0);
$skuId = intval($item['goods_sku_price_id'] ?? 0);
$rules = self::getEffectiveRules($goodsId, $skuId);
if (!empty($rules['is_custom'])) {
return $rules;
}
}
return $default;
}
}

查看文件

@@ -40,16 +40,19 @@ class PartnerRewardService
$parentChain = $chainService->collect($buyerId, false);
$selfChain = $chainService->collect($buyerId, true);
// 动态解析商品独立分成规则与全局默认配置
$orderRules = PartnerConfig::getOrderEffectiveRules($order);
$parent = $parentChain[0] ?? null;
(new Push3Reward())->run($order, $buyerId, $parent, $active);
(new Push3Reward())->run($order, $buyerId, $parent, $active, $orderRules);
$diff = (new MakerDiffReward())->run($order, $buyerId, $parentChain, $active);
(new MakerPeerReward())->run($order, $buyerId, $parentChain, $diff, $active);
$diff = (new MakerDiffReward())->run($order, $buyerId, $parentChain, $active, $orderRules);
(new MakerPeerReward())->run($order, $buyerId, $parentChain, $diff, $active, $orderRules);
$team = (new TeamSplitReward())->run($order, $buyerId, $selfChain, $active);
(new PeerShareReward())->run($order, $buyerId, $selfChain, $team, $active);
$team = (new TeamSplitReward())->run($order, $buyerId, $selfChain, $active, $orderRules);
(new PeerShareReward())->run($order, $buyerId, $selfChain, $team, $active, $orderRules);
(new VoucherService())->grant($order, $buyerId);
(new VoucherService())->grant($order, $buyerId, $orderRules);
return true;
});

查看文件

@@ -7,10 +7,14 @@ namespace addons\shopro\service\partner;
*/
class PeerShareReward
{
public function run($order, $buyerId, $chain, $teamResult, ActiveService $active)
public function run($order, $buyerId, $chain, $teamResult, ActiveService $active, $rules = null)
{
$venueRate = (float) PartnerConfig::get('partner_venue_peer_rate', 0.10);
$countyRate = (float) PartnerConfig::get('partner_county_peer_rate', 0.10);
$venueRate = (isset($rules['venue_peer_rate']) && is_numeric($rules['venue_peer_rate']))
? (float) $rules['venue_peer_rate']
: (float) PartnerConfig::get('partner_venue_peer_rate', 0.10);
$countyRate = (isset($rules['county_peer_rate']) && is_numeric($rules['county_peer_rate']))
? (float) $rules['county_peer_rate']
: (float) PartnerConfig::get('partner_county_peer_rate', 0.10);
if (!empty($teamResult['venue'])) {
$this->peer($order, $buyerId, $chain, $teamResult['venue'], 'is_venue', 'venue_peer', 'venue', $venueRate, $active, '酒道馆');

查看文件

@@ -9,7 +9,7 @@ use app\admin\model\shopro\commission\Agent as AgentModel;
*/
class Push3Reward
{
public function run($order, $buyerId, $parent, ActiveService $active)
public function run($order, $buyerId, $parent, ActiveService $active, $rules = null)
{
if (!$parent) {
PartnerRewardService::writeSkip($order, $buyerId, 0, 'push3', 'taster', 'no_parent', '暂无推荐人,不计提推荐开拓奖');
@@ -35,7 +35,9 @@ class Push3Reward
$agent->direct_order_seq = intval($agent->direct_order_seq) + 1;
$agent->save();
$amounts = PartnerConfig::push3Amounts();
$amounts = (!empty($rules['push3_amounts']) && is_array($rules['push3_amounts']))
? $rules['push3_amounts']
: PartnerConfig::push3Amounts();
$seq = intval($agent->direct_order_seq);
$amount = $amounts[($seq - 1) % 3];

查看文件

@@ -7,10 +7,14 @@ namespace addons\shopro\service\partner;
*/
class TeamSplitReward
{
public function run($order, $buyerId, $chain, ActiveService $active)
public function run($order, $buyerId, $chain, ActiveService $active, $rules = null)
{
$venueSplit = (float) PartnerConfig::get('partner_venue_split', 50);
$countyFull = (float) PartnerConfig::get('partner_county_full', 100);
$venueSplit = (isset($rules['venue_split']) && is_numeric($rules['venue_split']))
? (float) $rules['venue_split']
: (float) PartnerConfig::get('partner_venue_split', 50);
$countyFull = (isset($rules['county_full']) && is_numeric($rules['county_full']))
? (float) $rules['county_full']
: (float) PartnerConfig::get('partner_county_full', 100);
$result = ['venue' => null, 'county' => null];
$venue = $this->nearest($chain, 'is_venue', $active);

查看文件

@@ -123,15 +123,19 @@ class VoucherService
}
}
public function grant($order, $buyerId)
public function grant($order, $buyerId, $rules = null)
{
$exists = VoucherPlan::where('order_id', $order['id'])->find();
if ($exists) {
return $exists;
}
$times = (float) PartnerConfig::get('partner_voucher_times', 1.5);
$days = intval(PartnerConfig::get('partner_voucher_days', 365));
$times = (isset($rules['voucher_times']) && is_numeric($rules['voucher_times']))
? (float) $rules['voucher_times']
: (float) PartnerConfig::get('partner_voucher_times', 1.5);
$days = (isset($rules['voucher_days']) && is_numeric($rules['voucher_days']))
? intval($rules['voucher_days'])
: intval(PartnerConfig::get('partner_voucher_days', 365));
$days = $days > 0 ? $days : 365;
$rewardService = new PartnerRewardService();
$qualifiedPayFee = $rewardService->getQualifiedPayFee($order);

查看文件

@@ -249,6 +249,19 @@ class PayOper
// 订单支付完成
$user = User::where('id', $order->user_id)->find();
if ($order_type == 'order') {
// 兑换券同步核销(利用行锁即时扣减并标记,彻底消除异步队列延迟导致的并发双花漏洞)
$ext = $order->ext;
if (is_string($ext)) {
$ext = json_decode($ext, true) ?: [];
}
if (!empty($ext['voucher_fee']) && empty($ext['voucher_consumed'])) {
try {
(new \addons\shopro\service\partner\VoucherService())->consumeByOrder($order);
} catch (\Exception $e) {
\think\Log::record('[PayOper.consumeByOrder] 兑换券同步核销异常: ' . $e->getMessage(), 'error');
}
}
if ($pay_mode == 'offline') {
Action::add($order, null, auth_admin(), 'admin', '管理员操作自动货到付款支付成功');
// 在控制器执行后续内容,这里不再处理

查看文件

@@ -34,10 +34,16 @@ class MiniProgram
error_stop('登陆态已过期, 请重试', -1);
}
// 如果前端传了手机号凭证(新版 code 或传统 iv+encryptedData),解析手机号
$mobile = '';
if (!empty($this->payload['code']) || (!empty($this->payload['iv']) && !empty($this->payload['encryptedData']))) {
$mobile = $this->getUserPhoneNumber();
}
$wechatUser = [
'openid' => $sessionData['openid'],
'unionid' => $sessionData['unionid'] ?? '',
'mobile' => '',
'mobile' => $mobile,
'avatar' => '',
'nickname' => '',
];
@@ -65,9 +71,32 @@ class MiniProgram
return $wechatUser;
}
// 解密微信小程序手机号
// 解密微信小程序手机号(支持新版 code 与传统 iv + encryptedData)
public function getUserPhoneNumber()
{
// 1. 优先使用新版微信小程序通过 code 获取手机号 API
if (!empty($this->payload['code'])) {
try {
$response = $this->wechat->auth->httpPostJson('wxa/business/getuserphonenumber', [
'code' => $this->payload['code']
]);
if (isset($response['errcode']) && (int)$response['errcode'] === 0 && !empty($response['phone_info']['purePhoneNumber'])) {
if (!empty($response['phone_info']['countryCode']) && $response['phone_info']['countryCode'] !== '86') {
error_stop('仅支持大陆地区手机号');
}
return $response['phone_info']['purePhoneNumber'];
}
if (!empty($response['errmsg']) && empty($this->payload['encryptedData'])) {
error_stop('获取手机号失败: ' . $response['errmsg']);
}
} catch (\Exception $e) {
if (empty($this->payload['encryptedData'])) {
error_stop('获取手机号异常: ' . $e->getMessage());
}
}
}
// 2. 兼容传统 iv + encryptedData 模式
if (empty($this->payload['sessionId'])) {
error_stop('未获取到登陆态, 请重试', -1);
}
@@ -78,6 +107,10 @@ class MiniProgram
error_stop('登陆态已过期, 请重试', -1);
}
if (empty($this->payload['iv']) || empty($this->payload['encryptedData'])) {
error_stop('缺少手机号授权凭证');
}
$phoneInfo = $this->wechat->encryptor->decryptData($sessionData['session_key'], $this->payload['iv'], $this->payload['encryptedData']);
if (empty($phoneInfo['purePhoneNumber'])) {

查看文件

@@ -146,6 +146,23 @@ class Wechat
// 用户被删除,则重置第三方信息所绑定的用户id
if (!$user) {
$oauthInfo->user_id = 0;
} else {
// 如果本次快捷登录提供了手机号,且用户原本没有手机号,则为用户补充手机号
$isChanged = false;
if (!empty($extend['mobile']) && empty($user->mobile)) {
$user->mobile = $extend['mobile'];
$isChanged = true;
}
$verification = $user->verification;
$verificationObj = is_object($verification) ? $verification : (object)$verification;
if ((!empty($user->mobile) || !empty($extend['mobile'])) && empty($verificationObj->mobile)) {
$verificationObj->mobile = 1;
$user->verification = $verificationObj;
$isChanged = true;
}
if ($isChanged) {
$user->save();
}
}
}
@@ -161,8 +178,18 @@ class Wechat
return false;
}
// 注册新用户
// 注册新用户或匹配已有手机号用户
if ($oauthInfo->user_id === 0 && $user_id === 0) {
// 如果获取到了手机号,检查系统是否已有该手机号用户
if (!empty($extend['mobile'])) {
$existingUser = UserModel::where('mobile', $extend['mobile'])->find();
if ($existingUser) {
// 直接将此第三方账号关联到该已有手机号用户
$oauthInfo->user_id = $existingUser->id;
return $oauthInfo->save();
}
}
$auth = (new UserAuth())->register([
'nickname' => $oauthInfo->nickname ?? '',
'avatar' => $oauthInfo->avatar ?? '',