feat: Batch 4 - remaining pages (23 pages)
Agent Loop: 3 agents, all passed - 8 pshgl pages (排水户管理) - 8 fxgl+xjgl pages (防汛+工程) - 7 remaining (map/project/QR)
This commit is contained in:
234
src/views/pshgl/pshCheckList.vue
Normal file
234
src/views/pshgl/pshCheckList.vue
Normal file
@@ -0,0 +1,234 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 排水户检查选择列表页
|
||||
*
|
||||
* 展示待检查的排水户列表,支持搜索和复选框多选,
|
||||
* 选中后可进入检查填报页面。
|
||||
*/
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { showToast } from 'vant'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
const pshId = (route.params.id || route.query.id) as string
|
||||
|
||||
/** 搜索关键词 */
|
||||
const searchText = ref('')
|
||||
|
||||
/** 选中的排水户 ID 列表 */
|
||||
const checkedIds = ref<number[]>([])
|
||||
|
||||
/** 模拟待检查排水户数据 */
|
||||
const mockDrainUsers = [
|
||||
{ id: 1, name: '华丰食品厂', type: 'industrial', address: '城北工业园区A1栋', lastCheck: '2025-05-15', status: 'normal' },
|
||||
{ id: 2, name: '阳光花园小区', type: 'domestic', address: '阳光路88号', lastCheck: '2025-04-20', status: 'normal' },
|
||||
{ id: 3, name: '万达商业广场', type: 'commercial', address: '中山路100号', lastCheck: '2025-05-10', status: 'warning' },
|
||||
{ id: 4, name: '东风化工厂', type: 'industrial', address: '高新区化工大道56号', lastCheck: '2025-03-01', status: 'danger' },
|
||||
{ id: 5, name: '翠湖小区', type: 'domestic', address: '翠湖路66号', lastCheck: '2025-06-01', status: 'normal' },
|
||||
]
|
||||
|
||||
/** 类型映射 */
|
||||
const typeMap: Record<string, string> = {
|
||||
industrial: '工业',
|
||||
domestic: '生活',
|
||||
commercial: '商业',
|
||||
}
|
||||
|
||||
const typeColorMap: Record<string, string> = {
|
||||
industrial: '#1989fa',
|
||||
domestic: '#07c160',
|
||||
commercial: '#ff976a',
|
||||
}
|
||||
|
||||
/** 状态映射 */
|
||||
const statusMap: Record<string, string> = {
|
||||
normal: '正常',
|
||||
warning: '需检查',
|
||||
danger: '急需检查',
|
||||
}
|
||||
|
||||
const statusColorMap: Record<string, 'success' | 'warning' | 'danger'> = {
|
||||
normal: 'success',
|
||||
warning: 'warning',
|
||||
danger: 'danger',
|
||||
}
|
||||
|
||||
/** 筛选后的列表 */
|
||||
const filteredList = computed(() => {
|
||||
let list = mockDrainUsers
|
||||
if (searchText.value) {
|
||||
const kw = searchText.value.toLowerCase()
|
||||
list = list.filter(d =>
|
||||
d.name.toLowerCase().includes(kw) ||
|
||||
d.address.toLowerCase().includes(kw)
|
||||
)
|
||||
}
|
||||
return list
|
||||
})
|
||||
|
||||
/** 切换选中 */
|
||||
function toggleCheck(id: number) {
|
||||
const idx = checkedIds.value.indexOf(id)
|
||||
if (idx > -1) {
|
||||
checkedIds.value.splice(idx, 1)
|
||||
} else {
|
||||
checkedIds.value.push(id)
|
||||
}
|
||||
}
|
||||
|
||||
/** 全选/取消全选 */
|
||||
const isAllChecked = computed(() => {
|
||||
return filteredList.value.length > 0 && checkedIds.value.length === filteredList.value.length
|
||||
})
|
||||
|
||||
function toggleAll() {
|
||||
if (isAllChecked.value) {
|
||||
checkedIds.value = []
|
||||
} else {
|
||||
checkedIds.value = filteredList.value.map(d => d.id)
|
||||
}
|
||||
}
|
||||
|
||||
/** 开始检查 */
|
||||
function startCheck() {
|
||||
if (checkedIds.value.length === 0) {
|
||||
showToast('请选择排水户')
|
||||
return
|
||||
}
|
||||
const ids = checkedIds.value.join(',')
|
||||
router.push(`/pshCheck/${ids}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="check-select-page">
|
||||
<van-nav-bar title="选择检查排水户" left-arrow fixed placeholder @click-left="router.back()" />
|
||||
|
||||
<van-search v-model="searchText" placeholder="搜索排水户名称、地址" shape="round" />
|
||||
|
||||
<div class="toolbar">
|
||||
<van-checkbox :model-value="isAllChecked" @change="toggleAll">全选</van-checkbox>
|
||||
<span class="count-text">已选 {{ checkedIds.length }} 户</span>
|
||||
</div>
|
||||
|
||||
<div class="card-list">
|
||||
<van-empty v-if="filteredList.length === 0" description="暂无排水户" />
|
||||
<div
|
||||
v-for="item in filteredList"
|
||||
:key="item.id"
|
||||
class="check-card"
|
||||
@click="toggleCheck(item.id)"
|
||||
>
|
||||
<van-checkbox :model-value="checkedIds.includes(item.id)" />
|
||||
<div class="card-body">
|
||||
<div class="card-title">
|
||||
<span>{{ item.name }}</span>
|
||||
<van-tag :color="typeColorMap[item.type]" size="medium" text-color="#fff">
|
||||
{{ typeMap[item.type] }}
|
||||
</van-tag>
|
||||
<van-tag :type="statusColorMap[item.status]" size="medium">
|
||||
{{ statusMap[item.status] }}
|
||||
</van-tag>
|
||||
</div>
|
||||
<div class="card-desc">{{ item.address }}</div>
|
||||
<div class="card-meta">上次检查: {{ item.lastCheck }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bottom-bar">
|
||||
<van-button type="primary" block round @click="startCheck">
|
||||
开始检查 ({{ checkedIds.length }})
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.check-select-page {
|
||||
min-height: 100vh;
|
||||
background: var(--color-bg-page);
|
||||
padding-bottom: 80px;
|
||||
|
||||
:deep(.van-nav-bar) {
|
||||
background: var(--color-primary);
|
||||
--van-nav-bar-title-text-color: #fff;
|
||||
--van-nav-bar-text-color: #fff;
|
||||
--van-nav-bar-icon-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px 16px;
|
||||
background: var(--color-bg-card);
|
||||
|
||||
.count-text {
|
||||
font-size: 13px;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.card-list {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.check-card {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
margin: 8px;
|
||||
padding: 12px;
|
||||
border-radius: 10px;
|
||||
background: var(--color-bg-card);
|
||||
cursor: pointer;
|
||||
|
||||
:deep(.van-checkbox) {
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-primary);
|
||||
|
||||
:deep(.van-tag) {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.card-desc {
|
||||
margin-top: 4px;
|
||||
font-size: 13px;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.card-meta {
|
||||
margin-top: 4px;
|
||||
font-size: 11px;
|
||||
color: var(--color-text-placeholder);
|
||||
}
|
||||
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 12px 16px;
|
||||
background: var(--color-bg-card);
|
||||
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user