diff --git a/Server/application/superadmin/config/route.php b/Server/application/superadmin/config/route.php index 4127e142..71436418 100644 --- a/Server/application/superadmin/config/route.php +++ b/Server/application/superadmin/config/route.php @@ -27,6 +27,7 @@ Route::group('', function () { // 客户池管理路由 Route::group('trafficPool', function () { - Route::get('list', 'app\\superadmin\\controller\\TrafficPool@getList'); + Route::get('list', 'app\\superadmin\\controller\\TrafficPool@getList'); // 获取客户池列表 + Route::get('detail', 'app\\superadmin\\controller\\TrafficPool@getDetail'); // 获取客户详情 }); })->middleware(['app\\superadmin\\middleware\\AdminAuth']); \ No newline at end of file diff --git a/Server/application/superadmin/controller/TrafficPool.php b/Server/application/superadmin/controller/TrafficPool.php index 6f53170a..27ccd022 100644 --- a/Server/application/superadmin/controller/TrafficPool.php +++ b/Server/application/superadmin/controller/TrafficPool.php @@ -2,8 +2,14 @@ namespace app\superadmin\controller; use app\superadmin\model\TrafficPool as TrafficPoolModel; +use app\superadmin\model\TrafficSource; +use app\superadmin\model\Company; +use app\superadmin\model\WechatAccount; +use app\superadmin\model\WechatTag; use think\Controller; use think\facade\Request; +use think\facade\Session; +use think\facade\Validate; /** * 客户池控制器 @@ -80,4 +86,122 @@ class TrafficPool extends Controller ] ]); } + + /** + * 获取客户详情 + * @return \think\response\Json + */ + public function getDetail() + { + // 获取参数 + $id = Request::param('id/d'); + if (!$id) { + return json(['code' => 400, 'msg' => '参数错误']); + } + + try { + // 查询流量来源信息 + $sourceInfo = TrafficSource::alias('ts') + ->join('company c', 'ts.companyId = c.id', 'LEFT') + ->field([ + 'ts.fromd as source', + 'ts.createTime as addTime', + 'c.name as projectName', + 'ts.identifier' + ]) + ->where('ts.id', $id) + ->find(); + + if (!$sourceInfo) { + return json(['code' => 404, 'msg' => '记录不存在']); + } + + // 查询客户池信息 + $poolInfo = TrafficPoolModel::where('identifier', $sourceInfo['identifier']) + ->field('wechatId') + ->find(); + + $result = [ + 'source' => $sourceInfo['source'], + 'addTime' => $sourceInfo['addTime'], + 'projectName' => $sourceInfo['projectName'] + ]; + + // 如果存在微信ID,查询微信账号信息 + if ($poolInfo && $poolInfo['wechatId']) { + // 查询微信账号信息 + $wechatInfo = WechatAccount::where('wechatId', $poolInfo['wechatId']) + ->field('avatar,nickname,region,gender') + ->find(); + + if ($wechatInfo) { + $result = array_merge($result, [ + 'avatar' => $wechatInfo['avatar'], + 'nickname' => $wechatInfo['nickname'], + 'region' => $wechatInfo['region'], + 'gender' => $this->formatGender($wechatInfo['gender']) + ]); + + // 查询标签信息 + $tagInfo = WechatTag::where('wechatId', $poolInfo['wechatId']) + ->field('tags') + ->find(); + + if ($tagInfo) { + $result['tags'] = is_string($tagInfo['tags']) ? + json_decode($tagInfo['tags'], true) : + $tagInfo['tags']; + } else { + $result['tags'] = []; + } + } + } else { + $result = array_merge($result, [ + 'avatar' => '', + 'nickname' => '未知', + 'region' => '未知', + 'gender' => $this->formatGender(0), + 'tags' => [] + ]); + } + + return json([ + 'code' => 200, + 'msg' => '获取成功', + 'data' => $result + ]); + + } catch (\Exception $e) { + return json([ + 'code' => 500, + 'msg' => '系统错误:' . $e->getMessage() + ]); + } + } + + /** + * 格式化性别显示 + * @param int $gender + * @return string + */ + protected function formatGender($gender) + { + switch($gender) { + case 1: + return '男'; + case 2: + return '女'; + default: + return '保密'; + } + } + + /** + * 检查登录状态 + * @return bool + */ + protected function checkLogin() + { + return Session::has('admin_id'); + } } \ No newline at end of file diff --git a/SuperAdmin/app/dashboard/customers/page.tsx b/SuperAdmin/app/dashboard/customers/page.tsx index 478bd3e1..e966abc7 100644 --- a/SuperAdmin/app/dashboard/customers/page.tsx +++ b/SuperAdmin/app/dashboard/customers/page.tsx @@ -13,7 +13,7 @@ import { DropdownMenuSeparator, } from "@/components/ui/dropdown-menu" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" -import { Search, MoreHorizontal, Eye, UserPlus, Filter, ChevronLeft, ChevronRight, RefreshCw } from "lucide-react" +import { Search, MoreHorizontal, Eye, UserPlus, Filter, ChevronLeft, ChevronRight } from "lucide-react" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Badge } from "@/components/ui/badge" import { getTrafficPoolList } from "@/lib/traffic-pool-api" @@ -123,18 +123,9 @@ export default function CustomersPage() { const [currentPage, setCurrentPage] = useState(1) const [totalPages, setTotalPages] = useState(1) const [totalItems, setTotalItems] = useState(0) - const [pageSize, setPageSize] = useState(30) + const [pageSize, setPageSize] = useState(10) const [jumpToPage, setJumpToPage] = useState("") - // 添加重置函数 - const handleReset = () => { - setSearchTerm("") - setSelectedRegion("") - setSelectedGender("") - setSelectedSource("") - setSelectedProject("") - } - // 获取客户列表数据 useEffect(() => { const fetchCustomers = async () => { @@ -142,13 +133,7 @@ export default function CustomersPage() { try { const response = await getTrafficPoolList(currentPage, pageSize, searchTerm); if (response.code === 200 && response.data) { - // 处理标签数据,过滤掉无效标签 - const processedCustomers = response.data.list.map(customer => ({ - ...customer, - tags: customer.tags.filter(tag => tag && tag !== "请选择标签"), - createTime: customer.addTime // 统一使用createTime字段 - })); - setCustomers(processedCustomers); + setCustomers(response.data.list); setTotalItems(response.data.total); setTotalPages(Math.ceil(response.data.total / pageSize)); setError(null); @@ -191,124 +176,121 @@ export default function CustomersPage() { }; // Filter customers based on search and filters (兼容示例数据) - const filteredCustomers = customers.filter((customer) => { + const filteredCustomers = customersData.filter((customer) => { const matchesSearch = - customer.nickname.toLowerCase().includes(searchTerm.toLowerCase()) || - customer.wechatId.toLowerCase().includes(searchTerm.toLowerCase()); + customer.name.toLowerCase().includes(searchTerm.toLowerCase()) || + customer.wechatId.toLowerCase().includes(searchTerm.toLowerCase()) - const matchesRegion = selectedRegion ? customer.region === selectedRegion : true; - const matchesGender = selectedGender ? customer.gender === selectedGender : true; - const matchesSource = selectedSource ? customer.source === selectedSource : true; - const matchesProject = selectedProject ? customer.projectName === selectedProject : true; + const matchesRegion = selectedRegion ? customer.region === selectedRegion : true + const matchesGender = selectedGender ? customer.gender === selectedGender : true + const matchesSource = selectedSource ? customer.source === selectedSource : true + const matchesProject = selectedProject ? customer.projectName === selectedProject : true - return matchesSearch && matchesRegion && matchesGender && matchesSource && matchesProject; - }); + return matchesSearch && matchesRegion && matchesGender && matchesSource && matchesProject + }) // Get unique values for filters - const regions = [...new Set(customers.map((c) => c.region))] - const sources = [...new Set(customers.map((c) => c.source))] - const projects = [...new Set(customers.map((c) => c.projectName))] + const regions = [...new Set(customersData.map((c) => c.region))] + const sources = [...new Set(customersData.map((c) => c.source))] + const projects = [...new Set(customersData.map((c) => c.projectName))] return ( -
地区
+ +性别
+ +来源
+ +所属项目
+ +地区
- -性别
- -来源
- -所属项目
- -