From 151db81258f128954f7ea973cbc467afc78db5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Sat, 12 Apr 2025 19:06:00 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=B5=81=E9=87=8F=E6=B1=A0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../superadmin/controller/TrafficPool.php | 127 +++++++----------- Server/application/superadmin/model/Scene.php | 13 ++ .../superadmin/model/TrafficPool.php | 37 ++++- .../superadmin/model/TrafficSource.php | 37 +++++ .../superadmin/model/WechatAccount.php | 13 ++ .../superadmin/model/WechatTag.php | 13 ++ SuperAdmin/app/dashboard/customers/page.tsx | 64 +++++---- SuperAdmin/lib/traffic-pool-api.ts | 4 +- 8 files changed, 202 insertions(+), 106 deletions(-) create mode 100644 Server/application/superadmin/model/Scene.php create mode 100644 Server/application/superadmin/model/WechatAccount.php create mode 100644 Server/application/superadmin/model/WechatTag.php diff --git a/Server/application/superadmin/controller/TrafficPool.php b/Server/application/superadmin/controller/TrafficPool.php index f773cef7..83a96155 100644 --- a/Server/application/superadmin/controller/TrafficPool.php +++ b/Server/application/superadmin/controller/TrafficPool.php @@ -3,6 +3,7 @@ namespace app\superadmin\controller; use app\superadmin\model\TrafficPool as TrafficPoolModel; use think\Controller; +use think\facade\Request; /** * 客户池控制器 @@ -16,102 +17,66 @@ class TrafficPool extends Controller public function getList() { // 获取分页参数 - $page = $this->request->param('page/d', 1); - $limit = $this->request->param('limit/d', 20); - $keyword = $this->request->param('keyword/s', ''); + $page = Request::param('page/d', 1); + $limit = Request::param('limit/d', 30); - // 构建查询条件 - $where = []; - - // 如果有搜索关键词 - if (!empty($keyword)) { - $where[] = ['tp.nickname|tp.identifier|tp.alias', 'like', "%{$keyword}%"]; - } - - // 查询数据 + // 构建查询 $query = TrafficPoolModel::alias('tp') - // 关联流量来源表 - ->join('traffic_source ts', 'tp.identifier = ts.identifier', 'inner') - // 关联公司表 - ->join('company c', 'ts.companyId = c.id', 'left') - // 关联微信好友表 - ->join('wechat_friend wf', 'tp.wechatId = wf.wechatId', 'left') - // 查询字段 + ->join('traffic_source ts', 'tp.identifier = ts.identifier', 'INNER') + ->join('company c', 'ts.companyId = c.id', 'LEFT') + ->join('wechat_account wa', 'tp.wechatId = wa.wechatId', 'LEFT') + ->join('wechat_tag wt', 'wa.wechatId = wt.wechatId') ->field([ - 'distinct ts.identifier', 'tp.id', - 'tp.avatar', - 'tp.nickname', - 'tp.wechatId', - 'tp.mobile', - 'tp.createTime', + 'tp.wechatId', + 'tp.createTime as addTime', 'ts.fromd as source', - 'ts.companyId', - 'c.name as companyName', - 'wf.gender', - 'wf.region', - 'wf.labels' - ]); - - // 统计总数 - $total = $query->where($where)->count(); - - // 获取列表数据 - $list = $query->where($where) - ->order('tp.createTime', 'desc') - ->page($page, $limit) - ->select(); - - // 格式化数据 - $data = []; - foreach ($list as $item) { - $labels = []; - // 处理标签数据 - if (!empty($item['labels'])) { - $labelData = json_decode($item['labels'], true); - if (is_array($labelData)) { - foreach ($labelData as $label) { - if (isset($label['name'])) { - $labels[] = $label['name']; - } - } - } - } - - // 格式化性别 - $gender = '未知'; - switch ($item['gender']) { + 'c.name as projectName', + 'wa.avatar', + 'wa.gender', + 'wa.nickname', + 'wa.region', + 'wt.tags' + ]) + ->order('tp.createTime DESC'); + + // 执行分页查询 + $list = $query->paginate([ + 'list_rows' => $limit, + 'page' => $page + ]); + + // 处理性别显示 + $list->each(function($item) { + // 处理性别显示 + switch($item['gender']) { case 1: - $gender = '男'; + $item['gender'] = '男'; break; case 2: - $gender = '女'; + $item['gender'] = '女'; break; + default: + $item['gender'] = '保密'; } - - $data[] = [ - 'id' => $item['id'], - 'avatar' => $item['avatar'], - 'nickname' => $item['nickname'], - 'wechatId' => $item['wechatId'], - 'gender' => $gender, - 'region' => $item['region'] ?: '未知', - 'tags' => empty($labels) ? [] : $labels, - 'source' => $item['source'] ?: '未知', - 'companyName' => $item['companyName'] ?: '未知', - 'createTime' => date('Y-m-d H:i:s', $item['createTime']), - 'mobile' => $item['mobile'] - ]; - } + + // 处理标签显示 + if (is_string($item['tags'])) { + $item['tags'] = json_decode($item['tags'], true); + } + + return $item; + }); + // 返回结果 return json([ 'code' => 200, 'msg' => '获取成功', 'data' => [ - 'list' => $data, - 'total' => $total, - 'page' => $page, - 'limit' => $limit + 'total' => $list->total(), + 'list' => $list->items(), + 'page' => $list->currentPage(), + 'limit' => $list->listRows() ] ]); } diff --git a/Server/application/superadmin/model/Scene.php b/Server/application/superadmin/model/Scene.php new file mode 100644 index 00000000..ff53a5c8 --- /dev/null +++ b/Server/application/superadmin/model/Scene.php @@ -0,0 +1,13 @@ + 'integer', + 'wechatId' => 'string', + 'createTime' => 'datetime', + 'updateTime' => 'integer' + ]; + + // 定义字段验证规则 + protected $rule = [ + 'wechatId' => 'require|max:64', + 'identifier' => 'require|max:64' + ]; + + // 定义字段验证提示信息 + protected $message = [ + 'wechatId.require' => '微信ID不能为空', + 'wechatId.max' => '微信ID最多不能超过64个字符', + 'identifier.require' => '标识符不能为空', + 'identifier.max' => '标识符最多不能超过64个字符' + ]; } \ No newline at end of file diff --git a/Server/application/superadmin/model/TrafficSource.php b/Server/application/superadmin/model/TrafficSource.php index 7536cf1c..a2b02200 100644 --- a/Server/application/superadmin/model/TrafficSource.php +++ b/Server/application/superadmin/model/TrafficSource.php @@ -10,4 +10,41 @@ class TrafficSource extends Model { // 设置数据表名 protected $name = 'traffic_source'; + + // 设置表前缀 + protected $prefix = 'ck_'; + + // 设置主键 + protected $pk = 'id'; + + // 自动写入时间戳 + protected $autoWriteTimestamp = true; + + // 定义时间戳字段名 + protected $createTime = 'createTime'; + protected $updateTime = 'updateTime'; + + // 定义字段类型 + protected $type = [ + 'id' => 'integer', + 'identifier' => 'string', + 'companyId' => 'integer', + 'createTime' => 'datetime', + 'updateTime' => 'integer' + ]; + + // 定义字段验证规则 + protected $rule = [ + 'identifier' => 'require|max:64', + 'companyId' => 'number', + 'fromd' => 'max:255' + ]; + + // 定义字段验证提示信息 + protected $message = [ + 'identifier.require' => '标识符不能为空', + 'identifier.max' => '标识符最多不能超过64个字符', + 'companyId.number' => '公司ID必须为数字', + 'fromd.max' => '来源最多不能超过255个字符' + ]; } \ No newline at end of file diff --git a/Server/application/superadmin/model/WechatAccount.php b/Server/application/superadmin/model/WechatAccount.php new file mode 100644 index 00000000..b83281a6 --- /dev/null +++ b/Server/application/superadmin/model/WechatAccount.php @@ -0,0 +1,13 @@ + ({ + ...customer, + tags: customer.tags.filter(tag => tag && tag !== "请选择标签"), + createTime: customer.addTime // 统一使用createTime字段 + })); + setCustomers(processedCustomers); setTotalItems(response.data.total); setTotalPages(Math.ceil(response.data.total / pageSize)); setError(null); @@ -176,23 +182,23 @@ export default function CustomersPage() { }; // Filter customers based on search and filters (兼容示例数据) - const filteredCustomers = customersData.filter((customer) => { + const filteredCustomers = customers.filter((customer) => { const matchesSearch = - customer.name.toLowerCase().includes(searchTerm.toLowerCase()) || - customer.wechatId.toLowerCase().includes(searchTerm.toLowerCase()) + customer.nickname.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(customersData.map((c) => c.region))] - const sources = [...new Set(customersData.map((c) => c.source))] - const projects = [...new Set(customersData.map((c) => c.projectName))] + 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))] return (
@@ -323,7 +329,15 @@ export default function CustomersPage() {
- + { + // 图片加载失败时使用默认图片 + const target = e.target as HTMLImageElement; + target.src = "/placeholder.svg?height=40&width=40"; + }} + /> {customer.nickname.slice(0, 2)}
@@ -335,17 +349,21 @@ export default function CustomersPage() { {customer.wechatId}
- {customer.tags.map((tag, index) => ( - - {tag} - - ))} + {customer.tags && customer.tags.length > 0 ? ( + customer.tags.map((tag, index) => ( + + {tag} + + )) + ) : ( + 无标签 + )}
{customer.region} {customer.source} - {customer.companyName} - {customer.createTime} + {customer.projectName} + {customer.createTime || "未记录"} @@ -393,10 +411,10 @@ export default function CustomersPage() { - 10 30 50 100 + 150 diff --git a/SuperAdmin/lib/traffic-pool-api.ts b/SuperAdmin/lib/traffic-pool-api.ts index 39f77dfa..4f9f2dbc 100644 --- a/SuperAdmin/lib/traffic-pool-api.ts +++ b/SuperAdmin/lib/traffic-pool-api.ts @@ -12,8 +12,10 @@ export interface Customer { region: string; tags: string[]; source: string; + projectName: string; + addTime: string | null; + createTime: string | null; // 修改为允许null值 companyName: string; - createTime: string; mobile: number; }