request->param('name', ''); $phone = $this->request->param('phone', ''); $wechatId = $this->request->param('wechatId', ''); $remarks = $this->request->param('remarks', ''); $createType = $this->request->param('createType', DistributionChannel::CREATE_TYPE_MANUAL); // 默认为手动创建 $companyId = $this->getUserInfo('companyId'); // 参数验证 if (empty($name)) { return ResponseHelper::error('渠道名称不能为空', 400); } // 验证渠道名称长度 if (mb_strlen($name) > 50) { return ResponseHelper::error('渠道名称长度不能超过50个字符', 400); } // 验证手机号格式(如果提供) if (!empty($phone)) { if (!preg_match('/^1[3-9]\d{9}$/', $phone)) { return ResponseHelper::error('手机号格式不正确,请输入11位数字且以1开头', 400); } // 检查手机号是否已存在(排除已删除的渠道) $existChannel = Db::name('distribution_channel') ->where([ ['companyId', '=', $companyId], ['phone', '=', $phone], ['deleteTime', '=', 0] ]) ->find(); if ($existChannel) { return ResponseHelper::error('手机号已被使用', 400); } } // 验证微信号长度(如果提供) if (!empty($wechatId) && mb_strlen($wechatId) > 50) { return ResponseHelper::error('微信号长度不能超过50个字符', 400); } // 验证备注长度(如果提供) if (!empty($remarks) && mb_strlen($remarks) > 200) { return ResponseHelper::error('备注信息长度不能超过200个字符', 400); } // 验证创建类型 if (!in_array($createType, [DistributionChannel::CREATE_TYPE_MANUAL, DistributionChannel::CREATE_TYPE_AUTO])) { $createType = DistributionChannel::CREATE_TYPE_MANUAL; } // 生成渠道编码 $code = DistributionChannel::generateChannelCode(); // 准备插入数据 $data = [ 'companyId' => $companyId, 'name' => $name, 'code' => $code, 'phone' => $phone ?: '', 'password' => md5('123456'), // 默认密码123456,MD5加密 'wechatId' => $wechatId ?: '', 'remarks' => $remarks ?: '', 'createType' => $createType, 'status' => DistributionChannel::STATUS_ENABLED, 'totalCustomers' => 0, 'todayCustomers' => 0, 'totalFriends' => 0, 'todayFriends' => 0, 'withdrawableAmount' => 0, // 以分为单位存储 'createTime' => time(), 'updateTime' => time(), ]; // 插入数据库 $channelId = Db::name('distribution_channel')->insertGetId($data); if (!$channelId) { return ResponseHelper::error('创建渠道失败', 500); } // 获取创建的数据 $channel = Db::name('distribution_channel')->where('id', $channelId)->find(); // 格式化返回数据 $result = [ 'id' => $channel['id'], 'name' => $channel['name'], 'code' => $channel['code'], 'phone' => $channel['phone'] ?: '', 'wechatId' => $channel['wechatId'] ?: '', 'createType' => $channel['createType'], 'status' => $channel['status'], 'totalCustomers' => (int)$channel['totalCustomers'], 'todayCustomers' => (int)$channel['todayCustomers'], 'totalFriends' => (int)$channel['totalFriends'], 'todayFriends' => (int)$channel['todayFriends'], 'withdrawableAmount' => round(($channel['withdrawableAmount'] ?? 0) / 100, 2), // 分转元,保留2位小数 'createTime' => !empty($channel['createTime']) ? date('Y-m-d H:i:s', $channel['createTime']) : date('Y-m-d H:i:s'), ]; // 返回符合需求的格式(包含success字段) return json([ 'code' => 200, 'success' => true, 'msg' => '创建成功', 'data' => $result ]); } catch (Exception $e) { return ResponseHelper::error('创建渠道失败:' . $e->getMessage(), $e->getCode() ?: 500); } } /** * 获取渠道列表 * @return \think\response\Json */ public function index() { try { // 获取参数 $page = $this->request->param('page', 1); $limit = $this->request->param('limit', 20); $keyword = $this->request->param('keyword', ''); $status = $this->request->param('status', 'all'); // all、enabled、disabled $companyId = $this->getUserInfo('companyId'); // 参数验证 $page = max(1, intval($page)); $limit = max(1, min(100, intval($limit))); // 限制最大100 // 验证状态参数 $validStatuses = ['all', DistributionChannel::STATUS_ENABLED, DistributionChannel::STATUS_DISABLED]; if (!in_array($status, $validStatuses)) { $status = 'all'; } // 构建查询条件 $where = []; $where[] = ['companyId', '=', $companyId]; $where[] = ['deleteTime', '=', 0]; // 状态筛选 if ($status !== 'all') { $where[] = ['status', '=', $status]; } // 关键词搜索(模糊匹配 name、code、phone、wechatId) if (!empty($keyword)) { $keyword = trim($keyword); // 使用 | 分隔字段表示OR关系(ThinkPHP语法) $where[] = ['name|code|phone|wechatId', 'like', '%' . $keyword . '%']; } // 查询总数 $total = Db::name('distribution_channel') ->where($where) ->count(); // 查询列表(按创建时间倒序) $list = Db::name('distribution_channel') ->where($where) ->order('createTime DESC') ->page($page, $limit) ->select(); // 格式化数据 $formattedList = []; foreach ($list as $item) { $formattedItem = [ 'id' => (int)$item['id'], 'name' => $item['name'] ?? '', 'code' => $item['code'] ?? '', 'phone' => !empty($item['phone']) ? $item['phone'] : null, 'wechatId' => !empty($item['wechatId']) ? $item['wechatId'] : null, 'createType' => $item['createType'] ?? 'manual', 'status' => $item['status'] ?? 'enabled', 'totalCustomers' => (int)($item['totalCustomers'] ?? 0), 'todayCustomers' => (int)($item['todayCustomers'] ?? 0), 'totalFriends' => (int)($item['totalFriends'] ?? 0), 'todayFriends' => (int)($item['todayFriends'] ?? 0), 'withdrawableAmount' => round(($item['withdrawableAmount'] ?? 0) / 100, 2), // 分转元,保留2位小数 'createTime' => !empty($item['createTime']) ? date('Y-m-d H:i:s', $item['createTime']) : date('Y-m-d H:i:s'), ]; $formattedList[] = $formattedItem; } // 返回结果 return json([ 'code' => 200, 'success' => true, 'msg' => '获取成功', 'data' => [ 'list' => $formattedList, 'total' => (int)$total ] ]); } catch (Exception $e) { return json([ 'code' => $e->getCode() ?: 500, 'success' => false, 'msg' => '获取渠道列表失败:' . $e->getMessage(), 'data' => null ]); } } /** * 编辑渠道 * @return \think\response\Json */ public function update() { try { // 获取参数 $id = $this->request->param('id', 0); $name = $this->request->param('name', ''); $phone = $this->request->param('phone', ''); $wechatId = $this->request->param('wechatId', ''); $remarks = $this->request->param('remarks', ''); $companyId = $this->getUserInfo('companyId'); // 参数验证 if (empty($id)) { return json([ 'code' => 400, 'success' => false, 'msg' => '渠道ID不能为空', 'data' => null ]); } // 检查渠道是否存在且属于当前公司 $channel = Db::name('distribution_channel') ->where(['id' => $id, 'companyId' => $companyId, 'deleteTime' => 0]) ->find(); if (!$channel) { return json([ 'code' => 404, 'success' => false, 'msg' => '渠道不存在或没有权限', 'data' => null ]); } // 准备更新数据 $updateData = []; $updateData['updateTime'] = time(); // 更新渠道名称 if (!empty($name)) { if (mb_strlen($name) > 50) { return json([ 'code' => 400, 'success' => false, 'msg' => '渠道名称长度不能超过50个字符', 'data' => null ]); } $updateData['name'] = $name; } // 更新手机号 if (isset($phone)) { // 允许设置为空 if (!empty($phone)) { if (!preg_match('/^1[3-9]\d{9}$/', $phone)) { return json([ 'code' => 400, 'success' => false, 'msg' => '手机号格式不正确,请输入11位数字且以1开头', 'data' => null ]); } // 检查手机号是否已被其他渠道使用(排除当前渠道和已删除的渠道) $existChannel = Db::name('distribution_channel') ->where([ ['companyId', '=', $companyId], ['phone', '=', $phone], ['id', '<>', $id], ['deleteTime', '=', 0] ]) ->find(); if ($existChannel) { return json([ 'code' => 400, 'success' => false, 'msg' => '手机号已被其他渠道使用', 'data' => null ]); } } $updateData['phone'] = $phone ?: ''; } // 更新微信号 if (isset($wechatId)) { // 允许设置为空 if (!empty($wechatId) && mb_strlen($wechatId) > 50) { return json([ 'code' => 400, 'success' => false, 'msg' => '微信号长度不能超过50个字符', 'data' => null ]); } $updateData['wechatId'] = $wechatId ?: ''; } // 更新备注 if (isset($remarks)) { // 允许设置为空 if (!empty($remarks) && mb_strlen($remarks) > 200) { return json([ 'code' => 400, 'success' => false, 'msg' => '备注信息长度不能超过200个字符', 'data' => null ]); } $updateData['remarks'] = $remarks ?: ''; } // 如果没有要更新的数据 if (count($updateData) <= 1) { // 只有updateTime return json([ 'code' => 400, 'success' => false, 'msg' => '没有要更新的数据', 'data' => null ]); } // 更新数据库 $result = Db::name('distribution_channel') ->where(['id' => $id, 'companyId' => $companyId]) ->update($updateData); if ($result === false) { return json([ 'code' => 500, 'success' => false, 'msg' => '更新渠道失败', 'data' => null ]); } // 获取更新后的数据 $updatedChannel = Db::name('distribution_channel') ->where('id', $id) ->find(); // 格式化返回数据 $resultData = [ 'id' => (int)$updatedChannel['id'], 'name' => $updatedChannel['name'], 'code' => $updatedChannel['code'], 'phone' => !empty($updatedChannel['phone']) ? $updatedChannel['phone'] : null, 'wechatId' => !empty($updatedChannel['wechatId']) ? $updatedChannel['wechatId'] : null, 'createType' => $updatedChannel['createType'], 'status' => $updatedChannel['status'], 'totalCustomers' => (int)$updatedChannel['totalCustomers'], 'todayCustomers' => (int)$updatedChannel['todayCustomers'], 'totalFriends' => (int)$updatedChannel['totalFriends'], 'todayFriends' => (int)$updatedChannel['todayFriends'], 'withdrawableAmount' => round(($updatedChannel['withdrawableAmount'] ?? 0) / 100, 2), // 分转元,保留2位小数 'createTime' => !empty($updatedChannel['createTime']) ? date('Y-m-d H:i:s', $updatedChannel['createTime']) : date('Y-m-d H:i:s'), ]; return json([ 'code' => 200, 'success' => true, 'msg' => '更新成功', 'data' => $resultData ]); } catch (Exception $e) { return json([ 'code' => $e->getCode() ?: 500, 'success' => false, 'msg' => '更新渠道失败:' . $e->getMessage(), 'data' => null ]); } } /** * 删除渠道(软删除) * @return \think\response\Json */ public function delete() { try { // 获取参数 $id = $this->request->param('id', 0); $companyId = $this->getUserInfo('companyId'); // 参数验证 if (empty($id)) { return json([ 'code' => 400, 'success' => false, 'msg' => '渠道ID不能为空', 'data' => null ]); } // 检查渠道是否存在且属于当前公司 $channel = Db::name('distribution_channel') ->where(['id' => $id, 'companyId' => $companyId, 'deleteTime' => 0]) ->find(); if (!$channel) { return json([ 'code' => 404, 'success' => false, 'msg' => '渠道不存在或没有权限', 'data' => null ]); } // 软删除 $result = Db::name('distribution_channel') ->where(['id' => $id, 'companyId' => $companyId]) ->update([ 'deleteTime' => time(), 'updateTime' => time() ]); if ($result === false) { return json([ 'code' => 500, 'success' => false, 'msg' => '删除渠道失败', 'data' => null ]); } return json([ 'code' => 200, 'success' => true, 'msg' => '删除成功', 'data' => null ]); } catch (Exception $e) { return json([ 'code' => $e->getCode() ?: 500, 'success' => false, 'msg' => '删除渠道失败:' . $e->getMessage(), 'data' => null ]); } } /** * 禁用/启用渠道 * @return \think\response\Json */ public function toggleStatus() { try { // 获取参数 $id = $this->request->param('id', 0); $status = $this->request->param('status', ''); // enabled 或 disabled $companyId = $this->getUserInfo('companyId'); // 参数验证 if (empty($id)) { return json([ 'code' => 400, 'success' => false, 'msg' => '渠道ID不能为空', 'data' => null ]); } if (!in_array($status, [DistributionChannel::STATUS_ENABLED, DistributionChannel::STATUS_DISABLED])) { return json([ 'code' => 400, 'success' => false, 'msg' => '状态参数错误,必须为 enabled 或 disabled', 'data' => null ]); } // 检查渠道是否存在且属于当前公司 $channel = Db::name('distribution_channel') ->where(['id' => $id, 'companyId' => $companyId, 'deleteTime' => 0]) ->find(); if (!$channel) { return json([ 'code' => 404, 'success' => false, 'msg' => '渠道不存在或没有权限', 'data' => null ]); } // 如果状态相同,直接返回成功 if ($channel['status'] === $status) { $msg = $status === DistributionChannel::STATUS_ENABLED ? '渠道已启用' : '渠道已禁用'; return json([ 'code' => 200, 'success' => true, 'msg' => $msg, 'data' => null ]); } // 更新状态 $result = Db::name('distribution_channel') ->where(['id' => $id, 'companyId' => $companyId]) ->update([ 'status' => $status, 'updateTime' => time() ]); if ($result === false) { return json([ 'code' => 500, 'success' => false, 'msg' => '更新状态失败', 'data' => null ]); } $msg = $status === DistributionChannel::STATUS_ENABLED ? '启用成功' : '禁用成功'; return json([ 'code' => 200, 'success' => true, 'msg' => $msg, 'data' => [ 'id' => (int)$id, 'status' => $status ] ]); } catch (Exception $e) { return json([ 'code' => $e->getCode() ?: 500, 'success' => false, 'msg' => '更新状态失败:' . $e->getMessage(), 'data' => null ]); } } /** * 获取渠道统计数据 * @return \think\response\Json */ public function statistics() { try { $companyId = $this->getUserInfo('companyId'); // 获取今日开始和结束时间戳 $todayStart = strtotime(date('Y-m-d 00:00:00')); $todayEnd = strtotime(date('Y-m-d 23:59:59')); // 构建基础查询条件 $baseWhere = [ ['companyId', '=', $companyId], ['deleteTime', '=', 0] ]; // 1. 总渠道数 $totalChannels = Db::name('distribution_channel') ->where($baseWhere) ->count(); // 2. 今日新增渠道数 $todayChannels = Db::name('distribution_channel') ->where($baseWhere) ->where('createTime', 'between', [$todayStart, $todayEnd]) ->count(); // 3. 统计所有渠道的获客数和加好友数(使用聚合函数) $statistics = Db::name('distribution_channel') ->where($baseWhere) ->field([ 'SUM(totalCustomers) as totalCustomers', 'SUM(todayCustomers) as todayCustomers', 'SUM(totalFriends) as totalFriends', 'SUM(todayFriends) as todayFriends' ]) ->find(); // 格式化统计数据 $data = [ 'totalChannels' => (int)$totalChannels, 'todayChannels' => (int)$todayChannels, 'totalCustomers' => (int)($statistics['totalCustomers'] ?? 0), 'todayCustomers' => (int)($statistics['todayCustomers'] ?? 0), 'totalFriends' => (int)($statistics['totalFriends'] ?? 0), 'todayFriends' => (int)($statistics['todayFriends'] ?? 0), ]; return json([ 'code' => 200, 'msg' => '获取成功', 'data' => $data ]); } catch (Exception $e) { return json([ 'code' => $e->getCode() ?: 500, 'msg' => '获取统计数据失败:' . $e->getMessage(), 'data' => null ]); } } /** * 获取渠道收益统计(全局统计) * @return \think\response\Json */ public function revenueStatistics() { try { $companyId = $this->getUserInfo('companyId'); // 构建基础查询条件 $baseWhere = [ ['companyId', '=', $companyId] ]; // 1. 总支出:所有已打款的提现申请金额总和(状态为paid) $totalExpenditure = Db::name('distribution_withdrawal') ->where($baseWhere) ->where('status', DistributionWithdrawal::STATUS_PAID) ->sum('amount'); $totalExpenditure = intval($totalExpenditure ?? 0); // 2. 已提现:所有已打款的提现申请金额总和(状态为paid) $withdrawn = $totalExpenditure; // 已提现 = 总支出 // 3. 待审核:所有待审核的提现申请金额总和(状态为pending) $pendingReview = Db::name('distribution_withdrawal') ->where($baseWhere) ->where('status', DistributionWithdrawal::STATUS_PENDING) ->sum('amount'); $pendingReview = intval($pendingReview ?? 0); // 格式化返回数据(分转元) $data = [ 'totalExpenditure' => round($totalExpenditure / 100, 2), // 总支出(元) 'withdrawn' => round($withdrawn / 100, 2), // 已提现(元) 'pendingReview' => round($pendingReview / 100, 2), // 待审核(元) ]; return json([ 'code' => 200, 'success' => true, 'msg' => '获取成功', 'data' => $data ]); } catch (Exception $e) { return json([ 'code' => $e->getCode() ?: 500, 'success' => false, 'msg' => '获取收益统计失败:' . $e->getMessage(), 'data' => null ]); } } /** * 获取渠道收益明细列表(多个渠道的统计) * @return \think\response\Json */ public function revenueDetail() { try { // 获取参数 $page = $this->request->param('page', 1); $limit = $this->request->param('limit', 20); $keyword = $this->request->param('keyword', ''); $companyId = $this->getUserInfo('companyId'); // 参数验证 $page = max(1, intval($page)); $limit = max(1, min(100, intval($limit))); // 限制最大100 // 构建查询条件 $where = []; $where[] = ['companyId', '=', $companyId]; $where[] = ['deleteTime', '=', 0]; // 关键词搜索(模糊匹配 name、code) if (!empty($keyword)) { $keyword = trim($keyword); $where[] = ['name|code', 'like', '%' . $keyword . '%']; } // 查询总数 $total = Db::name('distribution_channel') ->where($where) ->count(); // 查询渠道列表(按创建时间倒序) $channels = Db::name('distribution_channel') ->where($where) ->order('createTime DESC') ->page($page, $limit) ->select(); // 批量获取所有渠道的提现统计数据(提高性能) $channelIds = array_column($channels, 'id'); $withdrawalStats = []; if (!empty($channelIds)) { // 按渠道ID和状态分组统计提现金额 $stats = Db::name('distribution_withdrawal') ->where([ ['companyId', '=', $companyId], ['channelId', 'in', $channelIds] ]) ->field([ 'channelId', 'status', 'SUM(amount) as totalAmount' ]) ->group('channelId, status') ->select(); // 组织统计数据 foreach ($stats as $stat) { $cid = $stat['channelId']; if (!isset($withdrawalStats[$cid])) { $withdrawalStats[$cid] = [ 'totalRevenue' => 0, // 所有状态的总金额 'withdrawn' => 0, // 已打款(paid) 'pendingReview' => 0 // 待审核(pending) ]; } $amount = intval($stat['totalAmount'] ?? 0); $withdrawalStats[$cid]['totalRevenue'] += $amount; if ($stat['status'] === DistributionWithdrawal::STATUS_PAID) { $withdrawalStats[$cid]['withdrawn'] += $amount; } elseif ($stat['status'] === DistributionWithdrawal::STATUS_PENDING) { $withdrawalStats[$cid]['pendingReview'] += $amount; } } } // 格式化数据 $formattedList = []; foreach ($channels as $channel) { $channelId = $channel['id']; $stats = $withdrawalStats[$channelId] ?? [ 'totalRevenue' => 0, 'withdrawn' => 0, 'pendingReview' => 0 ]; // 可提现金额:渠道的withdrawableAmount $withdrawableAmount = intval($channel['withdrawableAmount'] ?? 0); $formattedItem = [ 'channelId' => (string)$channelId, 'channelName' => $channel['name'] ?? '', 'channelCode' => $channel['code'] ?? '', 'totalRevenue' => round($stats['totalRevenue'] / 100, 2), // 总收益(元) 'withdrawable' => round($withdrawableAmount / 100, 2), // 可提现(元) 'withdrawn' => round($stats['withdrawn'] / 100, 2), // 已提现(元) 'pendingReview' => round($stats['pendingReview'] / 100, 2), // 待审核(元) ]; $formattedList[] = $formattedItem; } // 返回结果 return json([ 'code' => 200, 'success' => true, 'msg' => '获取成功', 'data' => [ 'list' => $formattedList, 'total' => (int)$total ] ]); } catch (Exception $e) { return json([ 'code' => $e->getCode() ?: 500, 'success' => false, 'msg' => '获取收益明细失败:' . $e->getMessage(), 'data' => null ]); } } /** * 生成渠道二维码(H5或小程序码) * @return \think\response\Json */ public function generateQrCode() { try { // 获取参数 $type = $this->request->param('type', 'h5'); // h5 或 miniprogram $companyId = $this->getUserInfo('companyId'); // 参数验证 if (!in_array($type, ['h5', 'miniprogram'])) { return json([ 'code' => 400, 'success' => false, 'msg' => '类型参数错误,必须为 h5 或 miniprogram', 'data' => null ]); } // 生成临时token(只包含公司ID,有效期24小时) // 用户扫码后需要自己填写所有信息 $tokenData = [ 'companyId' => $companyId, 'expireTime' => time() + 86400 // 24小时后过期 ]; $token = base64_encode(json_encode($tokenData)); if ($type === 'h5') { // 生成H5二维码 // 获取H5页面URL(需要根据实际项目配置) $h5BaseUrl = Env::get('h5.base_url', $this->request->domain()); // 确保URL格式正确(去除末尾斜杠) $h5BaseUrl = rtrim($h5BaseUrl, '/'); $h5Url = $h5BaseUrl . '/pages/channel/add?token=' . urlencode($token); // 生成二维码 $qrCode = new QrCode($h5Url); $qrCode->setSize(300); $qrCode->setMargin(10); $qrCode->setWriterByName('png'); $qrCode->setEncoding('UTF-8'); $qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH); // 转换为base64 $qrCodeBase64 = 'data:image/png;base64,' . base64_encode($qrCode->writeString()); return json([ 'code' => 200, 'success' => true, 'msg' => '生成H5二维码成功', 'data' => [ 'type' => 'h5', 'qrCode' => $qrCodeBase64, 'url' => $h5Url ] ]); } else { // 生成小程序码 try { // 从环境变量获取小程序配置 $miniProgramConfig = [ 'app_id' => Env::get('weChat.appidMiniApp', 'wx789850448e26c91d'), 'secret' => Env::get('weChat.secretMiniApp', 'd18f75b3a3623cb40da05648b08365a1'), 'response_type' => 'array' ]; $app = Factory::miniProgram($miniProgramConfig); // scene参数长度限制为32位,使用token的MD5值 $scene = substr(md5($token), 0, 32); // 调用接口生成小程序码 $response = $app->app_code->getUnlimit($scene, [ 'page' => 'pages/distribution/register', // 小程序页面路径,需要根据实际项目调整 'width' => 430, // 二维码的宽度 ]); // 成功时返回的是 StreamResponse,失败时通常返回数组(包含 errcode/errmsg) if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) { $img = $response->getBody()->getContents(); $imgBase64 = 'data:image/png;base64,' . base64_encode($img); return json([ 'code' => 200, 'success' => true, 'msg' => '生成小程序码成功', 'data' => [ 'type' => 'miniprogram', 'qrCode' => $imgBase64, 'scene' => $scene, // 返回scene供小程序端使用 'token' => $token // 返回token,小程序端可以通过scene查询 ] ]); } // 如果不是流响应,而是数组(错误信息),则解析错误返回 if (is_array($response) && isset($response['errcode']) && $response['errcode'] != 0) { $errMsg = isset($response['errmsg']) ? $response['errmsg'] : '微信接口返回错误'; return json([ 'code' => 500, 'success' => false, 'msg' => '生成小程序码失败:' . $errMsg, 'data' => $response ]); } // 其他未知格式 return json([ 'code' => 500, 'success' => false, 'msg' => '生成小程序码失败:响应格式错误', 'data' => $response ]); } catch (\Exception $e) { return json([ 'code' => 500, 'success' => false, 'msg' => '生成小程序码失败:' . $e->getMessage(), 'data' => null ]); } } } catch (Exception $e) { return json([ 'code' => $e->getCode() ?: 500, 'success' => false, 'msg' => '生成二维码失败:' . $e->getMessage(), 'data' => null ]); } } /** * 扫码提交渠道信息(H5和小程序共用) * GET请求:返回预填信息 * POST请求:提交渠道信息 * @return \think\response\Json */ public function registerByQrCode() { try { // 获取参数 $token = $this->request->param('token', ''); // 参数验证 if (empty($token)) { return json([ 'code' => 400, 'success' => false, 'msg' => 'token不能为空', 'data' => null ]); } // 解析token $tokenData = json_decode(base64_decode($token), true); if (!$tokenData || !isset($tokenData['companyId'])) { return json([ 'code' => 400, 'success' => false, 'msg' => 'token无效', 'data' => null ]); } // 检查token是否过期 if (isset($tokenData['expireTime']) && $tokenData['expireTime'] < time()) { return json([ 'code' => 400, 'success' => false, 'msg' => '二维码已过期,请重新生成', 'data' => null ]); } $companyId = $tokenData['companyId']; // GET请求:返回token验证成功信息(前端可以显示表单) if ($this->request->isGet()) { return json([ 'code' => 200, 'success' => true, 'msg' => 'token验证成功', 'data' => [ 'valid' => true ] ]); } // POST请求:提交渠道信息(所有信息都需要用户填写) $name = $this->request->param('name', ''); $phone = $this->request->param('phone', ''); $wechatId = $this->request->param('wechatId', ''); $remarks = $this->request->param('remarks', ''); // 参数验证 if (empty($name)) { return json([ 'code' => 400, 'success' => false, 'msg' => '渠道名称不能为空', 'data' => null ]); } // 验证渠道名称长度 if (mb_strlen($name) > 50) { return json([ 'code' => 400, 'success' => false, 'msg' => '渠道名称长度不能超过50个字符', 'data' => null ]); } // 验证手机号格式(如果提供) if (!empty($phone)) { if (!preg_match('/^1[3-9]\d{9}$/', $phone)) { return json([ 'code' => 400, 'success' => false, 'msg' => '手机号格式不正确,请输入11位数字且以1开头', 'data' => null ]); } // 检查手机号是否已存在(排除已删除的渠道) $existChannel = Db::name('distribution_channel') ->where([ ['companyId', '=', $companyId], ['phone', '=', $phone], ['deleteTime', '=', 0] ]) ->find(); if ($existChannel) { return json([ 'code' => 400, 'success' => false, 'msg' => '手机号已被使用', 'data' => null ]); } } // 验证微信号长度(如果提供) if (!empty($wechatId) && mb_strlen($wechatId) > 50) { return json([ 'code' => 400, 'success' => false, 'msg' => '微信号长度不能超过50个字符', 'data' => null ]); } // 验证备注长度(如果提供) if (!empty($remarks) && mb_strlen($remarks) > 200) { return json([ 'code' => 400, 'success' => false, 'msg' => '备注信息长度不能超过200个字符', 'data' => null ]); } // 生成渠道编码 $code = DistributionChannel::generateChannelCode(); // 准备插入数据 $data = [ 'companyId' => $companyId, 'name' => $name, 'code' => $code, 'phone' => $phone ?: '', 'password' => md5('123456'), // 默认密码123456,MD5加密 'wechatId' => $wechatId ?: '', 'remarks' => $remarks ?: '', 'createType' => DistributionChannel::CREATE_TYPE_AUTO, // 扫码创建 'status' => DistributionChannel::STATUS_ENABLED, 'totalCustomers' => 0, 'todayCustomers' => 0, 'totalFriends' => 0, 'todayFriends' => 0, 'withdrawableAmount' => 0, // 以分为单位存储 'createTime' => time(), 'updateTime' => time(), ]; // 插入数据库 $channelId = Db::name('distribution_channel')->insertGetId($data); if (!$channelId) { return json([ 'code' => 500, 'success' => false, 'msg' => '创建渠道失败', 'data' => null ]); } // 获取创建的数据 $channel = Db::name('distribution_channel')->where('id', $channelId)->find(); // 格式化返回数据 $result = [ 'id' => (string)$channel['id'], 'name' => $channel['name'], 'code' => $channel['code'], 'phone' => $channel['phone'] ?: '', 'wechatId' => $channel['wechatId'] ?: '', 'createType' => $channel['createType'], 'status' => $channel['status'], 'totalCustomers' => (int)$channel['totalCustomers'], 'todayCustomers' => (int)$channel['todayCustomers'], 'totalFriends' => (int)$channel['totalFriends'], 'todayFriends' => (int)$channel['todayFriends'], 'withdrawableAmount' => round(($channel['withdrawableAmount'] ?? 0) / 100, 2), // 分转元,保留2位小数 'createTime' => !empty($channel['createTime']) ? date('Y-m-d H:i:s', $channel['createTime']) : date('Y-m-d H:i:s'), ]; return json([ 'code' => 200, 'success' => true, 'msg' => '渠道注册成功', 'data' => $result ]); } catch (Exception $e) { return json([ 'code' => $e->getCode() ?: 500, 'success' => false, 'msg' => '渠道注册失败:' . $e->getMessage(), 'data' => null ]); } } }