|
|
|
@ -6,168 +6,132 @@ |
|
|
|
left-text="关闭" |
|
|
|
left-arrow |
|
|
|
@click-left="onClickLeft" |
|
|
|
/> |
|
|
|
|
|
|
|
<!-- Tab 切换 --> |
|
|
|
<van-tabs |
|
|
|
v-model:active="activeTab" |
|
|
|
title-active-color="#111" |
|
|
|
title-inactive-color="#666" |
|
|
|
color="#2f8bd3" |
|
|
|
line-width="36px" |
|
|
|
line-height="2px" |
|
|
|
:border="false" |
|
|
|
@change="onTabChange" |
|
|
|
> |
|
|
|
<van-tab title="待执法预告" name="pending"> |
|
|
|
<div class="list-container"> |
|
|
|
<van-pull-refresh v-model="pendingRefreshing" @refresh="onPendingRefresh"> |
|
|
|
<van-list |
|
|
|
v-model:loading="pendingLoading" |
|
|
|
:finished="pendingFinished" |
|
|
|
finished-text="" |
|
|
|
@load="onPendingLoad" |
|
|
|
:offset="50" |
|
|
|
> |
|
|
|
<van-empty v-if="pendingFinished && pendingList.length === 0" description="暂无待执法预告" /> |
|
|
|
<notice-card |
|
|
|
v-for="item in pendingList" |
|
|
|
:key="item.id" |
|
|
|
:item="item" |
|
|
|
@feedback="onFeedback" |
|
|
|
/> |
|
|
|
</van-list> |
|
|
|
</van-pull-refresh> |
|
|
|
</div> |
|
|
|
</van-tab> |
|
|
|
|
|
|
|
<van-tab title="历史预告" name="history"> |
|
|
|
<div class="list-container"> |
|
|
|
<van-pull-refresh v-model="historyRefreshing" @refresh="onHistoryRefresh"> |
|
|
|
<van-list |
|
|
|
v-model:loading="historyLoading" |
|
|
|
:finished="historyFinished" |
|
|
|
finished-text="" |
|
|
|
@load="onHistoryLoad" |
|
|
|
:offset="50" |
|
|
|
> |
|
|
|
<van-empty v-if="historyFinished && historyList.length === 0" description="暂无历史预告" /> |
|
|
|
<notice-card |
|
|
|
v-for="item in historyList" |
|
|
|
:key="item.id" |
|
|
|
:item="item" |
|
|
|
:show-feedback="false" |
|
|
|
/> |
|
|
|
</van-list> |
|
|
|
</van-pull-refresh> |
|
|
|
</div> |
|
|
|
</van-tab> |
|
|
|
</van-tabs> |
|
|
|
<!-- <template #right> |
|
|
|
<van-icon name="filter-o" size="20" @click="onFilterClick" /> |
|
|
|
<van-icon name="search" size="20" style="margin-left: 12px;" @click="onSearchClick" /> |
|
|
|
</template> --> |
|
|
|
</van-nav-bar> |
|
|
|
|
|
|
|
<!-- 搜索栏 --> |
|
|
|
<van-search v-model="searchText" show-action placeholder="请输入关键字查询" clearable clear-trigger="always" |
|
|
|
@clear="onClear" @search="onSearch"> |
|
|
|
<template #action> |
|
|
|
<div @click="onSearch">搜索</div> |
|
|
|
</template> |
|
|
|
</van-search> |
|
|
|
|
|
|
|
<!-- 列表区域 --> |
|
|
|
<div class="list-container"> |
|
|
|
<van-pull-refresh v-model="refreshing" @refresh="onRefresh"> |
|
|
|
<van-list |
|
|
|
v-model:loading="loading" |
|
|
|
:finished="finished" |
|
|
|
finished-text="" |
|
|
|
@load="onLoad" |
|
|
|
:offset="50" |
|
|
|
> |
|
|
|
<van-empty v-if="finished && list.length === 0" description="暂无数据" /> |
|
|
|
|
|
|
|
<div |
|
|
|
class="notice-card" |
|
|
|
v-for="item in list" |
|
|
|
:key="item.id" |
|
|
|
> |
|
|
|
<div class="card-row time-row"> |
|
|
|
<span class="label">执法时间:</span> |
|
|
|
<span class="value">{{ item.checkTime }}</span> |
|
|
|
</div> |
|
|
|
<div class="card-title">{{ item.checkItemText }}</div> |
|
|
|
<div class="card-row"> |
|
|
|
<span class="label">执法单位:</span> |
|
|
|
<span class="value">{{ item.bureauDeptName }}</span> |
|
|
|
</div> |
|
|
|
<div class="card-action"> |
|
|
|
<span class="feedback-btn" :class="{ 'has-dot': item.hasFeedback }" @click="onFeedback(item)"> |
|
|
|
<van-icon name="chat-o" size="14" /> |
|
|
|
反馈 |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</van-list> |
|
|
|
</van-pull-refresh> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script setup name="planNoticeList"> |
|
|
|
<script setup name="enforcementNoticeList"> |
|
|
|
import { ref } from 'vue'; |
|
|
|
import { useRouter } from 'vue-router'; |
|
|
|
import { showToast } from 'vant'; |
|
|
|
import 'vant/es/toast/style'; |
|
|
|
import { getPlanNoticeList } from '@/api/enterprise/planNotice'; |
|
|
|
import NoticeCard from './planNoticeCard.vue'; |
|
|
|
import { getLawNoticeList } from '@/api/enterprise'; |
|
|
|
|
|
|
|
const { useCommon } = $globalStore; |
|
|
|
const router = useRouter(); |
|
|
|
|
|
|
|
const activeTab = ref('pending'); |
|
|
|
|
|
|
|
// ========== 待执法列表状态 ========== |
|
|
|
const pendingList = ref([]); |
|
|
|
const pendingLoading = ref(false); |
|
|
|
const pendingFinished = ref(false); |
|
|
|
const pendingRefreshing = ref(false); |
|
|
|
const pendingPageNum = ref(1); |
|
|
|
|
|
|
|
// ========== 历史列表状态 ========== |
|
|
|
const historyList = ref([]); |
|
|
|
const historyLoading = ref(false); |
|
|
|
const historyFinished = ref(false); |
|
|
|
const historyRefreshing = ref(false); |
|
|
|
const historyPageNum = ref(1); |
|
|
|
|
|
|
|
const pageSize = 10; |
|
|
|
|
|
|
|
// ========== Tab切换 ========== |
|
|
|
const onTabChange = () => {}; |
|
|
|
|
|
|
|
// ========== 通用加载方法 ========== |
|
|
|
const fetchList = (status, listRef, loadingRef, finishedRef, refreshingRef, pageNumRef) => { |
|
|
|
const enterpriseNumber = useCommon.enterpriseNumber; |
|
|
|
if (!enterpriseNumber) { |
|
|
|
finishedRef.value = true; |
|
|
|
loadingRef.value = false; |
|
|
|
refreshingRef.value = false; |
|
|
|
showToast('企业信息未获取,请重新登录'); |
|
|
|
return; |
|
|
|
} |
|
|
|
// ========== 列表状态 ========== |
|
|
|
const list = ref([]); |
|
|
|
const loading = ref(false); |
|
|
|
const finished = ref(false); |
|
|
|
const refreshing = ref(false); |
|
|
|
const pageNum = ref(1); |
|
|
|
const pageSize = ref(10); |
|
|
|
const searchText = ref(''); |
|
|
|
|
|
|
|
// ========== 加载数据 ========== |
|
|
|
const fetchList = () => { |
|
|
|
const params = { |
|
|
|
enterpriseNumber, |
|
|
|
status, |
|
|
|
pageNum: pageNumRef.value, |
|
|
|
pageSize, |
|
|
|
pageNum: pageNum.value, |
|
|
|
pageSize: pageSize.value, |
|
|
|
}; |
|
|
|
getPlanNoticeList(params, (res) => { |
|
|
|
if (searchText.value) { |
|
|
|
params.searchValue = searchText.value; |
|
|
|
} |
|
|
|
getLawNoticeList(params, (res) => { |
|
|
|
if (res.code === 200) { |
|
|
|
const rows = res.rows || res.data?.rows || res.data?.list || res.data || []; |
|
|
|
const total = res.total ?? res.data?.total ?? 0; |
|
|
|
|
|
|
|
if (refreshingRef.value) { |
|
|
|
listRef.value = Array.isArray(rows) ? rows : []; |
|
|
|
refreshingRef.value = false; |
|
|
|
if (refreshing.value) { |
|
|
|
list.value = Array.isArray(rows) ? rows : []; |
|
|
|
refreshing.value = false; |
|
|
|
} else { |
|
|
|
listRef.value = [...listRef.value, ...(Array.isArray(rows) ? rows : [])]; |
|
|
|
list.value = [...list.value, ...(Array.isArray(rows) ? rows : [])]; |
|
|
|
} |
|
|
|
|
|
|
|
if (!Array.isArray(rows) || rows.length === 0 || listRef.value.length >= total) { |
|
|
|
finishedRef.value = true; |
|
|
|
if (!Array.isArray(rows) || rows.length === 0 || list.value.length >= total) { |
|
|
|
finished.value = true; |
|
|
|
} else { |
|
|
|
pageNumRef.value++; |
|
|
|
pageNum.value++; |
|
|
|
} |
|
|
|
loadingRef.value = false; |
|
|
|
loading.value = false; |
|
|
|
} else { |
|
|
|
finishedRef.value = true; |
|
|
|
loadingRef.value = false; |
|
|
|
refreshingRef.value = false; |
|
|
|
finished.value = true; |
|
|
|
loading.value = false; |
|
|
|
refreshing.value = false; |
|
|
|
showToast(res.msg || '加载失败'); |
|
|
|
} |
|
|
|
}, () => { |
|
|
|
finishedRef.value = true; |
|
|
|
loadingRef.value = false; |
|
|
|
refreshingRef.value = false; |
|
|
|
finished.value = true; |
|
|
|
loading.value = false; |
|
|
|
refreshing.value = false; |
|
|
|
showToast('网络请求失败'); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// ========== 待执法 ========== |
|
|
|
const onPendingLoad = () => { |
|
|
|
if (pendingRefreshing.value) return; |
|
|
|
fetchList(1, pendingList, pendingLoading, pendingFinished, pendingRefreshing, pendingPageNum); |
|
|
|
}; |
|
|
|
const onPendingRefresh = () => { |
|
|
|
pendingPageNum.value = 1; |
|
|
|
pendingList.value = []; |
|
|
|
pendingFinished.value = false; |
|
|
|
pendingLoading.value = true; |
|
|
|
fetchList(1, pendingList, pendingLoading, pendingFinished, pendingRefreshing, pendingPageNum); |
|
|
|
// ========== 触底加载 ========== |
|
|
|
const onLoad = () => { |
|
|
|
if (refreshing.value) return; |
|
|
|
fetchList(); |
|
|
|
}; |
|
|
|
|
|
|
|
// ========== 历史 ========== |
|
|
|
const onHistoryLoad = () => { |
|
|
|
if (historyRefreshing.value) return; |
|
|
|
fetchList(3, historyList, historyLoading, historyFinished, historyRefreshing, historyPageNum); |
|
|
|
}; |
|
|
|
const onHistoryRefresh = () => { |
|
|
|
historyPageNum.value = 1; |
|
|
|
historyList.value = []; |
|
|
|
historyFinished.value = false; |
|
|
|
historyLoading.value = true; |
|
|
|
fetchList(3, historyList, historyLoading, historyFinished, historyRefreshing, historyPageNum); |
|
|
|
// ========== 下拉刷新 ========== |
|
|
|
const onRefresh = () => { |
|
|
|
pageNum.value = 1; |
|
|
|
list.value = []; |
|
|
|
finished.value = false; |
|
|
|
loading.value = true; |
|
|
|
fetchList(); |
|
|
|
}; |
|
|
|
|
|
|
|
// ========== 返回上一页 ========== |
|
|
|
@ -175,24 +139,41 @@ const onClickLeft = () => { |
|
|
|
router.back(); |
|
|
|
}; |
|
|
|
|
|
|
|
// ========== 留言反馈 ========== |
|
|
|
const onFeedback = (item) => { |
|
|
|
router.push({ |
|
|
|
path: '/enterprise/planNoticeMessage', |
|
|
|
query: { id: item.id } |
|
|
|
}); |
|
|
|
// ========== 搜索 ========== |
|
|
|
const onSearch = () => { |
|
|
|
pageNum.value = 1; |
|
|
|
list.value = []; |
|
|
|
finished.value = false; |
|
|
|
loading.value = true; |
|
|
|
fetchList(); |
|
|
|
}; |
|
|
|
|
|
|
|
// ========== 工具方法 ========== |
|
|
|
const formatDate = (date) => { |
|
|
|
if (!date) return ''; |
|
|
|
return String(date).replace(/\s+00:00:00$/, ''); |
|
|
|
// ========== 清空搜索 ========== |
|
|
|
const onClear = () => { |
|
|
|
searchText.value = ''; |
|
|
|
onSearch(); |
|
|
|
}; |
|
|
|
const formatEnforceTime = (val) => { |
|
|
|
if (val === 1 || val === '1') return '上午'; |
|
|
|
if (val === 2 || val === '2') return '下午'; |
|
|
|
if (val === 3 || val === '3') return '其他'; |
|
|
|
return ''; |
|
|
|
|
|
|
|
// ========== 筛选点击 ========== |
|
|
|
const onFilterClick = () => { |
|
|
|
showToast('筛选功能开发中'); |
|
|
|
}; |
|
|
|
|
|
|
|
// ========== 搜索点击 ========== |
|
|
|
const onSearchClick = () => { |
|
|
|
showToast('搜索功能开发中'); |
|
|
|
}; |
|
|
|
|
|
|
|
// ========== 反馈点击 ========== |
|
|
|
const onFeedback = (item) => { |
|
|
|
router.push({ |
|
|
|
path: '/enforcement/enforcementChat', |
|
|
|
query: { |
|
|
|
title: item.title, |
|
|
|
bureauDeptName: item.bureauDeptName, |
|
|
|
enforcementTime: item.enforcementTime, |
|
|
|
} |
|
|
|
}); |
|
|
|
}; |
|
|
|
</script> |
|
|
|
|
|
|
|
@ -202,13 +183,17 @@ const formatEnforceTime = (val) => { |
|
|
|
flex-direction: column; |
|
|
|
height: 100%; |
|
|
|
background-color: #ebf3fb; |
|
|
|
overflow: hidden; |
|
|
|
|
|
|
|
.list-container { |
|
|
|
flex: 1; |
|
|
|
overflow-y: auto; |
|
|
|
padding: 0.27rem; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* ===== 导航栏 ===== */ |
|
|
|
/* ===== 导航栏样式覆盖 ===== */ |
|
|
|
:deep(.van-nav-bar) { |
|
|
|
background-color: #fff; |
|
|
|
flex-shrink: 0; |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.van-nav-bar__title) { |
|
|
|
@ -226,46 +211,94 @@ const formatEnforceTime = (val) => { |
|
|
|
color: #333; |
|
|
|
} |
|
|
|
|
|
|
|
/* ===== Tabs ===== */ |
|
|
|
:deep(.van-tabs) { |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
flex: 1; |
|
|
|
min-height: 0; |
|
|
|
/* ===== 卡片样式 ===== */ |
|
|
|
.notice-card { |
|
|
|
background: #fff; |
|
|
|
border-radius: 0.2rem; |
|
|
|
padding: 0.3rem 0.35rem; |
|
|
|
margin-bottom: 0.27rem; |
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.van-tabs__wrap) { |
|
|
|
height: 50px; |
|
|
|
background: #fff; |
|
|
|
border-bottom: 1px solid #e4edf7; |
|
|
|
flex-shrink: 0; |
|
|
|
.card-row { |
|
|
|
font-size: 0.32rem; |
|
|
|
color: #666; |
|
|
|
line-height: 1.6; |
|
|
|
|
|
|
|
.label { |
|
|
|
color: #999; |
|
|
|
} |
|
|
|
|
|
|
|
.value { |
|
|
|
color: #666; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.van-tab) { |
|
|
|
font-size: 15px; |
|
|
|
.time-row { |
|
|
|
margin-bottom: 0.15rem; |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.van-tab--active) { |
|
|
|
font-weight: 600; |
|
|
|
.card-title { |
|
|
|
font-size: 0.42rem; |
|
|
|
font-weight: bold; |
|
|
|
color: #1a1a1a; |
|
|
|
margin: 0.15rem 0; |
|
|
|
line-height: 1.4; |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.van-tabs__content), |
|
|
|
:deep(.van-tabs__track), |
|
|
|
:deep(.van-tab__panel-wrapper), |
|
|
|
:deep(.van-tab__panel) { |
|
|
|
flex: 1; |
|
|
|
min-height: 0; |
|
|
|
height: 100%; |
|
|
|
.card-action { |
|
|
|
display: flex; |
|
|
|
justify-content: flex-end; |
|
|
|
margin-top: 0.2rem; |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.van-tabs__content) { |
|
|
|
overflow: hidden; |
|
|
|
.feedback-btn { |
|
|
|
display: inline-flex; |
|
|
|
align-items: center; |
|
|
|
font-size: 0.32rem; |
|
|
|
color: #2d94fa; |
|
|
|
cursor: pointer; |
|
|
|
|
|
|
|
:deep(.van-icon) { |
|
|
|
margin-right: 0.08rem; |
|
|
|
color: #2d94fa; |
|
|
|
} |
|
|
|
|
|
|
|
&.has-dot { |
|
|
|
position: relative; |
|
|
|
|
|
|
|
:deep(.van-icon) { |
|
|
|
position: relative; |
|
|
|
|
|
|
|
&::after { |
|
|
|
content: ''; |
|
|
|
position: absolute; |
|
|
|
top: -2px; |
|
|
|
right: -2px; |
|
|
|
width: 6px; |
|
|
|
height: 6px; |
|
|
|
background: #f44336; |
|
|
|
border-radius: 50%; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
/* ===== Vant 搜索框样式覆盖 ===== */ |
|
|
|
:deep(.van-search__content) { |
|
|
|
height: 0.9rem; |
|
|
|
border: 1px solid #ececec; |
|
|
|
border-radius: 0.15rem 0 0 0.15rem; |
|
|
|
} |
|
|
|
|
|
|
|
/* ===== 列表容器 ===== */ |
|
|
|
.list-container { |
|
|
|
height: 100%; |
|
|
|
overflow-y: auto; |
|
|
|
padding: 0.27rem; |
|
|
|
:deep(.van-search__action) { |
|
|
|
margin: 0 3% 0 0; |
|
|
|
width: 10%; |
|
|
|
height: 0.9rem; |
|
|
|
background: #1367fe; |
|
|
|
border: 0.01rem solid #1367fe; |
|
|
|
border-radius: 0 0.15rem 0.15rem 0; |
|
|
|
color: #fff; |
|
|
|
text-align: center; |
|
|
|
line-height: 0.9rem; |
|
|
|
} |
|
|
|
</style> |
|
|
|
|