私域操盘手 - 流量池潜在用户的状态类型筛选功能

This commit is contained in:
柳清爽
2025-05-13 14:00:56 +08:00
parent 869ce043fc
commit e08a805e88
3 changed files with 71 additions and 41 deletions

View File

@@ -21,6 +21,7 @@ import { useDebounce } from "@/hooks/use-debounce"
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog" import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge" import { Badge } from "@/components/ui/badge"
import { api } from "@/lib/api"
interface UserTag { interface UserTag {
id: string id: string
@@ -44,6 +45,17 @@ interface TrafficUser {
tags: UserTag[] tags: UserTag[]
} }
interface StatusType {
id: number
name: string
}
interface ApiResponse<T> {
code: number
msg: string
data: T
}
export default function TrafficPoolPage() { export default function TrafficPoolPage() {
const router = useRouter() const router = useRouter()
const searchParams = useSearchParams() const searchParams = useSearchParams()
@@ -51,7 +63,8 @@ export default function TrafficPoolPage() {
const [loading, setLoading] = useState(true) // Start with loading state const [loading, setLoading] = useState(true) // Start with loading state
const [activeCategory, setActiveCategory] = useState("potential") // Changed default from "all" to "potential" const [activeCategory, setActiveCategory] = useState("potential") // Changed default from "all" to "potential"
const [sourceFilter, setSourceFilter] = useState("all") const [sourceFilter, setSourceFilter] = useState("all")
const [statusFilter, setStatusFilter] = useState("all") const [statusTypes, setStatusTypes] = useState<StatusType[]>([])
const [statusFilter, setStatusFilter] = useState<string>("all")
const [searchQuery, setSearchQuery] = useState("") const [searchQuery, setSearchQuery] = useState("")
const [currentPage, setCurrentPage] = useState(1) const [currentPage, setCurrentPage] = useState(1)
const [totalPages, setTotalPages] = useState(1) const [totalPages, setTotalPages] = useState(1)
@@ -81,7 +94,7 @@ export default function TrafficPoolPage() {
search: debouncedSearchQuery, search: debouncedSearchQuery,
category: activeCategory, category: activeCategory,
source: sourceFilter, source: sourceFilter,
status: statusFilter, status: statusFilter === "all" ? "" : statusFilter,
}) })
// 检查是否有来源参数 // 检查是否有来源参数
@@ -147,14 +160,38 @@ export default function TrafficPoolPage() {
} }
}, [currentPage, debouncedSearchQuery, activeCategory, sourceFilter, statusFilter, toast, searchParams]) }, [currentPage, debouncedSearchQuery, activeCategory, sourceFilter, statusFilter, toast, searchParams])
const fetchStatusTypes = useCallback(async () => {
try {
const response = await api.get<ApiResponse<StatusType[]>>('/v1/traffic/pool/types')
if (response.code === 200) {
setStatusTypes(response.data)
} else {
toast({
title: "获取状态列表失败",
description: response.msg || "请稍后重试",
variant: "destructive",
})
}
} catch (error) {
console.error("获取状态列表失败:", error)
toast({
title: "获取状态列表失败",
description: "请检查网络连接或稍后重试",
variant: "destructive",
})
}
}, [])
useEffect(() => { useEffect(() => {
fetchUsers() fetchUsers()
fetchStatusTypes()
return () => { return () => {
if (abortControllerRef.current) { if (abortControllerRef.current) {
abortControllerRef.current.abort() abortControllerRef.current.abort()
} }
} }
}, [fetchUsers]) }, [fetchUsers, fetchStatusTypes])
const handleUserClick = (user: TrafficUser) => { const handleUserClick = (user: TrafficUser) => {
setSelectedUser(user) setSelectedUser(user)
@@ -259,9 +296,11 @@ export default function TrafficPoolPage() {
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="all"></SelectItem> <SelectItem value="all"></SelectItem>
<SelectItem value="pending"></SelectItem> {statusTypes.map((status) => (
<SelectItem value="added"></SelectItem> <SelectItem key={status.id} value={status.id.toString()}>
<SelectItem value="failed"></SelectItem> {status.name}
</SelectItem>
))}
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>

View File

@@ -42,6 +42,7 @@ Route::group('v1/', function () {
// 流量池相关 // 流量池相关
Route::group('traffic/pool', function () { Route::group('traffic/pool', function () {
Route::get('', 'app\cunkebao\controller\traffic\GetDissociateListWithInCompanyV1Controller@index'); Route::get('', 'app\cunkebao\controller\traffic\GetDissociateListWithInCompanyV1Controller@index');
Route::get('types', 'app\cunkebao\controller\traffic\GetDissociateTypeListV1Controller@index');
}); });
// 工作台相关 // 工作台相关

View File

@@ -12,52 +12,42 @@ use library\ResponseHelper;
*/ */
class GetDissociateTypeListV1Controller extends BaseController class GetDissociateTypeListV1Controller extends BaseController
{ {
protected function getTypeList(): array
/**
* 获取流量池列表
*
* @param array $where
* @return \think\Paginator
*/
protected function getPoolListByCompanyId(array $where): \think\Paginator
{ {
$query = TrafficPoolModel::alias('t') return [
->field( [
[ 'id' => 1,
't.identifier', 't.mobile', 't.wechatId', 'name' => '待处理'
's.id', 's.fromd', 's.status', 's.createTime' ],
] [
) 'id' => 2,
->join('traffic_source s', 't.identifier=s.identifier') 'name' => '处理中'
->order('s.id desc'); ],
[
foreach ($where as $key => $value) { 'id' => 4,
if (is_numeric($key) && is_array($value) && isset($value[0]) && $value[0] === 'exp') { 'name' => '已拒绝'
$query->whereExp('', $value[1]); ],
continue; [
} 'id' => 5,
'name' => '已过期'
$query->where($key, $value); ],
} [
'id' => 6,
return $query->paginate($this->request->param('limit/d', 10), false, ['page' => $this->request->param('page/d', 1)]); 'name' => '已取消'
]
];
} }
/** /**
* 获取流量池列表 * 潜在客户的全部状态
* *
* @return \think\response\Json * @return \think\response\Json
*/ */
public function index() public function index()
{ {
try { try {
$result = $this->getPoolListByCompanyId( $this->makeWhere() );
return ResponseHelper::success( return ResponseHelper::success(
[ $this->getTypeList()
'list' => $result->items(),
'total' => $result->total(),
]
); );
} catch (\Exception $e) { } catch (\Exception $e) {
return ResponseHelper::error($e->getMessage(), $e->getCode()); return ResponseHelper::error($e->getMessage(), $e->getCode());