Browse Source

UI调整

dev-V1.10.2-temp
wangmingyong@163.com 3 months ago
parent
commit
b89d209141
  1. 2
      zdxt-web-client/zdxt-efcode-enforcement-app/src/components/FooterBar.vue
  2. 10
      zdxt-web-client/zdxt-efcode-enforcement-app/src/router/enforcement-app/enf-main-router.js
  3. 68
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/enforce/enforcementChat.vue
  4. 38
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/enforce/enforcementNoticeList.vue
  5. 1
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/message/enforcementTaskList.vue
  6. 20
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/message/messageCenter.vue
  7. 54
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/enforcementMy.vue
  8. 6
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/notice/cp_notice_detail.vue
  9. 6
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/notice/cp_notice_edit.vue
  10. 6
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/notice/cp_notice_list.vue
  11. 4
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/notice/cp_notice_tab_content.vue
  12. 2
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue
  13. 6
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_list.vue
  14. 265
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_mine.vue
  15. 6
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_other.vue

2
zdxt-web-client/zdxt-efcode-enforcement-app/src/components/FooterBar.vue

@ -156,8 +156,6 @@ onMounted(() => {
position: absolute; position: absolute;
top: -4px; top: -4px;
right: -8px; right: -8px;
// width: 16px;
// height: 16px;
padding: 0px 4px; padding: 0px 4px;
background: #f5222d; background: #f5222d;
color: #fff; color: #fff;

10
zdxt-web-client/zdxt-efcode-enforcement-app/src/router/enforcement-app/enf-main-router.js

@ -76,7 +76,7 @@ const routes = [
name: "enforcementQuery", name: "enforcementQuery",
component: () => import("@/views/enforcement/query/enforcementQuery.vue"), component: () => import("@/views/enforcement/query/enforcementQuery.vue"),
meta: { meta: {
isKeepAlive: true, isKeepAlive: false,
}, },
}, },
// 执法端-消息中心(tabbar) // 执法端-消息中心(tabbar)
@ -85,7 +85,7 @@ const routes = [
name: "enforcementMessage", name: "enforcementMessage",
component: () => import("@/views/enforcement/message/messageCenter.vue"), component: () => import("@/views/enforcement/message/messageCenter.vue"),
meta: { meta: {
isKeepAlive: true, isKeepAlive: false,
}, },
}, },
// 执法端-通知列表(tabbar) // 执法端-通知列表(tabbar)
@ -94,7 +94,7 @@ const routes = [
name: "enforcementNoticeList", name: "enforcementNoticeList",
component: () => import("@/views/enforcement/enforce/enforcementNoticeList.vue"), component: () => import("@/views/enforcement/enforce/enforcementNoticeList.vue"),
meta: { meta: {
isKeepAlive: true, isKeepAlive: false,
}, },
}, },
// 执法端-执法预告反馈聊天 // 执法端-执法预告反馈聊天
@ -148,7 +148,7 @@ const routes = [
name: "enforcementMy", name: "enforcementMy",
component: () => import("@/views/enforcement/my/enforcementMy.vue"), component: () => import("@/views/enforcement/my/enforcementMy.vue"),
meta: { meta: {
isKeepAlive: true, isKeepAlive: false,
}, },
}, },
// 执法端-计划(tabbar) // 执法端-计划(tabbar)
@ -157,7 +157,7 @@ const routes = [
name: "enforcementProgram", name: "enforcementProgram",
component: () => import("@/views/enforcement/program"), component: () => import("@/views/enforcement/program"),
meta: { meta: {
isKeepAlive: true, isKeepAlive: false,
}, },
}, },
// 执法端-计划列表(嵌套路由:我的计划 / 其他计划) // 执法端-计划列表(嵌套路由:我的计划 / 其他计划)

68
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/enforce/enforcementChat.vue

@ -122,15 +122,17 @@
</template> </template>
<script setup name="enforcementChat"> <script setup name="enforcementChat">
import { ref, nextTick } from 'vue'; import { ref, nextTick, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { showToast } from 'vant'; import { showToast } from 'vant';
import 'vant/es/toast/style'; import 'vant/es/toast/style';
import { getNoticeMessages, addNoticeMessage } from '@/api/enforcement/notice';
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
// ========== 从路由参数获取信息 ========== // ========== 从路由参数获取信息 ==========
const noticeId = route.query.id|| '';
const bureauDeptName = ref(route.query.bureauDeptName || '深圳司法局'); const bureauDeptName = ref(route.query.bureauDeptName || '深圳司法局');
const contactPerson = ref(route.query.contactPerson || '付明明 周昂'); const contactPerson = ref(route.query.contactPerson || '付明明 周昂');
const noticeTitle = ref(route.query.title || '安全生产检查'); const noticeTitle = ref(route.query.title || '安全生产检查');
@ -138,26 +140,27 @@ const noticeTitle = ref(route.query.title || '安全生产检查');
// ========== 头像占位 ========== // ========== 头像占位 ==========
const selfAvatar = 'https://placehold.co/40x40/447bf5/fff?text=我'; const selfAvatar = 'https://placehold.co/40x40/447bf5/fff?text=我';
const otherAvatar = 'https://placehold.co/40x40/999/fff?text=企'; const otherAvatar = 'https://placehold.co/40x40/999/fff?text=企';
// ========== 消息列表 ========== // ========== 消息列表 ==========
const messageList = ref([ const messageList = ref([]);
{ // ========== 加载留言列表 ==========
id: 1, const loadMessageList = () => {
sender: 'other', if (!noticeId) return;
content: `您好,我司将于${route.query.enforcementTime || '2026-04-07'}进行执法检查,特此告知。`, getNoticeMessages(noticeId, (res) => {
time: '2026-03-31 10:20', if (res && res.code === 200 && res.data) {
avatar: otherAvatar, messageList.value = res.data.map(item => ({
isRecalled: false, id: item.id,
}, sender: item.sender === 'self' ? 'self' : 'other',
{ content: item.content || item.message || '',
id: 2, time: item.createTime || item.time || '',
sender: 'self', avatar: item.sender === 'self' ? selfAvatar : otherAvatar,
content: '收到,我们会做好准备工作。', isRecalled: item.isRecalled || false,
time: '2026-03-31 18:32', }));
avatar: selfAvatar, nextTick(() => scrollToBottom());
isRecalled: false, }
}, }, () => {
]); showToast('加载消息失败');
});
};
const inputMessage = ref(''); const inputMessage = ref('');
const messageListRef = ref(null); const messageListRef = ref(null);
@ -315,23 +318,44 @@ const sendMessage = () => {
const now = new Date(); const now = new Date();
const timeStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`; const timeStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
messageList.value.push({ const newMsg = {
id: Date.now(), id: Date.now(),
sender: 'self', sender: 'self',
content: text, content: text,
time: timeStr, time: timeStr,
avatar: selfAvatar, avatar: selfAvatar,
isRecalled: false, isRecalled: false,
}); };
messageList.value.push(newMsg);
inputMessage.value = ''; inputMessage.value = '';
// 调用新增留言接口
if (noticeId) {
addNoticeMessage({
noticeId,
content: text,
}, (res) => {
if (res && res.code === 200) {
newMsg.id = res.data?.id || newMsg.id;
}
}, () => {
showToast('发送失败');
messageList.value.pop();
});
}
// 滚动到底部 // 滚动到底部
nextTick(() => { nextTick(() => {
scrollToBottom(); scrollToBottom();
}); });
}; };
// ========== 页面挂载加载数据 ==========
onMounted(() => {
loadMessageList();
});
// ========== 滚动到底部 ========== // ========== 滚动到底部 ==========
const scrollToBottom = () => { const scrollToBottom = () => {
const el = messageListRef.value; const el = messageListRef.value;

38
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/enforce/enforcementNoticeList.vue

@ -1,17 +1,17 @@
<template> <template>
<div class="notice-list-page"> <div class="notice-list-page">
<!-- 顶部导航栏 --> <!-- 顶部导航栏 -->
<van-nav-bar <!-- <van-nav-bar
title="执法预告" title="执法预告"
left-text="关闭" left-text="关闭"
left-arrow left-arrow
@click-left="onClickLeft" @click-left="onClickLeft"
> > -->
<!-- <template #right> <!-- <template #right>
<van-icon name="filter-o" size="20" @click="onFilterClick" /> <van-icon name="filter-o" size="20" @click="onFilterClick" />
<van-icon name="search" size="20" style="margin-left: 12px;" @click="onSearchClick" /> <van-icon name="search" size="20" style="margin-left: 12px;" @click="onSearchClick" />
</template> --> </template> -->
</van-nav-bar> <!-- </van-nav-bar> -->
<!-- 搜索栏 --> <!-- 搜索栏 -->
<SearchFilterBar :search-value="searchText" @search="onSearch" @clear="onClear" /> <SearchFilterBar :search-value="searchText" @search="onSearch" @clear="onClear" />
@ -19,20 +19,10 @@
<!-- 列表区域 --> <!-- 列表区域 -->
<div class="list-container"> <div class="list-container">
<van-pull-refresh v-model="refreshing" @refresh="onRefresh"> <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list <van-list v-model:loading="loading" :finished="finished" finished-text="" @load="onLoad" :offset="50">
v-model:loading="loading"
:finished="finished"
finished-text=""
@load="onLoad"
:offset="50"
>
<van-empty v-if="finished && list.length === 0" description="暂无数据" /> <van-empty v-if="finished && list.length === 0" description="暂无数据" />
<div <div class="notice-card" v-for="item in list" :key="item.id">
class="notice-card"
v-for="item in list"
:key="item.id"
>
<div class="card-row time-row"> <div class="card-row time-row">
<span class="label">执法时间:</span> <span class="label">执法时间:</span>
<span class="value">{{ item.checkTime }}</span> <span class="value">{{ item.checkTime }}</span>
@ -43,7 +33,8 @@
<span class="value">{{ item.bureauDeptName }}</span> <span class="value">{{ item.bureauDeptName }}</span>
</div> </div>
<div class="card-action"> <div class="card-action">
<span class="feedback-btn" :class="{ 'has-dot': item.hasFeedback }" @click="onFeedback(item)"> <span class="feedback-btn" :class="{ 'has-dot': item.hasFeedback }"
@click="onFeedback(item)">
<van-icon name="chat-o" size="14" /> <van-icon name="chat-o" size="14" />
反馈 反馈
</span> </span>
@ -56,7 +47,7 @@
</template> </template>
<script setup name="enforcementNoticeList"> <script setup name="enforcementNoticeList">
import { ref } from 'vue'; import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { showToast } from 'vant'; import { showToast } from 'vant';
import 'vant/es/toast/style'; import 'vant/es/toast/style';
@ -117,7 +108,7 @@ const fetchList = () => {
// ========== 触底加载 ========== // ========== 触底加载 ==========
const onLoad = () => { const onLoad = () => {
if (refreshing.value) return; if (loading.value || finished.value) return;
fetchList(); fetchList();
}; };
@ -168,12 +159,15 @@ const onFeedback = (item) => {
router.push({ router.push({
path: '/enforcement/enforcementChat', path: '/enforcement/enforcementChat',
query: { query: {
title: item.title, noticeId: item.id,
bureauDeptName: item.bureauDeptName,
enforcementTime: item.enforcementTime,
} }
}); });
}; };
// ========== 页面挂载加载数据 ==========
onMounted(() => {
fetchList();
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

1
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/message/enforcementTaskList.vue

@ -147,6 +147,7 @@ const onDateChange = ({ dateType: type, dateSearch: search }) => {
}; };
onMounted(() => { onMounted(() => {
console.log('enforcementTaskList mounted');
fetchTaskList(); fetchTaskList();
}); });
</script> </script>

20
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/message/messageCenter.vue

@ -125,15 +125,17 @@ const initMessageList = () => {
icon: 'law', icon: 'law',
iconBg: 'icon-blue', iconBg: 'icon-blue',
unreadCount: pffwCount.value, unreadCount: pffwCount.value,
},{ },
id: 2, // {
title: '计划通知', // id: 2,
desc: '', // title: '计划通知',
time: '', // desc: '',
icon: 'law', // time: '',
iconBg: 'icon-blue', // icon: 'law',
unreadCount: jhtzcount.value, // iconBg: 'icon-blue',
},{ // unreadCount: jhtzcount.value,
// },
{
id: 3, id: 3,
title: '执法反馈', title: '执法反馈',
desc: '', desc: '',

54
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/enforcementMy.vue

@ -2,7 +2,6 @@
<div class="my-page app_content"> <div class="my-page app_content">
<!-- 顶部蓝色背景(含城市天际线 + 用户信息) --> <!-- 顶部蓝色背景(含城市天际线 + 用户信息) -->
<div class="header-bg"> <div class="header-bg">
<div class="cityscape"></div>
<div class="user-wrap"> <div class="user-wrap">
<div class="avatar"> <div class="avatar">
@ -40,7 +39,7 @@
</div> </div>
<!-- 设置单独一组卡片 --> <!-- 设置单独一组卡片 -->
<div class="menu-card menu-card--split"> <!-- <div class="menu-card menu-card--split">
<div class="menu-item menu-item--last" @click="onMenuClick(settingItem)"> <div class="menu-item menu-item--last" @click="onMenuClick(settingItem)">
<div class="menu-icon" :class="settingItem.iconClass"> <div class="menu-icon" :class="settingItem.iconClass">
<component :is="settingItem.iconComp"/> <component :is="settingItem.iconComp"/>
@ -52,7 +51,7 @@
</svg> </svg>
</div> </div>
</div> </div>
</div> </div> -->
</div> </div>
<!-- 底部导航栏 --> <!-- 底部导航栏 -->
@ -147,58 +146,18 @@ const onMenuClick = (item) => {
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
background: #fbfdff; background: #fbfdff;
font-family: none;
overflow: hidden; overflow: hidden;
} }
/* ===== 顶部蓝色背景 ===== */ /* ===== 顶部蓝色背景 ===== */
.header-bg { .header-bg {
position: relative; position: relative;
background: linear-gradient(180deg, #2b7de9 0%, #5ba3f5 60%, #a0cdf8 100%); background: url('@/assets/images/bg_msg_2.jpg') no-repeat center center / cover;
padding: 24px 20px 70px; padding: 24px 20px 70px;
overflow: hidden; overflow: hidden;
flex-shrink: 0; flex-shrink: 0;
} }
.cityscape {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 110px;
opacity: 0.2;
pointer-events: none;
&::before {
content: '';
position: absolute;
bottom: 0;
left: 6%;
width: 8%;
height: 60px;
background: rgba(255, 255, 255, 0.5);
border-radius: 2px 2px 0 0;
box-shadow:
22px 18px 0 rgba(255, 255, 255, 0.4),
48px 30px 0 rgba(255, 255, 255, 0.35),
75px 12px 0 rgba(255, 255, 255, 0.3);
}
&::after {
content: '';
position: absolute;
bottom: 0;
right: 10%;
width: 6%;
height: 80px;
background: rgba(255, 255, 255, 0.4);
border-radius: 2px 2px 0 0;
box-shadow:
-30px 20px 0 rgba(255, 255, 255, 0.35),
-55px 35px 0 rgba(255, 255, 255, 0.28),
-80px 18px 0 rgba(255, 255, 255, 0.22);
}
}
.user-wrap { .user-wrap {
position: relative; position: relative;
@ -248,10 +207,13 @@ const onMenuClick = (item) => {
.menu-wrap { .menu-wrap {
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
padding: 0 16px 16px; padding:10px;
margin-top: -48px; margin-top: -42px;
position: relative; position: relative;
z-index: 2; z-index: 2;
background: #fbfdff;
border-top-left-radius: 14px;
border-top-right-radius: 14px;
} }
.menu-card { .menu-card {

6
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/notice/cp_notice_detail.vue

@ -1,11 +1,11 @@
<template> <template>
<div class="notice-detail-page app_content"> <div class="notice-detail-page app_content">
<!-- 顶部导航 --> <!-- 顶部导航 -->
<van-nav-bar <!-- <van-nav-bar
title="预告详情" title="预告详情"
left-arrow left-arrow
@click-left="onBack" @click-left="onBack"
/> /> -->
<div class="content"> <div class="content">
<div v-if="loading" class="loading-wrap"> <div v-if="loading" class="loading-wrap">
@ -133,7 +133,7 @@ onMounted(() => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
background: #eaf4ff; background: #fbfdff;
overflow: hidden; overflow: hidden;
} }

6
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/notice/cp_notice_edit.vue

@ -1,11 +1,11 @@
<template> <template>
<div class="notice-edit-page app_content"> <div class="notice-edit-page app_content">
<!-- 顶部导航 --> <!-- 顶部导航 -->
<van-nav-bar <!-- <van-nav-bar
:title="pageTitle" :title="pageTitle"
left-arrow left-arrow
@click-left="onBack" @click-left="onBack"
/> /> -->
<div class="content"> <div class="content">
<!-- 表单 --> <!-- 表单 -->
@ -687,7 +687,7 @@ const doSubmit = (isDraft) => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
background: #eaf4ff; background: #fbfdff;
overflow: hidden; overflow: hidden;
} }

6
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/notice/cp_notice_list.vue

@ -1,11 +1,11 @@
<template> <template>
<div class="notice-page app_content"> <div class="notice-page app_content">
<!-- 顶部导航 --> <!-- 顶部导航 -->
<van-nav-bar <!-- <van-nav-bar
title="预告" title="预告"
left-arrow left-arrow
@click-left="onBack" @click-left="onBack"
/> /> -->
<!-- Tab 切换 --> <!-- Tab 切换 -->
<van-tabs <van-tabs
@ -165,7 +165,7 @@ const onPublish = (item) => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
background: #eaf4ff; background: #fbfdff;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }

4
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/notice/cp_notice_tab_content.vue

@ -43,7 +43,7 @@
<div class="value">{{ item.enforceUserNames || '-' }}</div> <div class="value">{{ item.enforceUserNames || '-' }}</div>
</div> </div>
<div class="info-row"> <!-- <div class="info-row">
<div class="label">联系人:</div> <div class="label">联系人:</div>
<div class="value">{{ item.contactPerson || '-' }}</div> <div class="value">{{ item.contactPerson || '-' }}</div>
</div> </div>
@ -51,7 +51,7 @@
<div class="info-row"> <div class="info-row">
<div class="label">联系电话:</div> <div class="label">联系电话:</div>
<div class="value">{{ item.contactPhone || '-' }}</div> <div class="value">{{ item.contactPhone || '-' }}</div>
</div> </div> -->
<!-- 操作按钮 --> <!-- 操作按钮 -->
<div class="card-actions" v-if="canPublish || canEdit || canDelete || canMessage || canReinitiate" @click.stop> <div class="card-actions" v-if="canPublish || canEdit || canDelete || canMessage || canReinitiate" @click.stop>

2
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue

@ -805,7 +805,7 @@ const doSubmit = () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
background: #eaf4ff; background: #fbfdff;
overflow: hidden; overflow: hidden;
} }

6
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_list.vue

@ -1,11 +1,11 @@
<template> <template>
<div class="plan-page app_content"> <div class="plan-page app_content">
<!-- 顶部导航 --> <!-- 顶部导航 -->
<van-nav-bar <!-- <van-nav-bar
title="计划" title="计划"
left-arrow left-arrow
@click-left="onBack" @click-left="onBack"
/> /> -->
<!-- Tab 切换(通过路由切换) --> <!-- Tab 切换(通过路由切换) -->
<van-tabs <van-tabs
@ -71,7 +71,7 @@ const onAdd = () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
background: #eaf4ff; background: #fbfdff;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }

265
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_mine.vue

@ -1,7 +1,7 @@
<template> <template>
<div class="plan-mine"> <div class="plan-mine">
<!-- 状态过滤栏 --> <!-- 状态过滤栏 -->
<div class="filter-bar"> <!-- <div class="filter-bar">
<div <div
v-for="opt in filterOptions" v-for="opt in filterOptions"
:key="opt.label" :key="opt.label"
@ -11,34 +11,11 @@
> >
{{ opt.label }} {{ opt.label }}
</div> </div>
</div> </div> -->
<!-- 搜索触发栏 --> <!-- 统一搜索和时间筛选组件 -->
<div class="search-trigger" @click="showSearchPopup = true"> <SearchFilterBar :search-value="searchText" :date-type="dateType" :date-search="dateSearch"
<van-icon name="search" size="16" color="#666" /> @search="onSearch" @clear="onClear" @date-change="onDateChange" />
<span class="search-trigger-text">{{ searchSummary || '点击筛选查询' }}</span>
<van-icon v-if="hasSearchCondition" name="clear" size="14" color="#999" @click.stop="onResetSearch" />
</div>
<!-- 排序栏 -->
<div class="sort-bar">
<div
class="sort-item"
:class="{ active: sortField === 'createTime' }"
@click="onToggleSort('createTime')"
>
<span>创建时间</span>
<van-icon v-if="sortField === 'createTime'" :name="sortOrder === 'desc' ? 'arrow-down' : 'arrow-up'" size="12" />
</div>
<div
class="sort-item"
:class="{ active: sortField === 'planDate' }"
@click="onToggleSort('planDate')"
>
<span>执行日期</span>
<van-icon v-if="sortField === 'planDate'" :name="sortOrder === 'desc' ? 'arrow-down' : 'arrow-up'" size="12" />
</div>
</div>
<van-pull-refresh v-model="refreshing" @refresh="onRefresh"> <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list <van-list
@ -58,12 +35,12 @@
}" }"
@click="onToggleExpand(item)" @click="onToggleExpand(item)"
> >
<div class="card-header"> <!-- <div class="card-header">
<div class="card-type">{{ item.isUnion === 1 ? '联合执法' : '非联合执法' }} / {{ item.isPublic === 1 ? '公开' : '非公开' }}</div> <div class="card-type">{{ item.isUnion === 1 ? '联合执法' : '非联合执法' }} / {{ item.isPublic === 1 ? '公开' : '非公开' }}</div>
<div class="status blue" style="display: none"> <div class="status blue" style="display: none">
{{ getStatusText(item.reserveStatus) }} {{ getStatusText(item.reserveStatus) }}
</div> </div>
</div> </div> -->
<div class="plan-title">{{ item.enforceContent }}</div> <div class="plan-title">{{ item.enforceContent }}</div>
@ -158,58 +135,15 @@
<van-empty v-if="!loading && planList.length === 0" description="暂无计划" /> <van-empty v-if="!loading && planList.length === 0" description="暂无计划" />
</van-list> </van-list>
</van-pull-refresh> </van-pull-refresh>
<!-- 搜索弹窗 -->
<van-popup v-model:show="showSearchPopup" position="bottom" round :style="{ maxHeight: '70%' }">
<div class="search-popup">
<div class="search-popup-title">筛选查询</div>
<van-field
v-model="tempSearchForm.planDate"
label="执法日期"
placeholder="请选择"
readonly
is-link
@click="showSearchDate = true"
>
<template #right-icon>
<van-icon v-if="tempSearchForm.planDate" name="clear" @click.stop="tempSearchForm.planDate = ''" />
</template>
</van-field>
<van-field
v-model="tempSearchForm.enterpriseName"
label="企业名称"
placeholder="输入企业名称"
clearable
/>
<van-field
v-model="tempSearchForm.enforceContent"
label="执法事项"
placeholder="输入执法事项"
clearable
/>
<div class="search-popup-actions">
<van-button plain type="default" size="small" @click="onResetSearch">重置</van-button>
<van-button type="primary" size="small" @click="onConfirmSearch">查询</van-button>
</div>
</div>
</van-popup>
<!-- 日期选择器 -->
<van-popup v-model:show="showSearchDate" position="bottom" round :style="{ zIndex: 3000 }">
<van-date-picker
v-model="searchDateValue"
title="选择执法日期"
@confirm="onSearchDateConfirm"
@cancel="showSearchDate = false"
/>
</van-popup>
</div> </div>
</template> </template>
<script setup name="cpPlanMine"> <script setup name="cpPlanMine">
import { ref, onMounted } from 'vue';
import { showConfirmDialog, showToast } from 'vant'; import { showConfirmDialog, showToast } from 'vant';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { getPlanList, deletePlan } from '@/api/enforcement/plan'; import { getPlanList, deletePlan } from '@/api/enforcement/plan';
import SearchFilterBar from '@/components/common/SearchFilterBar.vue';
const router = useRouter(); const router = useRouter();
@ -227,75 +161,28 @@ const onFilterChange = (val) => {
doSearch(); doSearch();
}; };
// 排序相关 // 搜索和日期筛选相关
const sortField = ref('createTime'); // createTime | planDate const searchText = ref('');
const sortOrder = ref('desc'); // desc | asc const dateType = ref(null);
const dateSearch = ref(null);
const onToggleSort = (field) => {
if (sortField.value === field) { const onSearch = ({ searchValue } = {}) => {
// 同一字段切换升降序 if (searchValue !== undefined) {
sortOrder.value = sortOrder.value === 'desc' ? 'asc' : 'desc'; searchText.value = searchValue;
} else {
// 切换字段,默认降序
sortField.value = field;
sortOrder.value = 'desc';
} }
doSearch(); doSearch();
}; };
// 搜索相关 const onClear = () => {
const searchForm = ref({ searchText.value = '';
planDate: '', dateType.value = null;
enterpriseName: '', dateSearch.value = null;
enforceContent: '',
});
const tempSearchForm = ref({
planDate: '',
enterpriseName: '',
enforceContent: '',
});
const showSearchPopup = ref(false);
const showSearchDate = ref(false);
const searchDateValue = ref([
String(new Date().getFullYear()),
String(new Date().getMonth() + 1).padStart(2, '0'),
String(new Date().getDate()).padStart(2, '0'),
]);
// 是否有搜索条件
const hasSearchCondition = computed(() => {
const f = searchForm.value;
return !!(f.planDate || f.enterpriseName || f.enforceContent);
});
// 搜索摘要
const searchSummary = computed(() => {
const f = searchForm.value;
const parts = [];
if (f.planDate) parts.push(f.planDate);
if (f.enterpriseName) parts.push(f.enterpriseName);
if (f.enforceContent) parts.push(f.enforceContent);
return parts.join(' | ');
});
// 日期确认
const onSearchDateConfirm = ({ selectedValues }) => {
tempSearchForm.value.planDate = selectedValues.join('-');
showSearchDate.value = false;
};
// 确认搜索
const onConfirmSearch = () => {
searchForm.value = { ...tempSearchForm.value };
showSearchPopup.value = false;
doSearch(); doSearch();
}; };
// 重置搜索 const onDateChange = ({ dateType: dt, dateSearch: ds }) => {
const onResetSearch = () => { dateType.value = dt;
tempSearchForm.value = { planDate: '', enterpriseName: '', enforceContent: '' }; dateSearch.value = ds;
searchForm.value = { planDate: '', enterpriseName: '', enforceContent: '' };
showSearchPopup.value = false;
doSearch(); doSearch();
}; };
@ -313,7 +200,7 @@ const finished = ref(false);
const refreshing = ref(false); const refreshing = ref(false);
const pageNum = ref(1); const pageNum = ref(1);
const pageSize = 10; const pageSize = 10;
const expandedId = ref(null); // 当前展开的卡片ID const expandedId = ref(null);
// 切换展开/收起 // 切换展开/收起
const onToggleExpand = (item) => { const onToggleExpand = (item) => {
@ -368,12 +255,9 @@ const fetchList = () => {
loading.value = true; loading.value = true;
const params = { pageNum: pageNum.value, pageSize }; const params = { pageNum: pageNum.value, pageSize };
// 携带搜索条件 // 携带搜索条件
if (searchForm.value.planDate) params.planDate = searchForm.value.planDate; if (searchText.value) params.searchValue = searchText.value;
if (searchForm.value.enterpriseName) params.enterpriseName = searchForm.value.enterpriseName; // 携带日期筛选条件
if (searchForm.value.enforceContent) params.enforceContent = searchForm.value.enforceContent; if (dateSearch.value) params.planDate = dateSearch.value;
// 携带排序条件
params.orderByColumn = sortField.value;
params.isAsc = sortOrder.value;
// 携带状态过滤 // 携带状态过滤
if (filterStatus.value) { if (filterStatus.value) {
params['params[reserveStatusList]'] = filterStatus.value; params['params[reserveStatusList]'] = filterStatus.value;
@ -428,15 +312,19 @@ const onDeletePlan = (item) => {
}); });
}).catch(() => {}); }).catch(() => {});
}; };
// 页面挂载加载数据
onMounted(() => {
loading.value = true;
fetchList();
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.plan-mine { .plan-mine {
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
padding: 12px;
padding-top: 0; padding-top: 0;
box-sizing: border-box;
} }
.filter-bar { .filter-bar {
@ -464,91 +352,11 @@ const onDeletePlan = (item) => {
} }
} }
.search-trigger {
margin-top: 8px;
display: flex;
align-items: center;
gap: 8px;
background: #fff;
border-radius: 20px;
padding: 10px 14px;
margin-bottom: 8px;
box-shadow: 0 2px 8px rgba(44, 116, 190, 0.06);
cursor: pointer;
.search-trigger-text {
flex: 1;
font-size: 13px;
color: #999;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.sort-bar {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 12px;
padding: 0 4px;
.sort-item {
display: flex;
align-items: center;
gap: 3px;
font-size: 13px;
color: #999;
cursor: pointer;
padding: 4px 10px;
border-radius: 14px;
transition: all 0.2s;
&.active {
color: #2382cf;
font-weight: 500;
background: rgba(35, 130, 207, 0.08);
}
}
}
.search-popup {
padding: 16px;
.search-popup-title {
font-size: 16px;
font-weight: 600;
text-align: center;
margin-bottom: 16px;
color: #333;
}
:deep(.van-field) {
padding: 10px 0;
}
:deep(.van-field__label) {
width: 65px;
font-size: 14px;
color: #666;
}
.search-popup-actions {
display: flex;
gap: 12px;
margin-top: 20px;
padding: 0 10px;
.van-button {
flex: 1;
}
}
}
.plan-list { .plan-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 14px; padding:10px 12px;
box-sizing: border-box;
} }
/* 卡片通用 */ /* 卡片通用 */
@ -556,6 +364,7 @@ const onDeletePlan = (item) => {
border-radius: 14px; border-radius: 14px;
padding: 16px; padding: 16px;
overflow: hidden; overflow: hidden;
margin-bottom: 14px;
} }
.card-header { .card-header {

6
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_other.vue

@ -20,10 +20,10 @@
:key="item.id" :key="item.id"
class="plan-card normal-card pending-card" class="plan-card normal-card pending-card"
> >
<div class="card-header"> <!-- <div class="card-header">
<div class="card-type">{{ item.isUnion === 1 ? '联合执法' : '非联合执法' }}</div> <div class="card-type">{{ item.isUnion === 1 ? '联合执法' : '非联合执法' }}</div>
<div class="status blue">待预约</div> <div class="status blue">待预约</div>
</div> </div> -->
<div class="plan-title">{{ item.enforceContent }}</div> <div class="plan-title">{{ item.enforceContent }}</div>
@ -323,7 +323,7 @@ const onReservePlan = (item) => {
// 提示无法预约:仅当服务端返回500且消息为"请先添加我的计划再进行预约"时,才显示"添加计划"按钮 // 提示无法预约:仅当服务端返回500且消息为"请先添加我的计划再进行预约"时,才显示"添加计划"按钮
const showCannotReserveDialog = (item, code, msg) => { const showCannotReserveDialog = (item, code, msg) => {
const needAddPlanBtn = code === 500 && msg === '请先添加我的计划再进行预约'; const needAddPlanBtn = code === 500 && msg === '请先添加计划再进行预约';
if (needAddPlanBtn) { if (needAddPlanBtn) {
showDialog({ showDialog({
title: '提示', title: '提示',

Loading…
Cancel
Save