浏览代码

搜索框折叠

Luka 4 天之前
父节点
当前提交
5aeb3bb8d2

+ 61 - 24
src/views/notificationAnalysis/mattersStatistics/components/pageSearch.vue

@@ -8,9 +8,13 @@
 			class="search-form"
 		>
 			<!-- 第一行:筛选项 -->
-			<el-row :gutter="12" class="form-row">
-				<template v-for="item in searchConfig.formItems" :key="item.prop">
-					<el-col :span="item.span || 6" class="form-col">
+			<el-row :gutter="24" class="form-row">
+				<template v-for="(item, index) in searchConfig.formItems" :key="item.prop">
+					<el-col
+						:span="item.span || 6"
+						class="form-col"
+						:style="{ display: isCollapsed && index >= visibleItemsCount ? 'none' : 'block' }"
+					>
 						<el-form-item :label="item.label" :prop="item.prop">
 							<template v-if="item.type === 'input'">
 								<el-input v-model="searchForm[item.prop]" :placeholder="item.placeholder" />
@@ -61,13 +65,19 @@
 				</template>
 			</el-row>
 
-			<!-- 第二行:按钮区域 -->
 			<el-row class="btn-row">
 				<el-col :span="24">
 					<div class="btns">
 						<el-button size="default" type="primary" @click="handleQueryClick">查询</el-button>
 						<el-button size="default" @click="handleResetClick">重置</el-button>
 						<el-button size="default" type="primary" @click="onExport()">导出</el-button>
+						<el-button size="default" type="text" @click="toggleCollapse" v-if="showCollapseButton">
+							{{ isCollapsed ? '展开' : '收起' }}
+							<el-icon>
+								<ArrowUp v-if="!isCollapsed" />
+								<ArrowDown v-else />
+							</el-icon>
+						</el-button>
 					</div>
 				</el-col>
 			</el-row>
@@ -75,9 +85,10 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="page-search">
+<script setup lang="ts">
+import { ArrowUp, ArrowDown } from '@element-plus/icons-vue';
 import type { ElForm } from 'element-plus';
-import { reactive, ref, defineProps, defineEmits, watch, nextTick } from 'vue';
+import { reactive, ref, defineProps, defineEmits, watch, nextTick, computed } from 'vue';
 import useSystemStore from '@/store/main';
 import useUserStore from '@/store/modules/user';
 import { parseTime } from '@/utils/ruoyi';
@@ -89,9 +100,19 @@ import { storeToRefs } from 'pinia';
 const formRef = ref<InstanceType<typeof ElForm>>();
 const systemStore = useSystemStore();
 const sharedValueStore = useSharedValueStore();
-const { searchObj, pageList } = storeToRefs(systemStore); // 监听 pageList 变化
+const { searchObj, pageList } = storeToRefs(systemStore);
 const userStore = useUserStore().userInfo.userName === 'admin' ? '' : useUserStore().userInfo.userId;
 
+// 添加折叠功能相关状态
+const isCollapsed = ref(false);
+const showCollapseButton = computed(() => {
+	return props.searchConfig.formItems.length > visibleItemsCount;
+});
+
+const toggleCollapse = () => {
+	isCollapsed.value = !isCollapsed.value;
+};
+
 // Props 定义
 interface IProps {
 	searchConfig: {
@@ -113,11 +134,14 @@ interface IProps {
 		}>;
 		labelWidth?: number;
 		pageListParams?: Record<string, any>;
+		viewCount?: number; // 用于折叠(两行显示的项目数)
 	};
 }
 const props = defineProps<IProps>();
 const emit = defineEmits(['datePickerChange', 'handleSure']);
 
+const visibleItemsCount = props.searchConfig.viewCount || 8; // 两行显示的项目数(假设每行4个,共8个)
+
 // 动态生成初始值
 const generateInitialForm = () => {
 	const form: Record<string, any> = {};
@@ -159,14 +183,12 @@ const handleResetClick = async () => {
 
 	const newInitialForm = generateInitialForm();
 	Object.keys(searchForm).forEach(key => {
-		searchForm[key] = newInitialForm[key]; // 避免直接替换对象导致响应式失效
+		searchForm[key] = newInitialForm[key];
 	});
 
-	// 3. 等待数据更新完成后再请求
 	await nextTick();
-	fetchPageListData(searchForm); // 请求初始数据
-	sharedValueStore.upDatePageNum(2); // 同步页码状态
-	emit('handleSure', searchForm);
+	fetchPageListData(searchForm);
+	sharedValueStore.upDatePageNum(2);
 };
 
 const handleQueryClick = async () => {
@@ -186,12 +208,11 @@ const handleQueryClick = async () => {
 		}
 	});
 
-	// 2. 等待数据格式化完成后请求
 	await nextTick();
-	await fetchPageListData(formattedSearchForm); // 等待请求完成
-	searchObj.value = { ...formattedSearchForm }; // 解构赋值触发 Pinia 状态更新
+	await fetchPageListData(formattedSearchForm);
+	searchObj.value = { ...formattedSearchForm };
 	sharedValueStore.upDatePageNum(2);
-	emit('handleSure', formattedSearchForm);
+	emit('handleSure');
 };
 
 async function fetchPageListData(queryInfo: Record<string, any> = {}) {
@@ -216,28 +237,25 @@ async function fetchPageListData(queryInfo: Record<string, any> = {}) {
 	}
 }
 
-// 工具函数:格式化时间(带空值检查)
 function parseTimeWithCheck(value: any) {
 	if (!value) return '';
 	if (/^\d{8}$/.test(value)) return value;
 	return parseTime(value)?.slice(0, 10).replaceAll('-', '') || '';
 }
 
-// 日期选择器change事件
 const onDatePickerChange = (date: any) => {
 	emit('datePickerChange', date);
 };
 
-const getMonthDate = (event: any, prop: string) => {
-	// 月份选择器处理逻辑(根据业务需求补充)
-};
-
 const onExport = () => {
 	ElMessage.success('小编在努力开发中。。。');
 	return;
 };
 
-// 暴露方法
+const getMonthDate = (event: any, prop: string) => {
+	// 月份选择器处理逻辑
+};
+
 defineExpose({
 	searchForm,
 	fetchPageListData,
@@ -251,7 +269,6 @@ defineExpose({
 	background-color: #fff;
 	padding: 15px 20px;
 	border-radius: 5px;
-	width: 100%;
 
 	.search-form {
 		width: 100%;
@@ -286,6 +303,16 @@ defineExpose({
 			justify-content: flex-end;
 			gap: 10px;
 			padding: 10px 0;
+			align-items: center;
+
+			.el-button--text {
+				margin-left: 10px;
+				color: var(--el-color-primary);
+
+				.el-icon {
+					margin-left: 4px;
+				}
+			}
 		}
 	}
 
@@ -296,6 +323,16 @@ defineExpose({
 		.el-form-item {
 			padding: 8px 0;
 		}
+
+		// 移动端减少显示的项目数
+		.btn-row .btns {
+			flex-wrap: wrap;
+			justify-content: center;
+
+			.el-button {
+				margin: 4px;
+			}
+		}
 	}
 }
 </style>

+ 1 - 0
src/views/notificationAnalysis/mattersStatistics/config/search.config.ts

@@ -5,6 +5,7 @@ interface OptionsType {
 
 const searchConfig = {
 	pageName: 'ntlo',
+	viewCount: 4,
 	pageListParams: {
 		industryType: '1',
 		belongsDeptIds: '',

+ 2 - 52
src/views/notificationAnalysis/mattersStatistics/index.vue

@@ -1,9 +1,8 @@
 <template>
 	<div class="sensitive-words flex">
 		<div class="table-box">
-			<pageSearch ref="searchTableRef" :searchConfig="searchConfig" @handleSure="handerSearch" />
-
-			<statisticsItem :contentStatistics="contentStatistics"></statisticsItem>
+			<pageSearch ref="searchTableRef" :searchConfig="searchConfig" />
+			<statisticsItem></statisticsItem>
 			<statisticalChart class="mt20"></statisticalChart>
 			<majorStatisticalChart class="mt20"></majorStatisticalChart>
 			<pageContent ref="tableListRef" :total="total" v-loading="loading" :contentConfig="contentConfig">
@@ -84,55 +83,6 @@ const handleUnitdetail = async (id?: string) => {
 		query: { id: id },
 	});
 };
-// 查询回调 请求参数 并去获取图表及统计
-const handerSearch = async data => {
-	console.log(111);
-	handleStatistics();
-};
-const contentStatistics = ref<any>([]);
-const handleStatistics = async () => {
-	contentStatistics.value = [];
-	contentStatistics.value = [
-		{
-			label: '通报事项总计',
-			icon: '/assets/icon/1.png',
-			value: 1000,
-		},
-		{
-			label: '全国通用',
-			icon: '/assets/icon/1.png',
-			value: 19999,
-		},
-		{
-			label: '环渤海',
-			icon: '/assets/icon/1.png',
-			value: 19999,
-		},
-		{
-			label: '琼州海峡',
-			icon: '/assets/icon/1.png',
-			value: 19999,
-		},
-		{
-			label: '环渤海',
-			icon: '/assets/icon/1.png',
-			value: 19999,
-		},
-		{
-			label: '珠三角',
-			icon: '/assets/icon/1.png',
-			value: 19999,
-		},
-		{
-			label: '长三角',
-			icon: '/assets/icon/1.png',
-			value: 19999,
-		},
-	];
-};
-onMounted(() => {
-	handleStatistics();
-});
 
 const handleDownload = async () => {
 	ElMessageBox.confirm(`确定要导出所选数据信息?`, '提示', {

+ 61 - 24
src/views/notificationAnalysis/situationOverdueStatistics/components/pageSearch.vue

@@ -8,9 +8,13 @@
 			class="search-form"
 		>
 			<!-- 第一行:筛选项 -->
-			<el-row :gutter="12" class="form-row">
-				<template v-for="item in searchConfig.formItems" :key="item.prop">
-					<el-col :span="item.span || 6" class="form-col">
+			<el-row :gutter="24" class="form-row">
+				<template v-for="(item, index) in searchConfig.formItems" :key="item.prop">
+					<el-col
+						:span="item.span || 6"
+						class="form-col"
+						:style="{ display: isCollapsed && index >= visibleItemsCount ? 'none' : 'block' }"
+					>
 						<el-form-item :label="item.label" :prop="item.prop">
 							<template v-if="item.type === 'input'">
 								<el-input v-model="searchForm[item.prop]" :placeholder="item.placeholder" />
@@ -61,13 +65,19 @@
 				</template>
 			</el-row>
 
-			<!-- 第二行:按钮区域 -->
 			<el-row class="btn-row">
 				<el-col :span="24">
 					<div class="btns">
 						<el-button size="default" type="primary" @click="handleQueryClick">查询</el-button>
 						<el-button size="default" @click="handleResetClick">重置</el-button>
 						<el-button size="default" type="primary" @click="onExport()">导出</el-button>
+						<el-button size="default" type="text" @click="toggleCollapse" v-if="showCollapseButton">
+							{{ isCollapsed ? '展开' : '收起' }}
+							<el-icon>
+								<ArrowUp v-if="!isCollapsed" />
+								<ArrowDown v-else />
+							</el-icon>
+						</el-button>
 					</div>
 				</el-col>
 			</el-row>
@@ -75,9 +85,10 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="page-search">
+<script setup lang="ts">
+import { ArrowUp, ArrowDown } from '@element-plus/icons-vue';
 import type { ElForm } from 'element-plus';
-import { reactive, ref, defineProps, defineEmits, watch, nextTick } from 'vue';
+import { reactive, ref, defineProps, defineEmits, watch, nextTick, computed } from 'vue';
 import useSystemStore from '@/store/main';
 import useUserStore from '@/store/modules/user';
 import { parseTime } from '@/utils/ruoyi';
@@ -89,9 +100,19 @@ import { storeToRefs } from 'pinia';
 const formRef = ref<InstanceType<typeof ElForm>>();
 const systemStore = useSystemStore();
 const sharedValueStore = useSharedValueStore();
-const { searchObj, pageList } = storeToRefs(systemStore); // 监听 pageList 变化
+const { searchObj, pageList } = storeToRefs(systemStore);
 const userStore = useUserStore().userInfo.userName === 'admin' ? '' : useUserStore().userInfo.userId;
 
+// 添加折叠功能相关状态
+const isCollapsed = ref(false);
+const showCollapseButton = computed(() => {
+	return props.searchConfig.formItems.length > visibleItemsCount;
+});
+
+const toggleCollapse = () => {
+	isCollapsed.value = !isCollapsed.value;
+};
+
 // Props 定义
 interface IProps {
 	searchConfig: {
@@ -113,11 +134,14 @@ interface IProps {
 		}>;
 		labelWidth?: number;
 		pageListParams?: Record<string, any>;
+		viewCount?: number; // 用于折叠(两行显示的项目数)
 	};
 }
 const props = defineProps<IProps>();
 const emit = defineEmits(['datePickerChange', 'handleSure']);
 
+const visibleItemsCount = props.searchConfig.viewCount || 8; // 两行显示的项目数(假设每行4个,共8个)
+
 // 动态生成初始值
 const generateInitialForm = () => {
 	const form: Record<string, any> = {};
@@ -159,14 +183,12 @@ const handleResetClick = async () => {
 
 	const newInitialForm = generateInitialForm();
 	Object.keys(searchForm).forEach(key => {
-		searchForm[key] = newInitialForm[key]; // 避免直接替换对象导致响应式失效
+		searchForm[key] = newInitialForm[key];
 	});
 
-	// 3. 等待数据更新完成后再请求
 	await nextTick();
-	fetchPageListData(searchForm); // 请求初始数据
-	sharedValueStore.upDatePageNum(2); // 同步页码状态
-	emit('handleSure', searchForm);
+	fetchPageListData(searchForm);
+	sharedValueStore.upDatePageNum(2);
 };
 
 const handleQueryClick = async () => {
@@ -186,12 +208,11 @@ const handleQueryClick = async () => {
 		}
 	});
 
-	// 2. 等待数据格式化完成后请求
 	await nextTick();
-	await fetchPageListData(formattedSearchForm); // 等待请求完成
-	searchObj.value = { ...formattedSearchForm }; // 解构赋值触发 Pinia 状态更新
+	await fetchPageListData(formattedSearchForm);
+	searchObj.value = { ...formattedSearchForm };
 	sharedValueStore.upDatePageNum(2);
-	emit('handleSure', formattedSearchForm);
+	emit('handleSure');
 };
 
 async function fetchPageListData(queryInfo: Record<string, any> = {}) {
@@ -216,28 +237,25 @@ async function fetchPageListData(queryInfo: Record<string, any> = {}) {
 	}
 }
 
-// 工具函数:格式化时间(带空值检查)
 function parseTimeWithCheck(value: any) {
 	if (!value) return '';
 	if (/^\d{8}$/.test(value)) return value;
 	return parseTime(value)?.slice(0, 10).replaceAll('-', '') || '';
 }
 
-// 日期选择器change事件
 const onDatePickerChange = (date: any) => {
 	emit('datePickerChange', date);
 };
 
-const getMonthDate = (event: any, prop: string) => {
-	// 月份选择器处理逻辑(根据业务需求补充)
-};
-
 const onExport = () => {
 	ElMessage.success('小编在努力开发中。。。');
 	return;
 };
 
-// 暴露方法
+const getMonthDate = (event: any, prop: string) => {
+	// 月份选择器处理逻辑
+};
+
 defineExpose({
 	searchForm,
 	fetchPageListData,
@@ -251,7 +269,6 @@ defineExpose({
 	background-color: #fff;
 	padding: 15px 20px;
 	border-radius: 5px;
-	width: 100%;
 
 	.search-form {
 		width: 100%;
@@ -286,6 +303,16 @@ defineExpose({
 			justify-content: flex-end;
 			gap: 10px;
 			padding: 10px 0;
+			align-items: center;
+
+			.el-button--text {
+				margin-left: 10px;
+				color: var(--el-color-primary);
+
+				.el-icon {
+					margin-left: 4px;
+				}
+			}
 		}
 	}
 
@@ -296,6 +323,16 @@ defineExpose({
 		.el-form-item {
 			padding: 8px 0;
 		}
+
+		// 移动端减少显示的项目数
+		.btn-row .btns {
+			flex-wrap: wrap;
+			justify-content: center;
+
+			.el-button {
+				margin: 4px;
+			}
+		}
 	}
 }
 </style>

+ 1 - 0
src/views/notificationAnalysis/situationOverdueStatistics/config/search.config.ts

@@ -5,6 +5,7 @@ interface OptionsType {
 
 const searchConfig = {
 	pageName: 'ntlo',
+	viewCount: 4,
 	pageListParams: {
 		industryType: '1',
 		belongsDeptIds: '',

+ 1 - 5
src/views/notificationAnalysis/situationOverdueStatistics/index.vue

@@ -1,7 +1,7 @@
 <template>
 	<div class="sensitive-words flex">
 		<div class="table-box">
-			<pageSearch ref="searchTableRef" :searchConfig="searchConfig" @handleSure="handerSearch" />
+			<pageSearch ref="searchTableRef" :searchConfig="searchConfig" />
 			<overdueStatistics></overdueStatistics>
 			<industryOverdueStatistics></industryOverdueStatistics>
 			<statisticalChartPie class="mt20"></statisticalChartPie>
@@ -153,10 +153,6 @@ const handleUnitdetail = async (id?: string) => {
 		query: { id: id },
 	});
 };
-// 查询回调 请求参数 并去获取图表及统计
-const handerSearch = async data => {
-	console.log('data', data);
-};
 
 onMounted(() => {});
 const handleDownload = async () => {