chore: sync local project changes
This commit is contained in:
513
Project/fonrey/UI_DESIGN/楼盘列表_UI.html
Normal file
513
Project/fonrey/UI_DESIGN/楼盘列表_UI.html
Normal file
@@ -0,0 +1,513 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=1280" />
|
||||
<title>Fonrey 楼盘列表 · 静态原型</title>
|
||||
<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' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
:root {
|
||||
--bg-page: #F8FAFC;
|
||||
--bg-card: #FFFFFF;
|
||||
--bg-subtle: #F1F5F9;
|
||||
--text-primary: #0F172A;
|
||||
--text-secondary: #64748B;
|
||||
--border: #E2E8F0;
|
||||
}
|
||||
|
||||
html { scroll-behavior: smooth; }
|
||||
body {
|
||||
background: var(--bg-page);
|
||||
color: var(--text-primary);
|
||||
transition: background-color .2s ease, color .2s ease;
|
||||
}
|
||||
[x-cloak] { display: none !important; }
|
||||
.tabular-nums { font-variant-numeric: tabular-nums; }
|
||||
|
||||
.bg-surface { background: var(--bg-card); }
|
||||
.bg-subtle { background: var(--bg-subtle); }
|
||||
.border-surface { border-color: var(--border); }
|
||||
.text-surface { color: var(--text-primary); }
|
||||
.text-muted { color: var(--text-secondary); }
|
||||
|
||||
.module-tab {
|
||||
color: #64748B;
|
||||
border-bottom: 2px solid transparent;
|
||||
}
|
||||
.module-tab.active {
|
||||
color: #0F766E;
|
||||
border-bottom-color: #0F766E;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.chip {
|
||||
border: 1px solid #E2E8F0;
|
||||
background: #FFFFFF;
|
||||
color: #64748B;
|
||||
}
|
||||
.chip.active {
|
||||
border-color: #0F766E;
|
||||
color: #0F766E;
|
||||
background: #F0FDFA;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar { width: 8px; height: 8px; }
|
||||
::-webkit-scrollbar-thumb { background: #CBD5E1; border-radius: 4px; }
|
||||
::-webkit-scrollbar-thumb:hover { background: #94A3B8; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="text-sm antialiased" x-data="complexListPage()" x-init="init()">
|
||||
<!-- Top Bar -->
|
||||
<header class="fixed top-0 left-0 right-0 h-14 z-20 bg-primary-800 flex items-center justify-between">
|
||||
<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 text-sm font-semibold">F</div>
|
||||
<span class="text-base font-semibold text-white">Fonrey</span>
|
||||
</div>
|
||||
<nav class="flex items-center gap-1 flex-1 px-2" aria-label="主导航">
|
||||
<a class="px-3 py-1.5 text-sm rounded-md text-primary-100 hover:bg-primary-700 hover:text-white">工作台</a>
|
||||
<a class="px-3 py-1.5 text-sm rounded-md bg-primary-600 text-white font-medium">房源</a>
|
||||
<a class="px-3 py-1.5 text-sm rounded-md text-primary-100 hover:bg-primary-700 hover:text-white">客源</a>
|
||||
<a class="px-3 py-1.5 text-sm rounded-md text-primary-100 hover:bg-primary-700 hover:text-white">营销</a>
|
||||
<a class="px-3 py-1.5 text-sm rounded-md text-primary-100 hover:bg-primary-700 hover:text-white">交易</a>
|
||||
<a class="px-3 py-1.5 text-sm rounded-md text-primary-100 hover:bg-primary-700 hover:text-white">数据</a>
|
||||
<a class="px-3 py-1.5 text-sm rounded-md text-primary-100 hover:bg-primary-700 hover:text-white">人事</a>
|
||||
<a class="px-3 py-1.5 text-sm rounded-md text-primary-100 hover:bg-primary-700 hover:text-white">系统</a>
|
||||
</nav>
|
||||
<div class="flex items-center gap-1 px-4 shrink-0">
|
||||
<button class="p-1.5 text-primary-200 hover:bg-primary-700 hover:text-white rounded-md" aria-label="消息">
|
||||
<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>
|
||||
</button>
|
||||
<div class="flex items-center gap-2 pl-3 ml-1 border-l border-primary-700">
|
||||
<div class="w-8 h-8 rounded-full bg-primary-600 text-white flex items-center justify-center text-sm font-semibold">魏</div>
|
||||
<span class="text-sm font-medium text-primary-100">魏深</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Side Bar -->
|
||||
<aside class="fixed left-0 top-14 h-[calc(100vh-56px)] w-60 z-20 border-r border-surface bg-surface overflow-y-auto">
|
||||
<nav class="p-3 space-y-0.5">
|
||||
<div class="px-2 pt-2 pb-1 text-xs font-medium text-muted uppercase tracking-wide">房源管理</div>
|
||||
<a class="flex items-center gap-2 px-2 py-1.5 rounded-md bg-primary-50 text-primary-700 font-medium">楼盘管理</a>
|
||||
<a class="flex items-center gap-2 px-2 py-1.5 rounded-md text-neutral-700 hover:bg-neutral-100">房源列表</a>
|
||||
<a class="flex items-center gap-2 px-2 py-1.5 rounded-md text-neutral-700 hover:bg-neutral-100">新增房源</a>
|
||||
<a class="flex items-center gap-2 px-2 py-1.5 rounded-md text-neutral-700 hover:bg-neutral-100">成交房源</a>
|
||||
<a class="flex items-center gap-2 px-2 py-1.5 rounded-md text-neutral-700 hover:bg-neutral-100">已删房源</a>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<!-- Main -->
|
||||
<main class="ml-60 pt-[72px] min-h-screen px-6 py-5">
|
||||
<div class="mx-auto max-w-[1680px] space-y-4">
|
||||
<!-- Breadcrumb + title -->
|
||||
<section class="bg-surface border border-surface rounded-lg p-4">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<nav class="flex items-center gap-1 text-xs text-muted mb-2" aria-label="面包屑">
|
||||
<a href="#" class="hover:text-neutral-700">房源</a>
|
||||
<span>/</span>
|
||||
<a href="#" class="hover:text-neutral-700">小区</a>
|
||||
<span>/</span>
|
||||
<span class="text-surface">楼盘管理系统-楼盘管理</span>
|
||||
</nav>
|
||||
<h1 class="text-xl font-semibold text-surface">楼盘管理</h1>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Module Tabs -->
|
||||
<section class="bg-surface border border-surface rounded-lg px-4">
|
||||
<nav class="flex items-center gap-6 overflow-x-auto" aria-label="楼盘管理模块导航">
|
||||
<button class="module-tab py-3 whitespace-nowrap active">楼盘</button>
|
||||
<button class="module-tab py-3 whitespace-nowrap">区域管理</button>
|
||||
<button class="module-tab py-3 whitespace-nowrap">学校管理</button>
|
||||
<button class="module-tab py-3 whitespace-nowrap">应用标准数据</button>
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<!-- Completeness metrics -->
|
||||
<section class="bg-info-50 border border-info-600/20 rounded-lg p-3">
|
||||
<div class="flex items-center justify-between gap-3 mb-2">
|
||||
<h2 class="text-sm font-semibold text-info-600">数据完整度指标</h2>
|
||||
<button class="text-xs px-2 py-1 rounded border border-info-600/30 text-info-600 bg-white hover:bg-info-50" @click="notify('已触发重新计算(原型)')">重新计算</button>
|
||||
</div>
|
||||
<div class="grid grid-cols-7 gap-2 text-xs">
|
||||
<template x-for="item in metrics" :key="item.name">
|
||||
<div class="bg-white rounded-md border border-info-600/10 p-2">
|
||||
<p class="text-muted" x-text="item.name"></p>
|
||||
<p class="font-semibold tabular-nums mt-0.5" x-text="item.value"></p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Search + Filter -->
|
||||
<section class="bg-surface border border-surface rounded-lg p-4 space-y-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<input x-model.trim="filters.keyword" type="text" placeholder="楼盘名/别名/拼音/详细地址" class="w-[380px] px-3 py-2 rounded-md border border-surface bg-white focus:outline-none focus:ring-2 focus:ring-primary-600/40" />
|
||||
<button class="px-3 py-2 rounded-md bg-primary-600 text-white hover:bg-primary-700" @click="applyFilters()">查询</button>
|
||||
<button class="px-3 py-2 rounded-md border border-surface hover:bg-neutral-50" @click="resetFilters()">清除</button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<span class="text-xs text-muted">区域:</span>
|
||||
<template x-for="item in regionOptions" :key="item">
|
||||
<button class="chip px-2.5 py-1 rounded-md text-xs" :class="{ 'active': filters.region === item }" @click="filters.region = item" x-text="item"></button>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<span class="text-xs text-muted">用途:</span>
|
||||
<template x-for="item in usageOptions" :key="item">
|
||||
<button class="chip px-2.5 py-1 rounded-md text-xs" :class="{ 'active': filters.usage === item }" @click="filters.usage = item" x-text="item"></button>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-7 gap-2">
|
||||
<template x-for="cfg in extraFilters" :key="cfg.key">
|
||||
<select x-model="filters[cfg.key]" class="px-2.5 py-2 rounded-md border border-surface bg-white text-xs focus:outline-none focus:ring-2 focus:ring-primary-600/40">
|
||||
<option value="" x-text="cfg.label + ':不限'"></option>
|
||||
<template x-for="opt in cfg.options" :key="opt">
|
||||
<option :value="opt" x-text="opt"></option>
|
||||
</template>
|
||||
</select>
|
||||
</template>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Action bar -->
|
||||
<section class="bg-surface border border-surface rounded-lg p-3 flex items-center justify-between gap-3">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<button class="px-3 py-1.5 rounded-md bg-primary-600 text-white hover:bg-primary-700" @click="notify('新增楼盘(原型入口)')">+ 新增楼盘</button>
|
||||
<button class="px-3 py-1.5 rounded-md border border-surface" :disabled="selectedCount===0" :class="selectedCount===0 ? 'opacity-50 cursor-not-allowed' : 'hover:bg-neutral-50'">批量新增楼栋</button>
|
||||
<button class="px-3 py-1.5 rounded-md border border-surface" :disabled="selectedCount===0" :class="selectedCount===0 ? 'opacity-50 cursor-not-allowed' : 'hover:bg-neutral-50'">批改区域商圈</button>
|
||||
<button class="px-3 py-1.5 rounded-md border border-surface" :disabled="selectedCount===0" :class="selectedCount===0 ? 'opacity-50 cursor-not-allowed' : 'hover:bg-neutral-50'">删除</button>
|
||||
<button class="px-3 py-1.5 rounded-md border border-surface" :disabled="selectedCount===0" :class="selectedCount===0 ? 'opacity-50 cursor-not-allowed' : 'hover:bg-neutral-50'">合并楼盘</button>
|
||||
</div>
|
||||
|
||||
<div class="text-xs text-muted">
|
||||
<span x-show="selectedCount===0">未选中楼盘</span>
|
||||
<span x-show="selectedCount>0" x-text="'已选 ' + selectedCount + ' 条'"></span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Table -->
|
||||
<section class="bg-surface border border-surface rounded-lg overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full text-sm">
|
||||
<thead class="bg-subtle border-b border-surface">
|
||||
<tr class="text-left">
|
||||
<th scope="col" class="px-3 py-2 w-10">
|
||||
<input type="checkbox" class="rounded border-surface" :checked="allOnPageSelected" @click.prevent="toggleSelectPage(!allOnPageSelected)" aria-label="全选当前页" />
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-2">楼盘名称</th>
|
||||
<th scope="col" class="px-3 py-2">楼盘类型</th>
|
||||
<th scope="col" class="px-3 py-2">详细地址</th>
|
||||
<th scope="col" class="px-3 py-2">城区商圈</th>
|
||||
<th scope="col" class="px-3 py-2">当月挂牌均价(元/㎡)</th>
|
||||
<th scope="col" class="px-3 py-2">楼栋数</th>
|
||||
<th scope="col" class="px-3 py-2">产品数</th>
|
||||
<th scope="col" class="px-3 py-2">房源数</th>
|
||||
<th scope="col" class="px-3 py-2">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template x-if="paginatedRows.length === 0">
|
||||
<tr>
|
||||
<td colspan="10" class="px-4 py-12 text-center">
|
||||
<p class="text-base font-medium text-surface">暂无匹配楼盘</p>
|
||||
<p class="text-xs text-muted mt-1">请尝试调整筛选条件</p>
|
||||
<button class="mt-3 px-3 py-1.5 rounded-md border border-surface hover:bg-neutral-50" @click="resetFilters()">清除筛选</button>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<template x-for="row in paginatedRows" :key="row.id">
|
||||
<tr class="border-b border-surface hover:bg-neutral-50/50">
|
||||
<td class="px-3 py-2 align-top">
|
||||
<input type="checkbox" class="rounded border-surface" :checked="isSelected(row.id)" @click.prevent="toggleSelect(row.id, !isSelected(row.id))" aria-label="选择楼盘" />
|
||||
</td>
|
||||
<td class="px-3 py-2 align-top">
|
||||
<button class="text-left text-info-600 hover:underline font-medium" @click="openDetail(row)" x-text="row.name"></button>
|
||||
<div class="mt-1 flex items-center gap-1 flex-wrap">
|
||||
<span class="text-[10px] px-1.5 py-0.5 rounded-full bg-info-50 text-info-600">信息</span>
|
||||
<span class="text-[10px] px-1.5 py-0.5 rounded-full bg-warning-50 text-warning-600">标准楼盘</span>
|
||||
<span class="text-[10px] px-1.5 py-0.5 rounded-full bg-danger-50 text-danger-600">标准房号</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-3 py-2 align-top" x-text="row.usage"></td>
|
||||
<td class="px-3 py-2 align-top" x-text="row.address"></td>
|
||||
<td class="px-3 py-2 align-top" x-text="row.region + '-' + row.biz"></td>
|
||||
<td class="px-3 py-2 align-top tabular-nums" x-text="row.avgPrice"></td>
|
||||
<td class="px-3 py-2 align-top tabular-nums" x-text="row.buildingCount"></td>
|
||||
<td class="px-3 py-2 align-top tabular-nums" x-text="row.productCount"></td>
|
||||
<td class="px-3 py-2 align-top">
|
||||
<span class="text-xs text-muted">出售</span>
|
||||
<span class="tabular-nums" x-text="row.saleCount"></span>
|
||||
<span class="text-xs text-muted">/出租</span>
|
||||
<span class="tabular-nums" x-text="row.rentCount"></span>
|
||||
<span class="text-xs text-muted">/共</span>
|
||||
<span class="tabular-nums" x-text="row.saleCount + row.rentCount"></span>
|
||||
</td>
|
||||
<td class="px-3 py-2 align-top">
|
||||
<div class="flex items-center gap-2">
|
||||
<button class="text-info-600 hover:underline text-xs" @click="notify('编辑楼盘(原型)')">编辑</button>
|
||||
<button class="text-danger-600 hover:underline text-xs" @click="notify('删除楼盘(原型)')">删除</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Pagination -->
|
||||
<section class="bg-surface border border-surface rounded-lg px-4 py-3 flex items-center justify-between">
|
||||
<p class="text-xs text-muted" x-text="'共 ' + filteredRows.length + ' 条'" aria-live="polite"></p>
|
||||
|
||||
<div class="flex items-center gap-2 text-xs">
|
||||
<button class="px-2 py-1 rounded border border-surface" :disabled="currentPage===1" :class="currentPage===1 ? 'opacity-50 cursor-not-allowed' : 'hover:bg-neutral-50'" @click="goPrev()">上一页</button>
|
||||
<span class="tabular-nums" x-text="currentPage + ' / ' + totalPages"></span>
|
||||
<button class="px-2 py-1 rounded border border-surface" :disabled="currentPage===totalPages || totalPages===0" :class="(currentPage===totalPages || totalPages===0) ? 'opacity-50 cursor-not-allowed' : 'hover:bg-neutral-50'" @click="goNext()">下一页</button>
|
||||
|
||||
<span class="ml-2">20条/页</span>
|
||||
<span class="ml-2">跳至</span>
|
||||
<input type="number" min="1" :max="totalPages || 1" x-model.number="jumpPage" class="w-16 px-2 py-1 rounded border border-surface" />
|
||||
<button class="px-2 py-1 rounded border border-surface hover:bg-neutral-50" @click="goJump()">确定</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Toast -->
|
||||
<div x-show="toast.show" x-cloak class="fixed bottom-5 right-5 z-50 px-4 py-2 rounded-md text-sm text-white shadow-lg bg-success-600" x-text="toast.message"></div>
|
||||
|
||||
<script>
|
||||
function complexListPage() {
|
||||
return {
|
||||
rows: [],
|
||||
filters: {
|
||||
keyword: '',
|
||||
region: '不限',
|
||||
usage: '不限',
|
||||
fixedStatus: '',
|
||||
completion: '',
|
||||
complexType: '',
|
||||
hasProperty: '',
|
||||
buildingType: '',
|
||||
ownership: '',
|
||||
hasCoord: ''
|
||||
},
|
||||
regionOptions: ['不限', '静安', '闵行', '普陀', '松江', '长宁', '嘉定'],
|
||||
usageOptions: ['不限', '住宅', '别墅', '商住', '商业', '写字楼', '其他'],
|
||||
extraFilters: [
|
||||
{ key: 'fixedStatus', label: '固定情况', options: ['已固定', '未固定'] },
|
||||
{ key: 'completion', label: '完善情况', options: ['高', '中', '低'] },
|
||||
{ key: 'complexType', label: '楼盘类型', options: ['标准', '非标'] },
|
||||
{ key: 'hasProperty', label: '有无房源', options: ['有', '无'] },
|
||||
{ key: 'buildingType', label: '楼栋类型', options: ['板楼', '塔楼', '板塔结合'] },
|
||||
{ key: 'ownership', label: '权属关系', options: ['商品房', '房改房', '经济适用房'] },
|
||||
{ key: 'hasCoord', label: '有无坐标', options: ['有坐标', '无坐标'] }
|
||||
],
|
||||
metrics: [
|
||||
{ name: '楼盘关联率', value: '47.61%' },
|
||||
{ name: '楼栋及单元完整率', value: '100.38%' },
|
||||
{ name: '房号匹配率', value: '100%' },
|
||||
{ name: '处置率', value: '12.05%' },
|
||||
{ name: '入住人结构数据', value: '58 / 3000' },
|
||||
{ name: '有效结构数量', value: '523 / 523' },
|
||||
{ name: '房源对标', value: '1.83%' }
|
||||
],
|
||||
|
||||
pageSize: 20,
|
||||
currentPage: 1,
|
||||
jumpPage: 1,
|
||||
selectedIds: [],
|
||||
|
||||
toast: { show: false, message: '' },
|
||||
|
||||
init() {
|
||||
this.rows = this.mockRows();
|
||||
},
|
||||
|
||||
mockRows() {
|
||||
const seeds = [
|
||||
['都市港湾', '住宅', '嘉定', '丰庄', '上海 嘉定 海波路1000弄'],
|
||||
['阳光威尼斯四期', '别墅', '普陀', '真光', '上海 普陀 金鼎路1600弄'],
|
||||
['嘉城名都', '住宅', '嘉定', '江桥', '上海 嘉定 嘉城路188弄'],
|
||||
['中海臻如府', '商住', '普陀', '真如', '上海 普陀 真如路88弄'],
|
||||
['凯旋华庭', '写字楼', '长宁', '中山公园', '上海 长宁 凯旋路888号'],
|
||||
['虹桥商务中心', '商业', '闵行', '虹桥', '上海 闵行 申长路699号'],
|
||||
['静安云邸', '住宅', '静安', '大宁', '上海 静安 万荣路66弄'],
|
||||
['松江壹号院', '别墅', '松江', '大学城', '上海 松江 文汇路188号']
|
||||
];
|
||||
|
||||
const list = [];
|
||||
for (let i = 1; i <= 46; i++) {
|
||||
const s = seeds[(i - 1) % seeds.length];
|
||||
list.push({
|
||||
id: i,
|
||||
name: `${s[0]}${i}`,
|
||||
usage: s[1],
|
||||
region: s[2],
|
||||
biz: s[3],
|
||||
address: s[4],
|
||||
avgPrice: (32000 + i * 137).toFixed(2),
|
||||
buildingCount: (6 + (i % 16)),
|
||||
productCount: (50 + (i % 90)),
|
||||
saleCount: (i % 12),
|
||||
rentCount: (i % 8)
|
||||
});
|
||||
}
|
||||
return list;
|
||||
},
|
||||
|
||||
applyFilters() {
|
||||
this.currentPage = 1;
|
||||
this.jumpPage = 1;
|
||||
this.selectedIds = [];
|
||||
},
|
||||
|
||||
resetFilters() {
|
||||
this.filters = {
|
||||
keyword: '',
|
||||
region: '不限',
|
||||
usage: '不限',
|
||||
fixedStatus: '',
|
||||
completion: '',
|
||||
complexType: '',
|
||||
hasProperty: '',
|
||||
buildingType: '',
|
||||
ownership: '',
|
||||
hasCoord: ''
|
||||
};
|
||||
this.currentPage = 1;
|
||||
this.jumpPage = 1;
|
||||
this.selectedIds = [];
|
||||
},
|
||||
|
||||
get filteredRows() {
|
||||
const keyword = (this.filters.keyword || '').toLowerCase();
|
||||
return this.rows.filter((r) => {
|
||||
const hitKeyword = !keyword || [r.name, r.address, `${r.region}${r.biz}`].some(v => String(v).toLowerCase().includes(keyword));
|
||||
const hitRegion = this.filters.region === '不限' || r.region === this.filters.region;
|
||||
const hitUsage = this.filters.usage === '不限' || r.usage === this.filters.usage;
|
||||
return hitKeyword && hitRegion && hitUsage;
|
||||
});
|
||||
},
|
||||
|
||||
get totalPages() {
|
||||
return Math.max(1, Math.ceil(this.filteredRows.length / this.pageSize));
|
||||
},
|
||||
|
||||
get paginatedRows() {
|
||||
const page = Math.min(this.currentPage, this.totalPages);
|
||||
const start = (page - 1) * this.pageSize;
|
||||
return this.filteredRows.slice(start, start + this.pageSize);
|
||||
},
|
||||
|
||||
get selectedCount() {
|
||||
return this.selectedIds.length;
|
||||
},
|
||||
|
||||
isSelected(id) {
|
||||
return this.selectedIds.includes(id);
|
||||
},
|
||||
|
||||
toggleSelect(id, checked) {
|
||||
if (checked) {
|
||||
if (!this.selectedIds.includes(id)) this.selectedIds.push(id);
|
||||
} else {
|
||||
this.selectedIds = this.selectedIds.filter(x => x !== id);
|
||||
}
|
||||
},
|
||||
|
||||
get allOnPageSelected() {
|
||||
if (this.paginatedRows.length === 0) return false;
|
||||
return this.paginatedRows.every(r => this.selectedIds.includes(r.id));
|
||||
},
|
||||
|
||||
toggleSelectPage(checked) {
|
||||
const pageIds = this.paginatedRows.map(r => r.id);
|
||||
if (checked) {
|
||||
const set = new Set([...this.selectedIds, ...pageIds]);
|
||||
this.selectedIds = [...set];
|
||||
} else {
|
||||
this.selectedIds = this.selectedIds.filter(id => !pageIds.includes(id));
|
||||
}
|
||||
},
|
||||
|
||||
goPrev() {
|
||||
if (this.currentPage > 1) this.currentPage -= 1;
|
||||
this.jumpPage = this.currentPage;
|
||||
this.selectedIds = [];
|
||||
},
|
||||
|
||||
goNext() {
|
||||
if (this.currentPage < this.totalPages) this.currentPage += 1;
|
||||
this.jumpPage = this.currentPage;
|
||||
this.selectedIds = [];
|
||||
},
|
||||
|
||||
goJump() {
|
||||
let p = Number(this.jumpPage || 1);
|
||||
if (!Number.isFinite(p)) p = 1;
|
||||
p = Math.max(1, Math.min(this.totalPages, Math.floor(p)));
|
||||
this.currentPage = p;
|
||||
this.jumpPage = p;
|
||||
this.selectedIds = [];
|
||||
},
|
||||
|
||||
openDetail(row) {
|
||||
window.location.hash = `complex/${row.id}`;
|
||||
this.notify(`进入楼盘详情(原型):${row.name}`);
|
||||
},
|
||||
|
||||
notify(message) {
|
||||
this.toast = { show: true, message };
|
||||
window.setTimeout(() => { this.toast.show = false; }, 1800);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user