service->getAgentStatus(true); $condition = [ 'type' => '', 'value' => '' ]; switch ($status) { case AgentModel::AGENT_STATUS_NULL: $condition = $this->service->config->getBecomeAgentEvent(); if ($condition['type'] === 'goods') { $condition['value'] = GoodsModel::show()->whereIn('id', $condition['value'])->select(); } $this->error('', $condition, 100); break; case AgentModel::AGENT_STATUS_NEEDINFO: $this->error('待完善信息,请补充您的资料后提交审核', $condition, 103); break; case AgentModel::AGENT_STATUS_PENDING: $this->error('正在审核中,请耐心等候结果', $condition, 104); break; case AgentModel::AGENT_STATUS_REJECT: $agentFormStatus = $this->service->config->isAgentApplyForm(); if ($agentFormStatus) { $this->error('抱歉!您的申请信息未通过,请尝试修改后重新提交', $condition, 105); } else { $this->error('抱歉!您的申请未通过,请尝试重新申请', $condition, 106); } break; case AgentModel::AGENT_STATUS_FREEZE: $this->error('抱歉!您的账户已被冻结,如有疑问请联系客服', $condition, 107); break; } $data = $this->service->agent; // 增强代理商数据信息 if ($data) { $data = $data->toArray(); // 添加代理商类型描述(使用枚举类) $data['agent_type_text'] = AgentType::getTypeText($data['agent_type']); // 构造代理商身份描述和区域信息 $identityData = $this->buildAgentIdentityData($data); $data['agent_identity_title'] = $identityData['title']; $data['manage_area'] = $identityData['area_info']; $data['manage_area_text'] = $identityData['area_text']; // 获取用户基本信息和佣金数据 $user = $this->service->user; if ($user) { $data['user_info'] = [ 'nickname' => $user->nickname, 'avatar' => cdnurl($user->avatar), // 转换为完整CDN URL 'username' => $user->username, ]; } $data['commission'] = $this->service->user->commission ?? 0; // 获取代理商申请信息 $applyInfo = ApplyModel::where('user_id', $this->service->user->id) ->order('id desc') ->find(); $data['apply_info'] = $applyInfo; } $this->success('分销商信息', $data); } /** * 构造代理商身份数据(包括标题和区域信息) * 优化版本:直接使用数据库中存储的名称字段,无需关联查询区域表 * @param array $agentData 代理商数据 * @return array */ private function buildAgentIdentityData($agentData) { $result = [ 'title' => '普通代理商', 'area_info' => null, 'area_text' => '-' ]; switch ($agentData['agent_type']) { case AgentType::NORMAL: $result['title'] = '普通代理商'; break; case AgentType::PROVINCE: // 省级代理商:山东省代理商 $provinceName = $agentData['manage_province_name'] ?? ''; if (!empty($provinceName)) { $result['title'] = $provinceName . '代理商'; $result['area_info'] = [ 'province_name' => $provinceName, 'province_id' => $agentData['manage_province_id'] ?? null ]; $result['area_text'] = $provinceName; } else { $result['title'] = '省级代理商'; } break; case AgentType::CITY: // 市级代理商:临沂市代理商 $areaInfo = []; $areaText = []; // 获取省份信息 $provinceName = $agentData['manage_province_name'] ?? ''; if (!empty($provinceName)) { $areaInfo['province_name'] = $provinceName; $areaInfo['province_id'] = $agentData['manage_province_id'] ?? null; $areaText[] = $provinceName; } // 获取城市信息 $cityName = $agentData['manage_city_name'] ?? ''; if (!empty($cityName)) { $result['title'] = $cityName . '代理商'; $areaInfo['city_name'] = $cityName; $areaInfo['city_id'] = $agentData['manage_city_id'] ?? null; $areaText[] = $cityName; } else { $result['title'] = '市级代理商'; } if (!empty($areaInfo)) { $result['area_info'] = $areaInfo; $result['area_text'] = implode('-', $areaText); } break; case AgentType::DISTRICT: // 区级代理商:兰山区代理商 $areaInfo = []; $areaText = []; // 获取省份信息 $provinceName = $agentData['manage_province_name'] ?? ''; if (!empty($provinceName)) { $areaInfo['province_name'] = $provinceName; $areaInfo['province_id'] = $agentData['manage_province_id'] ?? null; $areaText[] = $provinceName; } // 获取城市信息 $cityName = $agentData['manage_city_name'] ?? ''; if (!empty($cityName)) { $areaInfo['city_name'] = $cityName; $areaInfo['city_id'] = $agentData['manage_city_id'] ?? null; $areaText[] = $cityName; } // 获取区域信息 $districtName = $agentData['manage_district_name'] ?? ''; if (!empty($districtName)) { $result['title'] = $districtName . '代理商'; $areaInfo['district_name'] = $districtName; $areaInfo['district_id'] = $agentData['manage_district_id'] ?? null; $areaText[] = $districtName; } else { $result['title'] = '区域代理商'; } if (!empty($areaInfo)) { $result['area_info'] = $areaInfo; $result['area_text'] = implode('-', $areaText); } break; } return $result; } // 我的团队 public function team() { $params = $this->request->param(); // 使用验证器验证分页参数:page, page_size, time_filter, start_date, end_date $validate = new \app\api\validate\Agent(); if (!$validate->scene('team')->check($params)) { $this->error($validate->getError()); } $agentId = $this->service->user->id; // 获取验证后的参数 $pageSize = isset($params['page_size']) ? (int)$params['page_size'] : 8; $timeFilter = isset($params['time_filter']) ? $params['time_filter'] : 'all'; $startDate = isset($params['start_date']) ? $params['start_date'] : ''; $endDate = isset($params['end_date']) ? $params['end_date'] : ''; // 构建查询条件 $query = UserModel::where('parent_user_id', $agentId) ->where('status', 1); // 根据时间筛选参数添加时间条件 if ($timeFilter !== 'all') { $timeConditions = $this->getTimeFilterConditions($timeFilter, $startDate, $endDate); if ($timeConditions) { $query->where('bind_time', '>=', $timeConditions['start_time']); if (isset($timeConditions['end_time'])) { $query->where('bind_time', '<=', $timeConditions['end_time']); } } } $data = $query->field('id,username,nickname,avatar,mobile,bind_time,commission,order_count,total_consume,status,parent_user_id') ->with(['agent' => function ($query) { return $query->with('level_info')->field('user_id,agent_type,child_user_count_all,child_order_money_all'); }]) ->paginate($pageSize); // 将分页对象转换为数组进行处理 $paginateData = $data->toArray(); // 为代理商成员添加身份标题和统计数据 $this->addAgentIdentityTitle($paginateData['data']); // 获取当前代理商信息 $currentAgent = $this->service->agent; // 重新构造返回数据 $result = [ 'total' => $paginateData['total'], 'per_page' => $paginateData['per_page'], 'current_page' => $paginateData['current_page'], 'last_page' => $paginateData['last_page'], 'list' => $paginateData['data'], 'agent_info' => [ 'child_user_count_all' => intval($currentAgent['child_user_count_all'] ?? 0), 'child_order_money_all' => BcMath::format($currentAgent['child_order_money_all'] ?? '0.00') ] ]; $this->success("", $result); } /** * 为团队成员添加身份标题和统计数据(统一处理所有用户) * @param array $teamMembers 团队成员数据数组的引用 * @return void */ private function addAgentIdentityTitle(&$teamMembers) { if (empty($teamMembers)) { return; } foreach ($teamMembers as &$member) { //处理头像 $member['avatar'] = !empty($member['avatar']) ? cdnurl($member['avatar']) : ''; //格式化绑定时间 $member['bind_time_text'] = !empty($member['bind_time']) ? date('Y-m-d', $member['bind_time']) : ''; if (!empty($member['agent'])) { // 代理商用户:构造具体的代理商身份标题 $identityData = $this->buildAgentIdentityData($member['agent']); $member['agent_identity_title'] = $identityData['title']; // 添加代理商统计数据 $member['order_count'] = intval($member['agent']['child_user_count_all'] ?? 0); $member['total_consume'] = BcMath::format($member['agent']['child_order_money_all'] ?? '0.00'); } else { // 普通用户:统一设置为"普通用户" $member['agent_identity_title'] = '普通用户'; // 添加普通用户统计数据 $member['order_count'] = intval($member['order_count'] ?? 0); $member['total_consume'] = BcMath::format($member['total_consume'] ?? '0.00'); } } } /** * 获取时间筛选条件 * @param string $timeFilter 时间筛选类型 * @param string $startDate 开始日期 (Y-m-d格式,用于自定义时间段) * @param string $endDate 结束日期 (Y-m-d格式,用于自定义时间段) * @return array|null 返回包含开始时间和结束时间的数组 */ private function getTimeFilterConditions($timeFilter, $startDate = '', $endDate = '') { $currentTime = time(); switch ($timeFilter) { case 'recent_7_days': return [ 'start_time' => $currentTime - 7 * 24 * 3600, ]; case 'recent_30_days': return [ 'start_time' => $currentTime - 30 * 24 * 3600, ]; case 'recent_90_days': return [ 'start_time' => $currentTime - 90 * 24 * 3600, ]; case 'current_year': // 当前年份的开始时间 $yearStart = strtotime(date('Y-01-01 00:00:00')); // 当前年份的结束时间 $yearEnd = strtotime(date('Y-12-31 23:59:59')); return [ 'start_time' => $yearStart, 'end_time' => $yearEnd, ]; case 'custom': // 自定义时间段 if (empty($startDate) || empty($endDate)) { return null; } $startTime = strtotime($startDate . ' 00:00:00'); $endTime = strtotime($endDate . ' 23:59:59'); if ($startTime === false || $endTime === false || $startTime > $endTime) { return null; } return [ 'start_time' => $startTime, 'end_time' => $endTime, ]; default: return null; } } // 佣金转余额/提现 public function transfer() { $amount = $this->request->param('amount'); if ($amount <= 0) { $this->error('请输入正确的金额'); } $agent = $this->service->agent; if (!$agent) { $this->error('您还不是分销商'); } // 使用BcMath工具类检查可提现余额(累计收益 - 已提现金额) $totalIncome = $agent->total_income ?? '0.00'; $withdrawnAmount = $agent->withdrawn_amount ?? '0.00'; $requestAmount = BcMath::format($amount); $availableBalance = BcMath::sub($totalIncome, $withdrawnAmount); // 使用BcMath比较函数检查余额是否足够 if (BcMath::comp($requestAmount, $availableBalance) > 0) { $this->error('提现金额超过可用余额,可用余额:' . $availableBalance . '元'); } Db::transaction(function () use ($amount, $agent) { $user = auth_user(); // 转账到用户余额 Wallet::change($user, 'money', $amount, 'commission_withdraw'); // 更新代理商的已提现金额 AgentModel::where('user_id', $user->id)->setInc('withdrawn_amount', $amount); }); $this->success('提现成功'); } /** * 生成分销海报微信小程序码 */ public function posterQrcode() { // 验证当前用户是否为分销商 $agent = $this->service->agent; if (!$agent) { $this->error('您还不是分销商'); } // 获取当前用户ID作为分享者 $shareUserId = $this->service->user->id; // 从请求头获取platform参数 $requestPlatform = $this->request->header('platform', ''); if (!$requestPlatform) { $this->error('缺少platform参数'); } // 将ChannelEnum映射到ShareEnum平台常量 $shareEnumPlatform = $this->mapChannelToSharePlatform($requestPlatform); // 使用ShareEnum获取平台ID (1=H5,2=微信公众号网页,3=微信小程序,4=App) $platformId = ShareEnum::getPlatformId($shareEnumPlatform); $fromPlatformId = $platformId; // 来源平台同当前平台 $commissionConfig = ShopConfigService::getConfigs('shop.commission'); // try { // 初始化微信服务 - 固定使用微信小程序平台生成小程序码 $wechatPlatform = ChannelEnum::CHANNEL_WECHAT_MINI_PROGRAM; $payload = []; $wechat = new WechatService($wechatPlatform, $payload); $mp = $wechat->getApp(); // 构造spm参数: shareId.page.query.platform.from // shareId: 分享者用户ID // page: 页面类型 (分销海报页面 = 6) // query: 代理商ID (使用分享者ID) // platform: 从请求头获取的平台ID // from: 来源平台ID $spmParams = sprintf('%s.%s.%s.%s.%s', $shareUserId, PageTypeEnum::AGENT_POSTER, $shareUserId, $platformId, // 使用映射后的平台ID $fromPlatformId // 来源平台ID ); // 固定跳转到分销海报页面,携带smp参数和邀请码 $page = 'pages/index/index'; // 分销海报页面路径 //$scene = 'spm=' . $spmParams . '&invite_code=' . $agent->invite_code; $scene = 'invite_code=' . $agent->invite_code; // 生成小程序码 $content = $mp->app_code->getUnlimit($scene, [ 'page' => $page, 'is_hyaline' => false, 'env_version' => 'trial', 'check_path' => false ]); if ($content instanceof \EasyWeChat\Kernel\Http\StreamResponse) { // 将小程序码转换为base64 $qrcodeBase64 = base64_encode($content->getBody()); // 构建返回数据 $result = [ 'qrcode_base64' => 'data:image/png;base64,' . $qrcodeBase64, 'invite_code' =>$agent->invite_code? $agent->invite_code : '', 'poster_background' => !empty($commissionConfig['poster_background_image']) ? cdnurl($commissionConfig['poster_background_image'], true) : '', ]; $this->success('生成成功', $result); } else { // 小程序码获取失败 $msg = $content['errcode'] ?? '-'; $msg .= $content['errmsg'] ?? ''; $this->error('小程序码生成失败:' . $msg); } // } catch (\Exception $e) { // $this->error('小程序码生成失败:' . $e->getMessage()); // } } /** * 将ChannelEnum的平台常量映射到ShareEnum的平台常量 * @param string $channelPlatform ChannelEnum平台常量 * @return string ShareEnum平台常量 */ private function mapChannelToSharePlatform($channelPlatform) { $channelToShareMap = [ ChannelEnum::CHANNEL_H5 => ShareEnum::PLATFORM_H5, ChannelEnum::CHANNEL_WECHAT_OFFICIAL_ACCOUNT => ShareEnum::PLATFORM_WECHAT_OFFICIAL_ACCOUNT, ChannelEnum::CHANNEL_WECHAT_MINI_PROGRAM => ShareEnum::PLATFORM_WECHAT_MINI_PROGRAM, ChannelEnum::CHANNEL_IOS_APP => ShareEnum::PLATFORM_APP, ChannelEnum::CHANNEL_ANDROID_APP => ShareEnum::PLATFORM_APP, ]; return $channelToShareMap[$channelPlatform] ?? ShareEnum::PLATFORM_WECHAT_MINI_PROGRAM; // 默认微信小程序 } }