修改文档
This commit is contained in:
File diff suppressed because it is too large
Load Diff
981
Project/fonrey/UI_DESIGN/客源列表_UI.html.bak
Normal file
981
Project/fonrey/UI_DESIGN/客源列表_UI.html.bak
Normal file
@@ -0,0 +1,981 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>客源列表 · 私客 · Fonrey 房睿</title>
|
||||||
|
<meta name="viewport" content="width=1280">
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
|
||||||
|
<script>
|
||||||
|
tailwind.config = {
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
primary: {
|
||||||
|
50:'#F0FDFA',100:'#CCFBF1',200:'#99F6E4',
|
||||||
|
500:'#14B8A6',600:'#0F766E',700:'#115E59',800:'#134E4A',
|
||||||
|
},
|
||||||
|
neutral: {
|
||||||
|
50:'#F8FAFC',100:'#F1F5F9',200:'#E2E8F0',300:'#CBD5E1',
|
||||||
|
400:'#94A3B8',500:'#64748B',600:'#475569',700:'#334155',
|
||||||
|
800:'#1E293B',900:'#0F172A',
|
||||||
|
},
|
||||||
|
success:{50:'#F0FDF4',600:'#16A34A'},
|
||||||
|
warning:{50:'#FFFBEB',600:'#D97706'},
|
||||||
|
danger: {50:'#FEF2F2',600:'#DC2626'},
|
||||||
|
info: {50:'#EFF6FF',600:'#2563EB'},
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
sans:['Inter','PingFang SC','Microsoft YaHei','sans-serif'],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
body { font-family: 'Inter','PingFang SC','Microsoft YaHei',sans-serif; }
|
||||||
|
.tabular-nums { font-variant-numeric: tabular-nums; }
|
||||||
|
[x-cloak] { display: none !important; }
|
||||||
|
::-webkit-scrollbar{width:6px;height:6px}
|
||||||
|
::-webkit-scrollbar-thumb{background:#CBD5E1;border-radius:4px}
|
||||||
|
::-webkit-scrollbar-thumb:hover{background:#94A3B8}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="bg-neutral-50 text-neutral-700 text-sm antialiased">
|
||||||
|
|
||||||
|
<!-- ============ 顶部导航 ============ -->
|
||||||
|
<header class="fixed top-0 left-0 right-0 h-14 z-30 bg-primary-800 flex items-center justify-between">
|
||||||
|
<!-- 左区:Logo -->
|
||||||
|
<div class="flex items-center gap-2 px-4 w-60 shrink-0">
|
||||||
|
<div class="w-7 h-7 rounded-md bg-primary-500 flex items-center justify-center text-white font-semibold text-sm">F</div>
|
||||||
|
<span class="font-semibold text-white text-base">Fonrey · 房睿</span>
|
||||||
|
</div>
|
||||||
|
<!-- 中区:主导航 + 搜索 -->
|
||||||
|
<div class="flex items-center gap-4 flex-1 px-2">
|
||||||
|
<nav class="flex items-center gap-1 text-sm">
|
||||||
|
<a href="#" class="px-3 py-1.5 rounded-md text-primary-100 hover:bg-primary-700 hover:text-white transition-colors">工作台</a>
|
||||||
|
<a href="#" class="px-3 py-1.5 rounded-md text-primary-100 hover:bg-primary-700 hover:text-white transition-colors">房源</a>
|
||||||
|
<a href="#" class="px-3 py-1.5 rounded-md bg-primary-600 text-white font-medium">客源</a>
|
||||||
|
<a href="#" class="px-3 py-1.5 rounded-md text-primary-100 hover:bg-primary-700 hover:text-white transition-colors">营销</a>
|
||||||
|
<a href="#" class="px-3 py-1.5 rounded-md text-primary-100 hover:bg-primary-700 hover:text-white transition-colors">交易</a>
|
||||||
|
<a href="#" class="px-3 py-1.5 rounded-md text-primary-100 hover:bg-primary-700 hover:text-white transition-colors">数据</a>
|
||||||
|
<a href="#" class="px-3 py-1.5 rounded-md text-primary-100 hover:bg-primary-700 hover:text-white transition-colors">人事</a>
|
||||||
|
<a href="#" class="px-3 py-1.5 rounded-md text-primary-100 hover:bg-primary-700 hover:text-white transition-colors">系统</a>
|
||||||
|
</nav>
|
||||||
|
<!-- 全局搜索 -->
|
||||||
|
<div class="max-w-xs w-full relative">
|
||||||
|
<svg class="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-primary-300" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m21 21-4.3-4.3M11 19a8 8 0 1 1 0-16 8 8 0 0 1 0 16Z"/></svg>
|
||||||
|
<input type="text" placeholder="搜索房源 / 客户 / 楼盘 ⌘K"
|
||||||
|
class="w-full pl-9 pr-3 py-1.5 text-sm rounded-md bg-primary-700/60 border border-transparent text-white placeholder:text-primary-300 hover:bg-primary-700 focus:bg-white focus:text-neutral-700 focus:border-primary-600 focus:ring-2 focus:ring-primary-600/20 focus:outline-none focus:placeholder:text-neutral-400 transition-all">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 右区:工具 -->
|
||||||
|
<div class="flex items-center gap-1 px-4 shrink-0">
|
||||||
|
<button class="relative p-1.5 text-primary-200 hover:bg-primary-700 hover:text-white rounded-md transition-colors">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022 23.848 23.848 0 0 0 5.454 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0"/></svg>
|
||||||
|
<span class="absolute top-1 right-1 w-1.5 h-1.5 rounded-full bg-danger-600"></span>
|
||||||
|
</button>
|
||||||
|
<button class="p-1.5 text-primary-200 hover:bg-primary-700 hover:text-white rounded-md transition-colors">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>
|
||||||
|
</button>
|
||||||
|
<div class="flex items-center gap-2 pl-3 ml-1 border-l border-primary-700">
|
||||||
|
<div class="w-7 h-7 rounded-full bg-primary-600 text-white flex items-center justify-center text-xs font-semibold">WS</div>
|
||||||
|
<span class="text-sm font-medium text-primary-100">魏深</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- ============ 左侧导航栏 ============ -->
|
||||||
|
<aside class="fixed left-0 top-14 h-[calc(100vh-56px)] w-60 z-20 border-r border-neutral-200 bg-white">
|
||||||
|
<nav class="p-3 space-y-0.5">
|
||||||
|
<div class="px-2 pt-2 pb-1 text-xs font-medium text-neutral-500 uppercase tracking-wide">客源管理</div>
|
||||||
|
<a href="#" class="flex items-center gap-2 px-2 py-1.5 rounded-md bg-primary-50 text-primary-700 font-medium">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"/></svg>
|
||||||
|
私客列表
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex items-center gap-2 px-2 py-1.5 rounded-md text-neutral-700 hover:bg-neutral-100">公客池</a>
|
||||||
|
<a href="#" class="flex items-center gap-2 px-2 py-1.5 rounded-md text-neutral-700 hover:bg-neutral-100">成交客</a>
|
||||||
|
<a href="#" class="flex items-center gap-2 px-2 py-1.5 rounded-md text-neutral-700 hover:bg-neutral-100">已删客源</a>
|
||||||
|
</nav>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<!-- ============ 主内容区 ============ -->
|
||||||
|
<main x-data="clientListApp()" class="ml-60 pt-[72px] min-h-screen bg-neutral-50">
|
||||||
|
<div class="px-6 py-4">
|
||||||
|
|
||||||
|
<!-- ======== 一级 Tab 导航 ======== -->
|
||||||
|
<div class="flex items-center justify-between border-b border-neutral-200 bg-neutral-50 sticky top-14 z-20 -mx-6 px-6 pt-1">
|
||||||
|
<div class="flex items-center gap-0">
|
||||||
|
<a href="#" class="px-4 py-3 text-sm border-b-2 border-primary-600 text-primary-600 font-medium whitespace-nowrap">私客</a>
|
||||||
|
<a href="#" class="px-4 py-3 text-sm border-b-2 border-transparent text-neutral-500 hover:text-neutral-700 whitespace-nowrap transition-colors">资料客</a>
|
||||||
|
<a href="#" class="px-4 py-3 text-sm border-b-2 border-transparent text-neutral-500 hover:text-neutral-700 whitespace-nowrap transition-colors">营销客</a>
|
||||||
|
<a href="#" class="px-4 py-3 text-sm border-b-2 border-transparent text-neutral-500 hover:text-neutral-700 whitespace-nowrap transition-colors">成交客</a>
|
||||||
|
<a href="#" class="px-4 py-3 text-sm border-b-2 border-transparent text-neutral-500 hover:text-neutral-700 whitespace-nowrap transition-colors">公客</a>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧操作区 -->
|
||||||
|
<div class="flex items-center gap-4 text-sm pb-1">
|
||||||
|
<span class="text-neutral-500">
|
||||||
|
私客与成交客重复:
|
||||||
|
<a href="#" class="text-info-600 hover:underline font-medium">3</a>
|
||||||
|
</span>
|
||||||
|
<span class="text-neutral-500">
|
||||||
|
私客与公客重复:
|
||||||
|
<a href="#" class="text-info-600 hover:underline font-medium">7</a>
|
||||||
|
</span>
|
||||||
|
<a href="#" class="text-neutral-500 hover:text-neutral-700 transition-colors">已删客源</a>
|
||||||
|
<a href="/clients/private/create/"
|
||||||
|
class="inline-flex items-center gap-1.5 px-3 py-1.5 bg-primary-600 hover:bg-primary-700 text-white text-sm font-medium rounded-lg transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||||
|
新增私客
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== 二级 Tab 导航 ======== -->
|
||||||
|
<div class="mt-3 flex items-center gap-1 p-1 bg-neutral-100 rounded-lg w-fit">
|
||||||
|
<template x-for="tab in tabs" :key="tab.key">
|
||||||
|
<button
|
||||||
|
:class="activeTab === tab.key
|
||||||
|
? 'bg-white text-primary-700 shadow-sm font-semibold'
|
||||||
|
: 'text-neutral-600 hover:bg-white/60'"
|
||||||
|
class="px-4 py-1.5 text-sm rounded-md transition-all flex items-center gap-1"
|
||||||
|
@click="activeTab = tab.key">
|
||||||
|
<span x-text="tab.label"></span>
|
||||||
|
<span x-show="tab.count !== null"
|
||||||
|
class="bg-neutral-200 text-neutral-600 text-xs px-1.5 py-0.5 rounded-full tabular-nums"
|
||||||
|
x-text="tab.count"></span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== 搜索 + 筛选区 ======== -->
|
||||||
|
<div class="bg-white rounded-lg border border-neutral-200 px-4 py-3 mt-3">
|
||||||
|
|
||||||
|
<!-- 搜索行 -->
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<!-- 范围选择器 -->
|
||||||
|
<select class="text-sm text-neutral-600 border border-neutral-300 rounded-lg px-3 py-2 bg-white focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-600/40 shrink-0">
|
||||||
|
<option>客户信息</option>
|
||||||
|
<option>客源编号</option>
|
||||||
|
<option>小区名称</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 搜索框 -->
|
||||||
|
<div class="relative flex-1 max-w-lg">
|
||||||
|
<svg class="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-neutral-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m21 21-4.3-4.3M11 19a8 8 0 1 1 0-16 8 8 0 0 1 0 16Z"/></svg>
|
||||||
|
<input type="search"
|
||||||
|
placeholder="输入客源姓名 / 号码 / 号码后4位 / 客源编号 / 备注信息"
|
||||||
|
class="w-full pl-9 pr-10 py-2 border border-neutral-300 rounded-lg text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-600/40">
|
||||||
|
<button class="absolute right-1 top-1/2 -translate-y-1/2 bg-primary-600 hover:bg-primary-700 text-white w-8 h-8 rounded-md flex items-center justify-center transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m21 21-4.3-4.3M11 19a8 8 0 1 1 0-16 8 8 0 0 1 0 16Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 已存搜索 -->
|
||||||
|
<div x-data="{ open: false }" class="relative shrink-0">
|
||||||
|
<button @click="open = !open"
|
||||||
|
class="text-sm text-neutral-500 hover:text-neutral-700 flex items-center gap-1 transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0 1 11.186 0Z"/></svg>
|
||||||
|
<span>3条已存搜索</span>
|
||||||
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5"/></svg>
|
||||||
|
</button>
|
||||||
|
<div x-show="open" x-cloak @click.outside="open = false"
|
||||||
|
class="absolute left-0 top-full mt-1 w-64 bg-white shadow-lg border border-neutral-200 rounded-lg z-50 py-1">
|
||||||
|
<div class="px-3 py-2 text-xs text-neutral-400 border-b border-neutral-100">已存搜索条件</div>
|
||||||
|
<a href="#" class="flex items-center justify-between px-3 py-2 text-sm text-neutral-700 hover:bg-neutral-50">
|
||||||
|
<span>求购·A级·宝山</span>
|
||||||
|
<button class="text-neutral-400 hover:text-danger-600 ml-2">
|
||||||
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex items-center justify-between px-3 py-2 text-sm text-neutral-700 hover:bg-neutral-50">
|
||||||
|
<span>7日活跃·与我相关</span>
|
||||||
|
<button class="text-neutral-400 hover:text-danger-600 ml-2">
|
||||||
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex items-center justify-between px-3 py-2 text-sm text-neutral-700 hover:bg-neutral-50">
|
||||||
|
<span>即将掉公·近30天录入</span>
|
||||||
|
<button class="text-neutral-400 hover:text-danger-600 ml-2">
|
||||||
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
<div class="px-3 py-2 border-t border-neutral-100">
|
||||||
|
<button class="text-xs text-primary-600 hover:underline">保存当前筛选条件</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 收起/展开筛选 -->
|
||||||
|
<button @click="showFilters = !showFilters"
|
||||||
|
class="ml-auto text-sm text-neutral-500 hover:text-primary-600 flex items-center gap-1 shrink-0 transition-colors">
|
||||||
|
<span x-text="showFilters ? '收起筛选' : '展开筛选'"></span>
|
||||||
|
<svg class="w-4 h-4 transition-transform" :class="showFilters ? 'rotate-180' : ''" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 筛选区(可折叠) -->
|
||||||
|
<div x-show="showFilters"
|
||||||
|
x-transition:enter="transition ease-out duration-150"
|
||||||
|
x-transition:enter-start="opacity-0 -translate-y-1"
|
||||||
|
x-transition:enter-end="opacity-100 translate-y-0"
|
||||||
|
x-transition:leave="transition ease-in duration-100"
|
||||||
|
x-transition:leave-start="opacity-100 translate-y-0"
|
||||||
|
x-transition:leave-end="opacity-0 -translate-y-1"
|
||||||
|
class="mt-3 space-y-2.5 border-t border-neutral-100 pt-3">
|
||||||
|
|
||||||
|
<!-- 快捷筛选行 -->
|
||||||
|
<div class="flex items-center gap-5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-6 shrink-0">常用</span>
|
||||||
|
<label class="flex items-center gap-1.5 cursor-pointer text-neutral-600 hover:text-primary-600 transition-colors">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> 即将掉公
|
||||||
|
</label>
|
||||||
|
<div class="flex items-center gap-1.5">
|
||||||
|
<span class="text-neutral-600">录入时间</span>
|
||||||
|
<select class="text-sm border-0 text-neutral-600 bg-transparent cursor-pointer focus:outline-none hover:text-primary-600 pr-4">
|
||||||
|
<option value="">不限</option>
|
||||||
|
<option>今天</option>
|
||||||
|
<option>最近7天</option>
|
||||||
|
<option>最近30天</option>
|
||||||
|
<option>自定义</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<label class="flex items-center gap-1.5 cursor-pointer text-neutral-600 hover:text-primary-600 transition-colors">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> 与我相关
|
||||||
|
<svg class="w-3.5 h-3.5 text-neutral-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/></svg>
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-1.5 cursor-pointer text-neutral-600 hover:text-primary-600 transition-colors">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> 我部门相关
|
||||||
|
<svg class="w-3.5 h-3.5 text-neutral-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/></svg>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 状态筛选行 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-2 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-6 shrink-0">状态</span>
|
||||||
|
<template x-for="opt in statusOptions" :key="opt.value">
|
||||||
|
<button
|
||||||
|
:class="activeStatus === opt.value
|
||||||
|
? 'bg-primary-600 text-white border-primary-600'
|
||||||
|
: 'border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600'"
|
||||||
|
class="px-3 py-1 text-xs border rounded-md transition-colors"
|
||||||
|
@click="activeStatus = opt.value"
|
||||||
|
x-text="opt.label">
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 需求类型筛选行 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-2 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-6 shrink-0">需求</span>
|
||||||
|
<button class="px-3 py-1 text-xs bg-primary-600 text-white border border-primary-600 rounded-md">不限</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">二手</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">新房</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 等级筛选行 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-2 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-6 shrink-0">等级</span>
|
||||||
|
<button class="px-3 py-1 text-xs bg-primary-600 text-white border border-primary-600 rounded-md">不限</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">A(急迫)</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">B(较强)</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">C(一般)</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">D(较弱)</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">E(暂不)</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">未填写</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 位置筛选行 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-2 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-6 shrink-0">位置</span>
|
||||||
|
<button class="px-3 py-1 text-xs bg-primary-600 text-white border border-primary-600 rounded-md">不限</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">宝山</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">崇明</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">奉贤</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">虹口</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">黄浦</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">嘉定</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">金山</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">静安</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">闵行</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">浦东</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">普陀</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">青浦</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">松江</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">徐汇</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">杨浦</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">长宁</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 购价筛选行 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-2 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-6 shrink-0">购价</span>
|
||||||
|
<button class="px-3 py-1 text-xs bg-primary-600 text-white border border-primary-600 rounded-md">不限</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">200万以下</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">200-300万</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">300-500万</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">500-800万</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">800-1000万</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">1000万以上</button>
|
||||||
|
<div class="flex items-center gap-1.5 ml-1">
|
||||||
|
<input type="number" placeholder="最小值" class="w-20 px-2 py-1 text-xs border border-neutral-300 rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-600/40">
|
||||||
|
<span class="text-neutral-400 text-xs">~</span>
|
||||||
|
<input type="number" placeholder="最大值" class="w-20 px-2 py-1 text-xs border border-neutral-300 rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-600/40">
|
||||||
|
<span class="text-xs text-neutral-500">万</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 居室筛选行 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-2 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-6 shrink-0">居室</span>
|
||||||
|
<button class="px-3 py-1 text-xs bg-primary-600 text-white border border-primary-600 rounded-md">不限</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">1居</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">2居</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">3居</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">4居</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">5居及以上</button>
|
||||||
|
<label class="flex items-center gap-1.5 cursor-pointer text-neutral-600 hover:text-primary-600 transition-colors ml-2">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> 是大价值
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 更多筛选(展开/收起) -->
|
||||||
|
<div x-data="{ showMore: false }">
|
||||||
|
<button @click="showMore = !showMore"
|
||||||
|
class="flex items-center gap-1 text-xs text-neutral-500 hover:text-primary-600 transition-colors py-0.5">
|
||||||
|
<svg class="w-3.5 h-3.5 transition-transform" :class="showMore ? 'rotate-180' : ''" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5"/></svg>
|
||||||
|
<span x-text="showMore ? '收起筛选' : '展开更多筛选'"></span>
|
||||||
|
</button>
|
||||||
|
<div x-show="showMore" x-cloak class="mt-2.5 space-y-2.5">
|
||||||
|
<!-- 相关方 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-3 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-10 shrink-0">相关方</span>
|
||||||
|
<select class="text-sm border border-neutral-300 rounded-md px-2 py-1 bg-white focus:outline-none text-neutral-600">
|
||||||
|
<option>不限</option>
|
||||||
|
<option>首录人:我</option>
|
||||||
|
<option>归属人:我</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<!-- 委托日期 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-3 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-10 shrink-0">委托日期</span>
|
||||||
|
<input type="date" class="text-sm border border-neutral-300 rounded-md px-2 py-1 bg-white focus:outline-none text-neutral-600">
|
||||||
|
<span class="text-neutral-400 text-xs">~</span>
|
||||||
|
<input type="date" class="text-sm border border-neutral-300 rounded-md px-2 py-1 bg-white focus:outline-none text-neutral-600">
|
||||||
|
</div>
|
||||||
|
<!-- 来源 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-3 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-10 shrink-0">来源</span>
|
||||||
|
<select class="text-sm border border-neutral-300 rounded-md px-2 py-1 bg-white focus:outline-none text-neutral-600">
|
||||||
|
<option>不限</option>
|
||||||
|
<option>自然到访</option>
|
||||||
|
<option>网络推广</option>
|
||||||
|
<option>老客介绍</option>
|
||||||
|
<option>巧客力</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<!-- 活跃情况 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-2 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-10 shrink-0">活跃</span>
|
||||||
|
<button class="px-3 py-1 text-xs bg-primary-600 text-white border border-primary-600 rounded-md">不限</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">新配房</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">7日活跃</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">30日活跃</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">即将过期</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">已暂缓</button>
|
||||||
|
</div>
|
||||||
|
<!-- 带看进度 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-2 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-10 shrink-0">带看</span>
|
||||||
|
<button class="px-3 py-1 text-xs bg-primary-600 text-white border border-primary-600 rounded-md">不限</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">未带看</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">一看</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">二看</button>
|
||||||
|
<button class="px-3 py-1 text-xs border border-neutral-200 text-neutral-600 hover:border-primary-400 hover:text-primary-600 rounded-md transition-colors">复看</button>
|
||||||
|
</div>
|
||||||
|
<!-- 保护客 -->
|
||||||
|
<div class="flex items-center flex-wrap gap-x-5 gap-y-1.5 text-sm">
|
||||||
|
<span class="text-neutral-400 text-xs w-10 shrink-0">其他</span>
|
||||||
|
<label class="flex items-center gap-1.5 cursor-pointer text-neutral-600 hover:text-primary-600 transition-colors">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> 保护客
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-1.5 cursor-pointer text-neutral-600 hover:text-primary-600 transition-colors">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> 偏好新房
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-1.5 cursor-pointer text-neutral-600 hover:text-primary-600 transition-colors">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> 收藏客源
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-1.5 cursor-pointer text-neutral-600 hover:text-primary-600 transition-colors">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> 置顶客源
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== 工具栏 ======== -->
|
||||||
|
<div class="flex items-center justify-between px-4 py-2.5 bg-white border border-neutral-200 rounded-lg mt-3">
|
||||||
|
<!-- 左侧:批量操作 + 计数 -->
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<button :disabled="selected.length === 0"
|
||||||
|
:class="selected.length > 0
|
||||||
|
? 'text-neutral-700 hover:bg-neutral-100 border-neutral-300 cursor-pointer'
|
||||||
|
: 'text-neutral-300 border-neutral-200 cursor-not-allowed'"
|
||||||
|
class="px-3 py-1.5 text-sm border rounded-md transition-colors">
|
||||||
|
修改相关方
|
||||||
|
</button>
|
||||||
|
<button :disabled="selected.length === 0"
|
||||||
|
:class="selected.length > 0
|
||||||
|
? 'text-neutral-700 hover:bg-neutral-100 border-neutral-300 cursor-pointer'
|
||||||
|
: 'text-neutral-300 border-neutral-200 cursor-not-allowed'"
|
||||||
|
class="px-3 py-1.5 text-sm border rounded-md transition-colors">
|
||||||
|
修改来源
|
||||||
|
</button>
|
||||||
|
<button :disabled="selected.length === 0"
|
||||||
|
:class="selected.length > 0
|
||||||
|
? 'text-danger-600 hover:bg-danger-50 border-danger-200 cursor-pointer'
|
||||||
|
: 'text-neutral-300 border-neutral-200 cursor-not-allowed'"
|
||||||
|
class="px-3 py-1.5 text-sm border rounded-md transition-colors">
|
||||||
|
删除客源
|
||||||
|
</button>
|
||||||
|
<button :disabled="selected.length === 0"
|
||||||
|
:class="selected.length > 0
|
||||||
|
? 'text-neutral-700 hover:bg-neutral-100 border-neutral-300 cursor-pointer'
|
||||||
|
: 'text-neutral-300 border-neutral-200 cursor-not-allowed'"
|
||||||
|
class="px-3 py-1.5 text-sm border rounded-md transition-colors">
|
||||||
|
合并客源
|
||||||
|
</button>
|
||||||
|
<span class="text-sm text-neutral-500 ml-2">
|
||||||
|
共 <strong class="text-neutral-800 tabular-nums">1,248</strong> 条
|
||||||
|
</span>
|
||||||
|
<span x-show="selected.length > 0" class="text-sm text-primary-600">
|
||||||
|
已选 <span x-text="selected.length" class="tabular-nums"></span> 条
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧:导出 + 自定义列 -->
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<button class="flex items-center gap-1.5 px-3 py-1.5 text-sm text-neutral-600 border border-neutral-300 rounded-md hover:bg-neutral-50 transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3"/></svg>
|
||||||
|
导出
|
||||||
|
</button>
|
||||||
|
<button @click="showColumnModal = true"
|
||||||
|
class="flex items-center gap-1.5 px-3 py-1.5 text-sm text-neutral-600 border border-neutral-300 rounded-md hover:bg-neutral-50 transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-9.75 0h9.75"/></svg>
|
||||||
|
自定义列表
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== 数据表格 ======== -->
|
||||||
|
<div id="client-list-container" class="rounded-lg border border-neutral-200 overflow-hidden bg-white mt-3">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="min-w-full divide-y divide-neutral-200">
|
||||||
|
<thead class="bg-neutral-50">
|
||||||
|
<tr>
|
||||||
|
<th class="w-10 px-4 py-3">
|
||||||
|
<input type="checkbox" id="select-all"
|
||||||
|
class="w-4 h-4 rounded accent-primary-600"
|
||||||
|
@change="toggleAll($event)">
|
||||||
|
</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap min-w-[160px]">姓名</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap w-20">状态</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap w-20">需求类型</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap min-w-[180px]">需求/解读</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap w-24">智能配房</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap min-w-[120px]">意向商圈/小区</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap min-w-[140px]">归属人</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap w-20">带看进度</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap w-[72px] cursor-pointer hover:bg-neutral-100 select-none">
|
||||||
|
带看次数
|
||||||
|
<svg class="inline w-3.5 h-3.5 text-neutral-300 ml-0.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"/></svg>
|
||||||
|
</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap w-24 cursor-pointer hover:bg-neutral-100 select-none">
|
||||||
|
委托日期
|
||||||
|
<svg class="inline w-3.5 h-3.5 text-neutral-300 ml-0.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"/></svg>
|
||||||
|
</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap w-24 cursor-pointer hover:bg-neutral-100 select-none text-primary-600">
|
||||||
|
最近时间
|
||||||
|
<svg class="inline w-3.5 h-3.5 text-primary-400 ml-0.5" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25 12 15.75 4.5 8.25"/></svg>
|
||||||
|
</th>
|
||||||
|
<th class="px-4 py-3 text-center text-xs font-semibold text-neutral-500 uppercase tracking-wide whitespace-nowrap w-16">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="client-table-body" class="divide-y divide-neutral-100 bg-white">
|
||||||
|
|
||||||
|
<!-- 数据行 1 -->
|
||||||
|
<tr class="hover:bg-neutral-50 transition-colors"
|
||||||
|
:class="selected.includes('c001') ? 'bg-primary-50 hover:bg-primary-100' : ''">
|
||||||
|
<td class="w-10 px-4 py-2">
|
||||||
|
<input type="checkbox" value="c001" class="w-4 h-4 rounded accent-primary-600" x-model="selected">
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 min-w-[160px]">
|
||||||
|
<div class="flex flex-col gap-0.5">
|
||||||
|
<a href="/clients/private/c001/" class="text-info-600 hover:underline font-medium text-sm truncate max-w-[160px]">王建国</a>
|
||||||
|
<div class="flex items-center gap-1 flex-wrap">
|
||||||
|
<span class="text-[11px] text-neutral-500">A(急迫)</span>
|
||||||
|
<span class="text-[11px] px-1.5 py-0.5 rounded-full font-medium bg-success-50 text-success-600">7日活跃</span>
|
||||||
|
<span class="text-[11px] px-1.5 py-0.5 rounded-full font-medium bg-info-50 text-info-600">新配房</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="bg-primary-50 text-primary-700 text-xs px-2 py-0.5 rounded-full">求购</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700">二手</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[200px]" title="550-600万,100㎡-110㎡,3居,宝山">550-600万,100㎡-110㎡,3居,宝山</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<span class="text-sm text-neutral-700 font-medium">8套</span>
|
||||||
|
<button class="text-neutral-400 hover:text-info-600 transition-colors" title="查看配房详情">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[160px]" title="宝山·顾村,大华锦绣华城">宝山·顾村,大华锦绣华城</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700">张伟-都市港湾店一组</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="bg-warning-50 text-warning-600 px-2 py-0.5 rounded-full text-xs">一看</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">3次</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-600 tabular-nums">2026-03-15</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">今天</td>
|
||||||
|
<td class="px-3 py-2 text-center">
|
||||||
|
<button class="inline-flex items-center justify-center w-8 h-8 rounded-md text-primary-600 hover:bg-primary-50 hover:text-primary-700 transition-colors" title="拨号">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 0 1-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- 数据行 2 -->
|
||||||
|
<tr class="hover:bg-neutral-50 transition-colors"
|
||||||
|
:class="selected.includes('c002') ? 'bg-primary-50 hover:bg-primary-100' : ''">
|
||||||
|
<td class="w-10 px-4 py-2">
|
||||||
|
<input type="checkbox" value="c002" class="w-4 h-4 rounded accent-primary-600" x-model="selected">
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 min-w-[160px]">
|
||||||
|
<div class="flex flex-col gap-0.5">
|
||||||
|
<a href="/clients/private/c002/" class="text-info-600 hover:underline font-medium text-sm truncate max-w-[160px]">李晓敏</a>
|
||||||
|
<div class="flex items-center gap-1 flex-wrap">
|
||||||
|
<span class="text-[11px] text-neutral-500">B(较强)</span>
|
||||||
|
<span class="text-[11px] px-1.5 py-0.5 rounded-full font-medium bg-purple-50 text-purple-600">营销客</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="bg-info-50 text-info-600 text-xs px-2 py-0.5 rounded-full">求租</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700">租房</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[200px]" title="4000-6000元/月,60㎡-80㎡,2居,静安">4000-6000元/月,60㎡-80㎡,2居,静安</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<span class="text-sm text-neutral-700 font-medium">12套</span>
|
||||||
|
<button class="text-neutral-400 hover:text-info-600 transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[160px]">静安·南京西路</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700">陈丽-静安旗舰店二组</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-500">未带看</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">0次</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-600 tabular-nums">2026-04-10</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">3天前</td>
|
||||||
|
<td class="px-3 py-2 text-center">
|
||||||
|
<button class="inline-flex items-center justify-center w-8 h-8 rounded-md text-primary-600 hover:bg-primary-50 hover:text-primary-700 transition-colors" title="拨号">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 0 1-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- 数据行 3 -->
|
||||||
|
<tr class="hover:bg-neutral-50 transition-colors"
|
||||||
|
:class="selected.includes('c003') ? 'bg-primary-50 hover:bg-primary-100' : ''">
|
||||||
|
<td class="w-10 px-4 py-2">
|
||||||
|
<input type="checkbox" value="c003" class="w-4 h-4 rounded accent-primary-600" x-model="selected">
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 min-w-[160px]">
|
||||||
|
<div class="flex flex-col gap-0.5">
|
||||||
|
<a href="/clients/private/c003/" class="text-info-600 hover:underline font-medium text-sm truncate max-w-[160px]">赵志远</a>
|
||||||
|
<div class="flex items-center gap-1 flex-wrap">
|
||||||
|
<span class="text-[11px] text-neutral-500">A(急迫)</span>
|
||||||
|
<span class="text-[11px] px-1.5 py-0.5 rounded-full font-medium bg-warning-50 text-warning-600">即将过期</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="bg-warning-50 text-warning-600 text-xs px-2 py-0.5 rounded-full">租购</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700">二手</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[200px]" title="800-1000万,120㎡以上,4居,浦东">800-1000万,120㎡以上,4居,浦东</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<span class="text-sm text-neutral-700 font-medium">5套</span>
|
||||||
|
<button class="text-neutral-400 hover:text-info-600 transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[160px]">浦东·陆家嘴,世纪公园</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700">刘洋-浦东总店三组</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="bg-info-50 text-info-600 px-2 py-0.5 rounded-full text-xs">二看</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">5次</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-600 tabular-nums">2026-01-20</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">8天前</td>
|
||||||
|
<td class="px-3 py-2 text-center">
|
||||||
|
<button class="inline-flex items-center justify-center w-8 h-8 rounded-md text-primary-600 hover:bg-primary-50 hover:text-primary-700 transition-colors" title="拨号">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 0 1-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- 数据行 4 -->
|
||||||
|
<tr class="hover:bg-neutral-50 transition-colors"
|
||||||
|
:class="selected.includes('c004') ? 'bg-primary-50 hover:bg-primary-100' : ''">
|
||||||
|
<td class="w-10 px-4 py-2">
|
||||||
|
<input type="checkbox" value="c004" class="w-4 h-4 rounded accent-primary-600" x-model="selected">
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 min-w-[160px]">
|
||||||
|
<div class="flex flex-col gap-0.5">
|
||||||
|
<a href="/clients/private/c004/" class="text-info-600 hover:underline font-medium text-sm truncate max-w-[160px]">孙美玲</a>
|
||||||
|
<div class="flex items-center gap-1 flex-wrap">
|
||||||
|
<span class="text-[11px] text-neutral-500">C(一般)</span>
|
||||||
|
<span class="text-[11px] px-1.5 py-0.5 rounded-full font-medium bg-neutral-100 text-neutral-500">暂缓</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="bg-neutral-100 text-neutral-500 text-xs px-2 py-0.5 rounded-full">暂缓</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700">二手</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-500 truncate block max-w-[200px]">-</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<span class="text-sm text-neutral-500">0套</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-500">-</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700">魏深-都市港湾店一组</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-500">未带看</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">0次</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-600 tabular-nums">2026-04-01</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-danger-600 tabular-nums">32天前</td>
|
||||||
|
<td class="px-3 py-2 text-center">
|
||||||
|
<button class="inline-flex items-center justify-center w-8 h-8 rounded-md text-primary-600 hover:bg-primary-50 hover:text-primary-700 transition-colors" title="拨号">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 0 1-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- 数据行 5 -->
|
||||||
|
<tr class="hover:bg-neutral-50 transition-colors"
|
||||||
|
:class="selected.includes('c005') ? 'bg-primary-50 hover:bg-primary-100' : ''">
|
||||||
|
<td class="w-10 px-4 py-2">
|
||||||
|
<input type="checkbox" value="c005" class="w-4 h-4 rounded accent-primary-600" x-model="selected">
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 min-w-[160px]">
|
||||||
|
<div class="flex flex-col gap-0.5">
|
||||||
|
<a href="/clients/private/c005/" class="text-info-600 hover:underline font-medium text-sm truncate max-w-[160px]">陈建华</a>
|
||||||
|
<div class="flex items-center gap-1 flex-wrap">
|
||||||
|
<span class="text-[11px] text-neutral-500">B(较强)</span>
|
||||||
|
<span class="text-[11px] px-1.5 py-0.5 rounded-full font-medium bg-orange-50 text-orange-600">销售客</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="bg-primary-50 text-primary-700 text-xs px-2 py-0.5 rounded-full">求购</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700">新房</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[200px]" title="300-400万,90㎡-110㎡,3居,嘉定/青浦">300-400万,90㎡-110㎡,3居,嘉定/青浦</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<span class="text-sm text-neutral-700 font-medium">23套</span>
|
||||||
|
<button class="text-neutral-400 hover:text-info-600 transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[160px]">嘉定·新城,远香湖</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700">魏深-都市港湾店一组</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="bg-success-50 text-success-600 px-2 py-0.5 rounded-full text-xs">复看</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">7次</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-600 tabular-nums">2026-02-28</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">1天前</td>
|
||||||
|
<td class="px-3 py-2 text-center">
|
||||||
|
<button class="inline-flex items-center justify-center w-8 h-8 rounded-md text-primary-600 hover:bg-primary-50 hover:text-primary-700 transition-colors" title="拨号">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 0 1-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- 数据行 6 -->
|
||||||
|
<tr class="hover:bg-neutral-50 transition-colors"
|
||||||
|
:class="selected.includes('c006') ? 'bg-primary-50 hover:bg-primary-100' : ''">
|
||||||
|
<td class="w-10 px-4 py-2">
|
||||||
|
<input type="checkbox" value="c006" class="w-4 h-4 rounded accent-primary-600" x-model="selected">
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 min-w-[160px]">
|
||||||
|
<div class="flex flex-col gap-0.5">
|
||||||
|
<a href="/clients/private/c006/" class="text-info-600 hover:underline font-medium text-sm truncate max-w-[160px]">周小燕</a>
|
||||||
|
<div class="flex items-center gap-1 flex-wrap">
|
||||||
|
<span class="text-[11px] text-neutral-500">D(较弱)</span>
|
||||||
|
<span class="text-[11px] px-1.5 py-0.5 rounded-full font-medium bg-danger-50 text-danger-600">无效</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="bg-primary-50 text-primary-700 text-xs px-2 py-0.5 rounded-full">求购</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700">二手</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[200px]" title="200-300万,80㎡-100㎡,2居,普陀/长宁">200-300万,80㎡-100㎡,2居,普陀/长宁</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<span class="text-sm text-neutral-700 font-medium">2套</span>
|
||||||
|
<button class="text-neutral-400 hover:text-info-600 transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700 truncate block max-w-[160px]">普陀·长风</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-700">王芳-普陀新村店</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2">
|
||||||
|
<span class="text-sm text-neutral-500">未带看</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-700 tabular-nums">1次</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-neutral-600 tabular-nums">2025-12-01</td>
|
||||||
|
<td class="px-4 py-2 text-sm text-danger-600 tabular-nums">45天前</td>
|
||||||
|
<td class="px-3 py-2 text-center">
|
||||||
|
<button class="inline-flex items-center justify-center w-8 h-8 rounded-md text-primary-600 hover:bg-primary-50 hover:text-primary-700 transition-colors" title="拨号">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 0 1-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z"/></svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== 分页栏 ======== -->
|
||||||
|
<div class="mt-4 flex items-center justify-between px-1">
|
||||||
|
<!-- 左侧:总条数 -->
|
||||||
|
<div class="text-sm text-neutral-500">
|
||||||
|
共 <span class="font-medium text-neutral-800 tabular-nums">1,248</span> 条
|
||||||
|
</div>
|
||||||
|
<!-- 中间:页码 -->
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<button class="flex items-center gap-1 px-2.5 py-1.5 text-sm text-neutral-600 hover:bg-neutral-100 rounded-md transition-colors disabled:opacity-40 disabled:cursor-not-allowed">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5"/></svg>
|
||||||
|
上一页
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 flex items-center justify-center text-sm bg-primary-600 text-white rounded-md font-medium tabular-nums">1</button>
|
||||||
|
<button class="w-8 h-8 flex items-center justify-center text-sm text-neutral-600 hover:bg-neutral-100 rounded-md transition-colors tabular-nums">2</button>
|
||||||
|
<button class="w-8 h-8 flex items-center justify-center text-sm text-neutral-600 hover:bg-neutral-100 rounded-md transition-colors tabular-nums">3</button>
|
||||||
|
<button class="w-8 h-8 flex items-center justify-center text-sm text-neutral-600 hover:bg-neutral-100 rounded-md transition-colors tabular-nums">4</button>
|
||||||
|
<button class="w-8 h-8 flex items-center justify-center text-sm text-neutral-600 hover:bg-neutral-100 rounded-md transition-colors tabular-nums">5</button>
|
||||||
|
<span class="w-8 h-8 flex items-center justify-center text-sm text-neutral-400">…</span>
|
||||||
|
<button class="w-8 h-8 flex items-center justify-center text-sm text-neutral-600 hover:bg-neutral-100 rounded-md transition-colors tabular-nums">63</button>
|
||||||
|
<button class="flex items-center gap-1 px-2.5 py-1.5 text-sm text-neutral-600 hover:bg-neutral-100 rounded-md transition-colors">
|
||||||
|
下一页
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧:每页条数 + 跳页 -->
|
||||||
|
<div class="flex items-center gap-3 text-sm">
|
||||||
|
<select class="border border-neutral-300 rounded-md px-2 py-1.5 text-sm text-neutral-600 bg-white focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-600/40">
|
||||||
|
<option>20条/页</option>
|
||||||
|
<option>50条/页</option>
|
||||||
|
<option>100条/页</option>
|
||||||
|
</select>
|
||||||
|
<div class="flex items-center gap-1.5 text-neutral-500">
|
||||||
|
跳至
|
||||||
|
<input type="number" min="1" max="63"
|
||||||
|
class="w-14 px-2 py-1.5 border border-neutral-300 rounded-md text-center text-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-600/40 tabular-nums">
|
||||||
|
页
|
||||||
|
<button class="px-2.5 py-1.5 text-sm border border-neutral-300 rounded-md text-neutral-600 hover:bg-neutral-50 transition-colors">确定</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div><!-- /px-6 py-4 -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ======== 自定义列弹窗 ======== -->
|
||||||
|
<div x-show="showColumnModal" x-cloak
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
x-transition:enter="ease-out duration-200"
|
||||||
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="ease-in duration-150"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0">
|
||||||
|
<!-- Overlay -->
|
||||||
|
<div class="absolute inset-0 bg-neutral-900/40 backdrop-blur-sm" @click="showColumnModal = false"></div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div class="relative bg-white rounded-xl shadow-xl w-full max-w-2xl flex flex-col max-h-[80vh]"
|
||||||
|
x-transition:enter="ease-out duration-200"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95 translate-y-2"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100 translate-y-0">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="flex items-center justify-between px-6 py-4 border-b border-neutral-200">
|
||||||
|
<h2 class="text-base font-semibold text-neutral-800">自定义信息</h2>
|
||||||
|
<button @click="showColumnModal = false" class="text-neutral-400 hover:text-neutral-600 transition-colors">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<!-- Body -->
|
||||||
|
<div class="flex flex-1 overflow-hidden">
|
||||||
|
<!-- 左栏:未选信息 -->
|
||||||
|
<div class="w-1/2 border-r border-neutral-200 overflow-y-auto">
|
||||||
|
<div class="px-4 py-3 text-xs font-semibold text-neutral-500 uppercase tracking-wide border-b border-neutral-100">未选信息</div>
|
||||||
|
<div class="p-3 space-y-1">
|
||||||
|
<label class="flex items-center gap-2.5 px-2 py-2 rounded-md hover:bg-neutral-50 cursor-pointer">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> <span class="text-sm text-neutral-700">录入日期</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-2.5 px-2 py-2 rounded-md hover:bg-neutral-50 cursor-pointer">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> <span class="text-sm text-neutral-700">最近通话日期</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-2.5 px-2 py-2 rounded-md hover:bg-neutral-50 cursor-pointer">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> <span class="text-sm text-neutral-700">用途</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-2.5 px-2 py-2 rounded-md hover:bg-neutral-50 cursor-pointer">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> <span class="text-sm text-neutral-700">来源</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-2.5 px-2 py-2 rounded-md hover:bg-neutral-50 cursor-pointer">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> <span class="text-sm text-neutral-700">客源编号</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-2.5 px-2 py-2 rounded-md hover:bg-neutral-50 cursor-pointer">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> <span class="text-sm text-neutral-700">首录人</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-2.5 px-2 py-2 rounded-md hover:bg-neutral-50 cursor-pointer">
|
||||||
|
<input type="checkbox" class="w-4 h-4 rounded accent-primary-600"> <span class="text-sm text-neutral-700">成交人</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 右栏:已选信息 -->
|
||||||
|
<div class="w-1/2 overflow-y-auto">
|
||||||
|
<div class="px-4 py-3 text-xs font-semibold text-neutral-500 uppercase tracking-wide border-b border-neutral-100">已选信息</div>
|
||||||
|
<div class="p-3 space-y-1">
|
||||||
|
<!-- 固定字段(不可删) -->
|
||||||
|
<div class="flex items-center gap-2 px-2 py-2 rounded-md bg-neutral-50">
|
||||||
|
<svg class="w-4 h-4 text-neutral-300 cursor-grab" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 5.25h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5"/></svg>
|
||||||
|
<span class="text-sm text-neutral-700 flex-1">姓名</span>
|
||||||
|
<svg class="w-3.5 h-3.5 text-neutral-300" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z"/></svg>
|
||||||
|
</div>
|
||||||
|
<!-- 可删字段 -->
|
||||||
|
<template x-for="(col, idx) in selectedColumns" :key="col">
|
||||||
|
<div class="flex items-center gap-2 px-2 py-2 rounded-md hover:bg-neutral-50 group">
|
||||||
|
<svg class="w-4 h-4 text-neutral-300 cursor-grab group-hover:text-neutral-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 5.25h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5"/></svg>
|
||||||
|
<span class="text-sm text-neutral-700 flex-1" x-text="col"></span>
|
||||||
|
<button @click="selectedColumns.splice(idx, 1)" class="text-neutral-400 hover:text-danger-600 transition-colors opacity-0 group-hover:opacity-100">
|
||||||
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<p class="px-5 pb-3 text-xs text-neutral-400">提示:拖拽可调整展示顺序</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Footer -->
|
||||||
|
<div class="flex items-center justify-between px-6 py-4 border-t border-neutral-200">
|
||||||
|
<button class="text-sm text-neutral-500 hover:text-neutral-700 transition-colors">恢复默认</button>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<button @click="showColumnModal = false" class="px-4 py-2 text-sm text-neutral-600 border border-neutral-300 rounded-lg hover:bg-neutral-50 transition-colors">取消</button>
|
||||||
|
<button @click="showColumnModal = false" class="px-4 py-2 text-sm font-medium bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-colors">确定</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div><!-- /modal -->
|
||||||
|
|
||||||
|
</main><!-- /clientListApp -->
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function clientListApp() {
|
||||||
|
return {
|
||||||
|
// 二级 Tab
|
||||||
|
activeTab: 'all',
|
||||||
|
tabs: [
|
||||||
|
{ key: 'buying', label: '求购', count: 913 },
|
||||||
|
{ key: 'renting', label: '求租', count: 187 },
|
||||||
|
{ key: 'suspended', label: '暂缓', count: null },
|
||||||
|
{ key: 'all', label: '全部私客', count: null },
|
||||||
|
],
|
||||||
|
|
||||||
|
// 筛选区展开
|
||||||
|
showFilters: true,
|
||||||
|
|
||||||
|
// 状态筛选选项
|
||||||
|
activeStatus: '',
|
||||||
|
statusOptions: [
|
||||||
|
{ value: '', label: '不限' },
|
||||||
|
{ value: 'buying', label: '求购' },
|
||||||
|
{ value: 'buy_or_rent', label: '租购' },
|
||||||
|
],
|
||||||
|
|
||||||
|
// 表格勾选
|
||||||
|
selected: [],
|
||||||
|
|
||||||
|
toggleAll(event) {
|
||||||
|
if (event.target.checked) {
|
||||||
|
this.selected = ['c001', 'c002', 'c003', 'c004', 'c005', 'c006'];
|
||||||
|
} else {
|
||||||
|
this.selected = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 自定义列弹窗
|
||||||
|
showColumnModal: false,
|
||||||
|
selectedColumns: ['状态', '需求类型', '需求/解读', '智能配房', '意向商圈/小区', '归属人', '带看进度', '带看次数', '委托日期', '最近时间'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -263,8 +263,7 @@
|
|||||||
<!-- 已存搜索 -->
|
<!-- 已存搜索 -->
|
||||||
<div x-data="{ open: false }" class="relative">
|
<div x-data="{ open: false }" class="relative">
|
||||||
<button @click="open = !open"
|
<button @click="open = !open"
|
||||||
class="text-sm text-neutral-500 hover:text-neutral-700
|
class="text-sm text-neutral-500 hover:text-neutral-700 flex items-center gap-1">
|
||||||
flex items-center gap-1">
|
|
||||||
<svg class="w-4 h-4"><!-- bookmark --></svg>
|
<svg class="w-4 h-4"><!-- bookmark --></svg>
|
||||||
<span>{{ saved_search_count }}条已存搜索</span>
|
<span>{{ saved_search_count }}条已存搜索</span>
|
||||||
<svg class="w-3 h-3"><!-- chevron-down --></svg>
|
<svg class="w-3 h-3"><!-- chevron-down --></svg>
|
||||||
@@ -1090,15 +1089,15 @@ buy_or_rent(租购)→ public(公客)[不可逆]
|
|||||||
|
|
||||||
## 9. 开放问题(待决策)
|
## 9. 开放问题(待决策)
|
||||||
|
|
||||||
| # | 问题 | 影响范围 | 待确认方 |
|
| # | 问题 | 影响范围 | 待确认方 | 回答 |
|
||||||
| --- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ------------------- |
|
| --- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ------------------- | ----------- |
|
||||||
| 1 | 「资料客」「营销客」Tab 在 MVP 阶段是否展示为灰色禁用 Tab,还是直接不显示? | 一级 Tab 导航 §2.1.3 | 产品经理 |
|
| 1 | 「资料客」「营销客」Tab 在 MVP 阶段是否展示为灰色禁用 Tab,还是直接不显示? | 一级 Tab 导航 §2.1.3 | 产品经理 | 展示为灰色禁用 |
|
||||||
| 2 | 二级 Tab 上的客源数量 Badge(如「求购 913」)是否实时计数?若是,是否有性能开销?建议改为后端分 Tab 预聚合或缓存 | 二级 Tab §2.1.3 | 后端 + 产品 |
|
| 2 | 二级 Tab 上的客源数量 Badge(如「求购 913」)是否实时计数?若是,是否有性能开销?建议改为后端分 Tab 预聚合或缓存 | 二级 Tab §2.1.3 | 后端 + 产品 | 改为后端分Tab预聚合 |
|
||||||
| 3 | 「与我相关」和「我部门相关」的精确业务定义:经纪人同时是首录人和归属人时,「与我相关」指 `owner_id=me OR first_recorder_id=me`?还是仅 `owner_id=me`? | 快捷筛选行 §2.1.3 | 产品经理 |
|
| 3 | 「与我相关」和「我部门相关」的精确业务定义:经纪人同时是首录人和归属人时,「与我相关」指 `owner_id=me OR first_recorder_id=me`?还是仅 `owner_id=me`? | 快捷筛选行 §2.1.3 | 产品经理 | owner_id=me |
|
||||||
| 4 | 「即将掉公」筛选的时间阈值(距自动转公还有多少天开始提示)是运营后台可配置项还是硬编码?需要前端在筛选行旁边展示剩余天数吗? | 快捷筛选行 | 产品 + 后端 |
|
| 4 | 「即将掉公」筛选的时间阈值(距自动转公还有多少天开始提示)是运营后台可配置项还是硬编码?需要前端在筛选行旁边展示剩余天数吗? | 快捷筛选行 | 产品 + 后端 | 后台可配置 |
|
||||||
| 5 | 价格筛选的自定义区间输入:用户手动输入后是否需要点击「搜索」按钮才触发,还是 blur 后自动 HTMX?(与其他 Tag 筛选项行为需统一) | 价格筛选 §2.1.3 | 产品经理 |
|
| 5 | 价格筛选的自定义区间输入:用户手动输入后是否需要点击「搜索」按钮才触发,还是 blur 后自动 HTMX?(与其他 Tag 筛选项行为需统一) | 价格筛选 §2.1.3 | 产品经理 | blur后自动HTMX |
|
||||||
| 6 | 表格「最近时间」列:PRD 写的是「最近时间」(最近跟进或带看的距今天数),截图中显示「N天前」+ 日期(如`2026-04-19`)两行,是否需要双行展示? | 表格列定义 §2.1.3 | 产品经理(截图已有双行,建议对齐截图) |
|
| 6 | 表格「最近时间」列:PRD 写的是「最近时间」(最近跟进或带看的距今天数),截图中显示「N天前」+ 日期(如`2026-04-19`)两行,是否需要双行展示? | 表格列定义 §2.1.3 | 产品经理(截图已有双行,建议对齐截图) | |
|
||||||
| 7 | 导出功能:Celery 异步生成后如何通知用户下载?WebSocket Push / 轮询 / 下载中心页?MVP 阶段建议使用轮询+下载链接 Toast | 导出按钮 §2.1.3 | 后端 + 产品 |
|
| 7 | 导出功能:Celery 异步生成后如何通知用户下载?WebSocket Push / 轮询 / 下载中心页?MVP 阶段建议使用轮询+下载链接 Toast | 导出按钮 §2.1.3 | 后端 + 产品 | 可在通知中心里显示消息 |
|
||||||
| 8 | 批量合并客源:需要独立的合并规则弹窗(选择主记录 + 字段合并规则),复杂度高,是否降级到 P2? | 工具栏批量操作 | 产品经理 |
|
| 8 | 批量合并客源:需要独立的合并规则弹窗(选择主记录 + 字段合并规则),复杂度高,是否降级到 P2? | 工具栏批量操作 | 产品经理 | P0不做 |
|
||||||
| 9 | 转成交弹窗中「成交方」人员选择器:默认带入当前用户所属门店,支持修改的范围是全司还是当前用户权限内? | 详情页转成交弹窗(待详情页文档) | 产品 + 后端 |
|
| 9 | 转成交弹窗中「成交方」人员选择器:默认带入当前用户所属门店,支持修改的范围是全司还是当前用户权限内? | 详情页转成交弹窗(待详情页文档) | 产品 + 后端 | 全司 |
|
||||||
| 10 | 活跃度标签「营销客」「销售客」「访客」的触发条件(截图可见但 DATA_MODEL_CLIENT.md 中的 `activity_level` 枚举不含这三项):这些是 `source` 字段衍生的展示标签,还是独立的 `activity_level` 值?需后端澄清 | 活跃度标签渲染 §2.1.3 | 后端 |
|
| 10 | 活跃度标签「营销客」「销售客」「访客」的触发条件(截图可见但 DATA_MODEL_CLIENT.md 中的 `activity_level` 枚举不含这三项):这些是 `source` 字段衍生的展示标签,还是独立的 `activity_level` 值?需后端澄清 | 活跃度标签渲染 §2.1.3 | 后端 | 后台可配置 |
|
||||||
@@ -294,6 +294,7 @@ activeSection: 'section-requirements'
|
|||||||
- 带看进度(如「一看」):`bg-primary-50 text-primary-700`
|
- 带看进度(如「一看」):`bg-primary-50 text-primary-700`
|
||||||
- 等级(如「C(一般)」):`bg-warning-50 text-warning-600`
|
- 等级(如「C(一般)」):`bg-warning-50 text-warning-600`
|
||||||
- 统一尺寸:`inline-flex items-center px-1.5 py-0.5 text-xs rounded`
|
- 统一尺寸:`inline-flex items-center px-1.5 py-0.5 text-xs rounded`
|
||||||
|
- 右侧文字链「编辑」`text-sm text-primary-600 hover:text-primary-700 hover:underline underline-offset-2`
|
||||||
|
|
||||||
**字段列表**(`dl space-y-1.5`):
|
**字段列表**(`dl space-y-1.5`):
|
||||||
- 每行:`grid grid-cols-[72px_1fr] gap-2`
|
- 每行:`grid grid-cols-[72px_1fr] gap-2`
|
||||||
@@ -737,11 +737,11 @@ Alpine.js 控制展开/收起,初始折叠。
|
|||||||
|
|
||||||
## 8. 开放问题(待决策)
|
## 8. 开放问题(待决策)
|
||||||
|
|
||||||
| # | 问题 | 影响范围 | 待确认方 |
|
| # | 问题 | 影响范围 | 待确认方 | 回答问题 |
|
||||||
|---|------|---------|---------|
|
| --- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ----- | ------------------ |
|
||||||
| 1 | **主操作按钮颜色**:竞品截图和 PRD 均描述「确定」为橙色,但 Fonrey 设计规范主色为 Teal(`primary-600`)。应使用 `warning-600`(与竞品一致,橙色)还是 `primary-600`(与全局规范一致,Teal)? | §2.1.3 区域E,影响全模块提交按钮 | 产品/设计 |
|
| 1 | **主操作按钮颜色**:竞品截图和 PRD 均描述「确定」为橙色,但 Fonrey 设计规范主色为 Teal(`primary-600`)。应使用 `warning-600`(与竞品一致,橙色)还是 `primary-600`(与全局规范一致,Teal)? | §2.1.3 区域E,影响全模块提交按钮 | 产品/设计 | `primary-600`和全局一致 |
|
||||||
| 2 | **联系人上限**:PRD §5.2.2 写「理论上不限联系人数量(建议上限5个)」,本文档取5个上限。是否采用5个或其他数量? | §2.1.3 区域B | 产品 |
|
| 2 | **联系人上限**:PRD §5.2.2 写「理论上不限联系人数量(建议上限5个)」,本文档取5个上限。是否采用5个或其他数量? | §2.1.3 区域B | 产品 | 3个 |
|
||||||
| 3 | **来源枚举加载时机**:来源下拉是页面加载时随 Django 模板渲染(同步),还是通过 HTMX 异步加载?若系统配置中来源枚举较少(<50条),推荐同步渲染 | §2.1.3 区域C,§4.3 HTMX规范 | 后端/产品 |
|
| 3 | **来源枚举加载时机**:来源下拉是页面加载时随 Django 模板渲染(同步),还是通过 HTMX 异步加载?若系统配置中来源枚举较少(<50条),推荐同步渲染 | §2.1.3 区域C,§4.3 HTMX规范 | 后端/产品 | |
|
||||||
| 4 | **电话重复检测后是否阻断提交**:当前方案为「警告不阻断」(允许继续提交),与 PRD §5.2.5 一致。是否在产品层面确认不需要强制阻断(即两人同一号码可同时保存)? | §4.3 电话检测行为 | 产品 |
|
| 4 | **电话重复检测后是否阻断提交**:当前方案为「警告不阻断」(允许继续提交),与 PRD §5.2.5 一致。是否在产品层面确认不需要强制阻断(即两人同一号码可同时保存)? | §4.3 电话检测行为 | 产品 | |
|
||||||
| 5 | **意向学校数据源**:PRD §5.2.3 录入页为「下拉多选」,但编辑页截图显示为「文本输入 + 添加学校」。本文档以截图为准取文本输入。若产品希望关联楼盘数据库中的学校,需改为带搜索的下拉选择器 | §3.2.2 意向学校字段 | 产品/数据 |
|
| 5 | **意向学校数据源**:PRD §5.2.3 录入页为「下拉多选」,但编辑页截图显示为「文本输入 + 添加学校」。本文档以截图为准取文本输入。若产品希望关联楼盘数据库中的学校,需改为带搜索的下拉选择器 | §3.2.2 意向学校字段 | 产品/数据 | 改为带搜索的下拉选择器 |
|
||||||
| 6 | **区号选择器完整枚举**:目前仅列出常用5个区号(+86/+852/+853/+886/+1)。是否需要完整的国际区号列表(约240+)?若是,建议实现带搜索的 Alpine.js 自定义下拉,而非原生 `<select>` | §2.1.3 电话1规范 | 产品 |
|
| 6 | **区号选择器完整枚举**:目前仅列出常用5个区号(+86/+852/+853/+886/+1)。是否需要完整的国际区号列表(约240+)?若是,建议实现带搜索的 Alpine.js 自定义下拉,而非原生 `<select>` | §2.1.3 电话1规范 | 产品 | 只保留+86 |
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -230,3 +230,74 @@
|
|||||||
- 对于同一模块内页面较多的情况(如房源管理有列表、详情、新增、跟进等多个页面),**全部包含在同一份文档中**,通过 `§2.N` 分节区分
|
- 对于同一模块内页面较多的情况(如房源管理有列表、详情、新增、跟进等多个页面),**全部包含在同一份文档中**,通过 `§2.N` 分节区分
|
||||||
- 弹窗数量较多时(如房源详情有 10+ 个编辑弹窗),可以将**结构相似的弹窗合并为一个通用弹窗规范**,仅列出字段差异表
|
- 弹窗数量较多时(如房源详情有 10+ 个编辑弹窗),可以将**结构相似的弹窗合并为一个通用弹窗规范**,仅列出字段差异表
|
||||||
- 生成完成后,将文档路径更新到上方「已生成的模块 UI 设计文档」表格中
|
- 生成完成后,将文档路径更新到上方「已生成的模块 UI 设计文档」表格中
|
||||||
|
|
||||||
|
# 任务:为客源详情生成模块 UI 静态原型
|
||||||
|
|
||||||
|
## 你的角色
|
||||||
|
|
||||||
|
你是 Fonrey 房产经纪管理系统的 **UI/UX 架构师**,负责根据竞品截图和 PRD 功能描述,产出一份标准化的模块级 UI 设计文档。该文档将直接交给 AI Engineer 用于编码实现,必须包含足够的细节,Engineer 无需再问任何问题。
|
||||||
|
|
||||||
|
**注意**
|
||||||
|
以下所有的文档或图片是基于文档库的相对路径。
|
||||||
|
文档库的根路径为:`/mnt/d/Workspace/nexus`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 全局设计约束(必须严格遵守)
|
||||||
|
|
||||||
|
> 所有设计决策必须符合 `Project/fonrey/UI_SYSTEM/UI_SYSTEM.md` 中的设计规范。核心约束如下:
|
||||||
|
|
||||||
|
- **技术栈**:Tailwind CSS + HTMX + Alpine.js + Django HTML 模板(非 React/Vue/JSX)
|
||||||
|
- **图标库**:Heroicons v2(Outline 24px 默认,Solid 20px 强调,Mini 16px 极密场景)
|
||||||
|
- **主色**:Teal `#0F766E`(`primary-600`),所有颜色引用 Token,禁止硬编码 Hex
|
||||||
|
- **圆角**:`rounded-lg`(8px)为默认,表格行/小组件用 `rounded-md`(6px)
|
||||||
|
- **表格行高**:56px(`h-14`)
|
||||||
|
- **字体**:Inter + PingFang SC,正文 `text-sm`(14px)
|
||||||
|
- **焦点环**:`focus-visible:ring-2 focus-visible:ring-primary-600/40`
|
||||||
|
- **桌面优先**:≥1280px,不做移动端适配
|
||||||
|
- **禁止独立 CSS 文件或 CSS-in-JS**:所有样式用 Tailwind utility class(少量例外如 Flatpickr 覆盖样式)
|
||||||
|
- **组件实现参考**:`Project/fonrey/UI_SYSTEM/组件规范设计.md`(含 20 个特殊组件的完整 HTML + Alpine.js 实现)
|
||||||
|
|
||||||
|
|
||||||
|
**输入文件**
|
||||||
|
1. 【UI_SYSTEM】全局UI设计规范文档 `Project/fonrey/UI_SYSTEM/UI_SYSTEM.md`
|
||||||
|
2. 【现有原型页面】已完成的HTML页面(作为视觉和代码参考基准)
|
||||||
|
- `Project/fonrey/UI_SYSTEM/preview.html`
|
||||||
|
3. 【本次模块UI设计文档】本次需要实现的模块设计说明
|
||||||
|
- `Project/fonrey/UI_DESIGN/客源详情_UI.md`
|
||||||
|
**输出文件**
|
||||||
|
- 【本次模块UI输出静态原型文件】
|
||||||
|
- `Project/fonrey/UI_DESIGN/客源详情_UI.html`
|
||||||
|
|
||||||
|
### 强制约束(不可违反)
|
||||||
|
|
||||||
|
#### 一致性约束
|
||||||
|
- 颜色、字体、字号、圆角、阴影、间距等视觉变量,必须与 UI_SYSTEM 保持完全一致,不得自行创造新的变量
|
||||||
|
- 公共组件(导航栏、侧边栏、顶部栏、按钮、表单、卡片、标签等)的样式和结构,必须与现有原型页面中的实现保持一致
|
||||||
|
- 如果现有页面使用了 CSS 变量或特定 class 命名规范,本次输出必须沿用相同的规范
|
||||||
|
|
||||||
|
#### 布局约束
|
||||||
|
- 整体页面框架(如侧边栏宽度、顶栏高度、内容区边距)必须与现有原型页面保持一致
|
||||||
|
- 响应式断点策略(如有)需与已有页面对齐
|
||||||
|
#### 代码约束
|
||||||
|
- 输出单一 HTML 文件,CSS 写在 `<style>` 标签内,JS 写在 `<script>` 标签内
|
||||||
|
- 不引入任何外部依赖,除非现有原型页面已经使用了该依赖
|
||||||
|
- 类名、变量名的命名风格与现有代码保持一致
|
||||||
|
|
||||||
|
#### 执行步骤(按顺序执行)
|
||||||
|
1. 通读所有输入材料,识别 UI_SYSTEM 中的核心设计 token
|
||||||
|
2. 分析现有原型页面,提取公共组件的 HTML 结构和 CSS 实现
|
||||||
|
3. 阅读本次模块设计文档,理解页面结构、交互状态和内容层级
|
||||||
|
4. 以现有页面为外壳,将本次模块内容填入正确的内容区域
|
||||||
|
5. 对照设计文档逐项检查还原度,确认无遗漏后输出
|
||||||
|
|
||||||
|
#### 输出要求
|
||||||
|
- 直接输出完整可运行的 HTML 文件内容
|
||||||
|
- 页面中需要数据的地方使用合理的占位内容(不要留空)
|
||||||
|
- 交互状态(hover、active、selected、disabled)需在 CSS 中体现
|
||||||
|
- 输出完成后,列出你在本次实现中做出的所有设计假设或补充决策
|
||||||
|
|
||||||
|
#### 注意事项
|
||||||
|
- 如果设计文档与 UI_SYSTEM 存在冲突,以 UI_SYSTEM 为准,并告知我冲突点
|
||||||
|
- 如果设计文档描述不清晰,不要自行猜测,先列出疑问再继续
|
||||||
|
|
||||||
|
|||||||
@@ -205,3 +205,74 @@
|
|||||||
- 对于同一模块内页面较多的情况(如房源管理有列表、详情、新增、跟进等多个页面),**全部包含在同一份文档中**,通过 `§2.N` 分节区分
|
- 对于同一模块内页面较多的情况(如房源管理有列表、详情、新增、跟进等多个页面),**全部包含在同一份文档中**,通过 `§2.N` 分节区分
|
||||||
- 弹窗数量较多时(如房源详情有 10+ 个编辑弹窗),可以将**结构相似的弹窗合并为一个通用弹窗规范**,仅列出字段差异表
|
- 弹窗数量较多时(如房源详情有 10+ 个编辑弹窗),可以将**结构相似的弹窗合并为一个通用弹窗规范**,仅列出字段差异表
|
||||||
- 生成完成后,将文档路径更新到上方「已生成的模块 UI 设计文档」表格中
|
- 生成完成后,将文档路径更新到上方「已生成的模块 UI 设计文档」表格中
|
||||||
|
|
||||||
|
|
||||||
|
# 任务:为客源列表生成模块 UI 静态原型
|
||||||
|
|
||||||
|
## 你的角色
|
||||||
|
|
||||||
|
你是 Fonrey 房产经纪管理系统的 **UI/UX 架构师**,负责根据竞品截图和 PRD 功能描述,产出一份标准化的模块级 UI 设计文档。该文档将直接交给 AI Engineer 用于编码实现,必须包含足够的细节,Engineer 无需再问任何问题。
|
||||||
|
|
||||||
|
**注意**
|
||||||
|
以下所有的文档或图片是基于文档库的相对路径。
|
||||||
|
文档库的根路径为:`/mnt/d/Workspace/nexus`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 全局设计约束(必须严格遵守)
|
||||||
|
|
||||||
|
> 所有设计决策必须符合 `Project/fonrey/UI_SYSTEM/UI_SYSTEM.md` 中的设计规范。核心约束如下:
|
||||||
|
|
||||||
|
- **技术栈**:Tailwind CSS + HTMX + Alpine.js + Django HTML 模板(非 React/Vue/JSX)
|
||||||
|
- **图标库**:Heroicons v2(Outline 24px 默认,Solid 20px 强调,Mini 16px 极密场景)
|
||||||
|
- **主色**:Teal `#0F766E`(`primary-600`),所有颜色引用 Token,禁止硬编码 Hex
|
||||||
|
- **圆角**:`rounded-lg`(8px)为默认,表格行/小组件用 `rounded-md`(6px)
|
||||||
|
- **表格行高**:56px(`h-14`)
|
||||||
|
- **字体**:Inter + PingFang SC,正文 `text-sm`(14px)
|
||||||
|
- **焦点环**:`focus-visible:ring-2 focus-visible:ring-primary-600/40`
|
||||||
|
- **桌面优先**:≥1280px,不做移动端适配
|
||||||
|
- **禁止独立 CSS 文件或 CSS-in-JS**:所有样式用 Tailwind utility class(少量例外如 Flatpickr 覆盖样式)
|
||||||
|
- **组件实现参考**:`Project/fonrey/UI_SYSTEM/组件规范设计.md`(含 20 个特殊组件的完整 HTML + Alpine.js 实现)
|
||||||
|
|
||||||
|
|
||||||
|
**输入文件**
|
||||||
|
1. 【UI_SYSTEM】全局UI设计规范文档 `Project/fonrey/UI_SYSTEM/UI_SYSTEM.md`
|
||||||
|
2. 【现有原型页面】已完成的HTML页面(作为视觉和代码参考基准)
|
||||||
|
- `Project/fonrey/UI_SYSTEM/preview.html`
|
||||||
|
3. 【本次模块UI设计文档】本次需要实现的模块设计说明
|
||||||
|
- `Project/fonrey/UI_DESIGN/客源列表_UI.md`
|
||||||
|
**输出文件**
|
||||||
|
- 【本次模块UI输出静态原型文件】
|
||||||
|
- `Project/fonrey/UI_DESIGN/客源列表_UI.html`
|
||||||
|
|
||||||
|
### 强制约束(不可违反)
|
||||||
|
|
||||||
|
#### 一致性约束
|
||||||
|
- 颜色、字体、字号、圆角、阴影、间距等视觉变量,必须与 UI_SYSTEM 保持完全一致,不得自行创造新的变量
|
||||||
|
- 公共组件(导航栏、侧边栏、顶部栏、按钮、表单、卡片、标签等)的样式和结构,必须与现有原型页面中的实现保持一致
|
||||||
|
- 如果现有页面使用了 CSS 变量或特定 class 命名规范,本次输出必须沿用相同的规范
|
||||||
|
|
||||||
|
#### 布局约束
|
||||||
|
- 整体页面框架(如侧边栏宽度、顶栏高度、内容区边距)必须与现有原型页面保持一致
|
||||||
|
- 响应式断点策略(如有)需与已有页面对齐
|
||||||
|
#### 代码约束
|
||||||
|
- 输出单一 HTML 文件,CSS 写在 `<style>` 标签内,JS 写在 `<script>` 标签内
|
||||||
|
- 不引入任何外部依赖,除非现有原型页面已经使用了该依赖
|
||||||
|
- 类名、变量名的命名风格与现有代码保持一致
|
||||||
|
|
||||||
|
#### 执行步骤(按顺序执行)
|
||||||
|
1. 通读所有输入材料,识别 UI_SYSTEM 中的核心设计 token
|
||||||
|
2. 分析现有原型页面,提取公共组件的 HTML 结构和 CSS 实现
|
||||||
|
3. 阅读本次模块设计文档,理解页面结构、交互状态和内容层级
|
||||||
|
4. 以现有页面为外壳,将本次模块内容填入正确的内容区域
|
||||||
|
5. 对照设计文档逐项检查还原度,确认无遗漏后输出
|
||||||
|
|
||||||
|
#### 输出要求
|
||||||
|
- 直接输出完整可运行的 HTML 文件内容
|
||||||
|
- 页面中需要数据的地方使用合理的占位内容(不要留空)
|
||||||
|
- 交互状态(hover、active、selected、disabled)需在 CSS 中体现
|
||||||
|
- 输出完成后,列出你在本次实现中做出的所有设计假设或补充决策
|
||||||
|
|
||||||
|
#### 注意事项
|
||||||
|
- 如果设计文档与 UI_SYSTEM 存在冲突,以 UI_SYSTEM 为准,并告知我冲突点
|
||||||
|
- 如果设计文档描述不清晰,不要自行猜测,先列出疑问再继续
|
||||||
|
|||||||
Reference in New Issue
Block a user