Browse Source

修改分页及首页

yangg 1 day ago
parent
commit
eb98502b27

+ 1 - 1
index.html

@@ -14,7 +14,7 @@
 		/>
 		<link rel="icon" href="/favicon.ico" />
 		<title>django-vue-admin</title>
-		 <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
+		<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
 	</head>
 	<body>
     <div id="app"></div>

+ 1 - 1
src/layout/navBars/breadcrumb/user.vue

@@ -93,7 +93,7 @@
 			<template #dropdown>
 				<el-dropdown-menu>
 					<el-dropdown-item command="/home">{{ $t('message.user.dropdown1') }}</el-dropdown-item>
-					<el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item>
+					<!-- <el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item> -->
 					
 					<el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item>
 				</el-dropdown-menu>

+ 1 - 1
src/utils/service.ts

@@ -174,7 +174,7 @@ function createRequestFunction(service: any) {
 			headers: {
 				'Content-Type': get(config, 'headers.Content-Type', 'application/json'),
 			},
-			timeout: 5000,
+			timeout: 20000,
 			baseURL: getBaseURL(),
 			data: {},
 		};

+ 1 - 1
src/views/system/Inventorycount/crud.tsx

@@ -123,7 +123,7 @@ export const createCrudOptions = function ({ crudExpose , inventoryDialog}: Crea
 
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/allusers/crud.tsx

@@ -59,7 +59,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				}
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/areas/crud.tsx

@@ -68,7 +68,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				},
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},
 			table: {
 				rowKey: 'id',

+ 1 - 1
src/views/system/borrowingnotice/crud.tsx

@@ -60,7 +60,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/deviceclass/crud.tsx

@@ -64,7 +64,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				},
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/devicedamage/crud.tsx

@@ -93,7 +93,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/devicelabel/crud.tsx

@@ -59,7 +59,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/devicemaintenance/crud.tsx

@@ -76,7 +76,7 @@ export const createCrudOptions = function ({ crudExpose,  dialogId,
 
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/devicemanual/crud.tsx

@@ -69,7 +69,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/devicepreserve/crud.tsx

@@ -64,7 +64,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/devicepreserveplan/crud.tsx

@@ -64,7 +64,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 2 - 1
src/views/system/home/api.ts

@@ -20,10 +20,11 @@ export function GetOverviewList() {
 	});
 }
 
-export function GetDeviceRankList() {
+export function GetDeviceRankList(params:object) {
 	return request({
 		url: apiPrefix+'device_rankings/',
 		method: 'get',
+		params:params
 	});
 }
 

+ 56 - 29
src/views/system/home/index.vue

@@ -11,8 +11,8 @@
 							<el-button class="fullscreen-btn" type="text" @click="toggleFullScreen">
 								<el-icon><FullScreen v-if="!isFullscreen"/><Aim v-else/></el-icon>
 							</el-button>
-							<el-button class="settings-btn" type="text" @click="openSettings">
-								<el-icon><Setting /></el-icon>
+							<el-button class="fullscreen-btn" type="text" @click="openSettings">
+								<el-icon :size="40"><Setting /></el-icon>
 							</el-button>
 						</div>
 						<h1>设备运维数据中心</h1>
@@ -116,22 +116,22 @@
 
 							<li>
 
-								<div class="timeselect" style="height:30px">
-									<!-- 快捷时间选择 -->
+								<!-- <div class="timeselect" style="height:30px">
+									
 									<el-radio-group class="transparent-radio" v-model="quickRange"
 										@change="handleQuickRange">
 										<el-radio-button label="day">今日</el-radio-button>
 										<el-radio-button label="month">本月</el-radio-button>
 										<el-radio-button label="year">今年</el-radio-button>
 									</el-radio-group>
-								</div>
-								<div v-if="panelSettings.deviceBorrowRanking" class="boxall" :style="{ height: !panelSettings.activeUsers ? '670px' : '350px', overflow: 'hidden' }">
+								</div> -->
+								<div v-if="panelSettings.deviceBorrowRanking" class="boxall" :style="{ height: !panelSettings.activeUsers ? '670px' : '400px', overflow: 'hidden' }">
 									<div class="alltitle">单台设备累计借用次数排名</div>
 									<div class="navboxall">
 
-										<div class="filter-bar"
+										<!-- <div class="filter-bar"
 											style="margin-bottom: 10px; display: flex; gap: 12px; align-items: center;">
-											<!-- 借用类型筛选 -->
+									
 											<el-select class="transparent-select"  v-model="selectedType"
 												placeholder="借用类型" @change="fetchRankings">
 												<el-option label="全部" value="all" />
@@ -141,7 +141,7 @@
 											</el-select>
 
 
-											<!-- 时间范围筛选 -->
+											
 											<el-date-picker v-model="dateRange" type="daterange"
 												start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD"
 												value-format="YYYY-MM-DD" @change="fetchRankings" />
@@ -151,9 +151,9 @@
 											<el-option v-for="item in labelType" :key="item.id" :label="item.name" :value="item.id" />
 											</el-select>
 
-										</div>
+										</div> -->
 
-										<el-table :data="teamRankings" style="width: 100%;height: 75%;">
+										<el-table :data="teamRankings" style="width: 100%;height: 95%;">
 											<el-table-column type="index" label="排名" width="80" />
 											<el-table-column prop="device_name" label="设备名称" />
 											<!-- <el-table-column prop="device_code" label="设备编码" /> -->
@@ -171,13 +171,13 @@
 								</div>
 
 
-								<div v-if="panelSettings.activeUsers" class="boxall" :style="{ height: !panelSettings.deviceBorrowRanking ? '670px' : '320px' }">
+								<div v-if="panelSettings.activeUsers" class="boxall" :style="{ height: !panelSettings.deviceBorrowRanking ? '670px' : '310px' }">
 									<div class="alltitle">活跃用户排名</div>
 									<div class="navboxall">
 										<div class="wraptit">
 											<span>排名</span><span>用户名</span><span>学号/工号</span><span>总借用次数</span>
 										</div>
-										<div class="wrap" :style="isFullscreen?'height: 85%':'height: 61%'">
+										<div class="wrap" :style="isFullscreen?'height: 85%':'height: 60%'">
 											<ul>
 												<li v-for="(hero, index) in userList" :key="index" style="width: 100%;padding:5px 0 ;border-bottom: 1px solid #232e63 ;">
 													<div
@@ -239,6 +239,7 @@ import { request } from '/@/utils/service';
 import dayjs from 'dayjs';
 import { GetList } from '../devicelabel/api'
 import { FullScreen, Aim, Setting } from '@element-plus/icons-vue'
+import { Session, Local } from '/@/utils/storage';
 
 
 
@@ -605,9 +606,7 @@ export default defineComponent({
 			if (savedSettings) {
 				state.panelSettings = JSON.parse(savedSettings);
 			}
-			nextTick(() => {
-
-			});
+		/* 	fetchRankings(); */
 		});
 		// 由于页面缓存原因,keep-alive
 		onActivated(() => {
@@ -660,7 +659,15 @@ export default defineComponent({
 					state.devicedata = res.data;
 					updateZbCharts(res.data);
 				}
-				const drres = await api.GetDeviceRankList();
+				const borrow_rank = Local.get(`borrow_ranking_filters_${Session.get('userInfo').username}`)
+				const params = {
+					type: borrow_rank.borrowType,//selectedType.value,
+					start_date: borrow_rank.dateRange?.[0],
+					end_date: borrow_rank.dateRange?.[1],
+					tag_id:borrow_rank.deviceTagIds
+				};
+				console.log(borrow_rank);
+				const drres = await api.GetDeviceRankList(params);
 				if (res.code === 2000) {
 					state.teamRankings = [...drres.data.borrow_count_ranking].sort(
 						(a, b) => b.borrow_count - a.borrow_count
@@ -714,12 +721,13 @@ export default defineComponent({
 		};
 
 		const fetchRankings = async () => {
+			const borrow_rank = Local.get(`borrow_ranking_filters_${Session.get('userInfo').username}`)
 			try {
 				const params = {
-					type: selectedType.value,
-					start_date: dateRange.value?.[0],
-					end_date: dateRange.value?.[1],
-					tag_id:deviceTagId.value
+					type: borrow_rank.borrowType,//selectedType.value,
+					start_date: borrow_rank.dateRange.value?.[0],
+					end_date: borrow_rank.dateRange.value?.[1],
+					tag_id:borrow_rank.deviceTagIds
 				};
 				const res = await api.GetBorrowRanking(params);
 				if (res.code === 2000) {
@@ -900,15 +908,24 @@ export default defineComponent({
 
 
 		//更新利用趋势图
-		const updateMonthlyUtilizationChart = (monthlyData: Array<{ month: string; rate: number }>) => {
+		const updateMonthlyUtilizationChart = (monthlyData: Array<{ date: string; utilization_rate: number }>) => {
 			const echart5 = echarts.init(document.getElementById('echart5'));
 			if (!echart5) return;
-
+			console.log(monthlyData);
 			const option = {
 				xAxis: {
 					type: 'category',
 					data: monthlyData.map(item => item.date),
-					axisLabel: { color: '#fff' }
+					axisLabel: { 
+						color: '#fff',
+						rotate: 0, // 旋转45度,避免标签重叠
+						interval: 0, // 显示所有标签
+						fontSize: 10, // 调整字体大小
+						margin: 15 // 增加标签与轴的距离
+					},
+					axisTick: {
+						alignWithLabel: true // 刻度线与标签对齐
+					}
 				},
 				yAxis: {
 					type: 'value',
@@ -934,7 +951,8 @@ export default defineComponent({
 				grid: {
 					left: '3%',
 					right: '4%',
-					bottom: '3%',
+					bottom: '15%', // 增加底部空间,为旋转后的标签预留空间
+					top: '10%', // 适当增加顶部空间
 					containLabel: true
 				}
 			};
@@ -992,6 +1010,12 @@ export default defineComponent({
 		// 初始化时间显示
 		const initTime = () => {
 			const showTime = () => {
+				const timeElement = document.getElementById("showTime");
+				if (!timeElement) {
+					console.warn('时间显示元素未找到');
+					return;
+				}
+				
 				const dt = new Date();
 				const y = dt.getFullYear();
 				const mt = dt.getMonth() + 1;
@@ -999,11 +1023,14 @@ export default defineComponent({
 				const h = dt.getHours();
 				const m = dt.getMinutes();
 				const s = dt.getSeconds();
-				document.getElementById("showTime")!.innerHTML =
-					y + "年" + mt + "月" + day + "日" + h + "时" + m + "分" + s + "秒";
+				timeElement.innerHTML = y + "年" + mt + "月" + day + "日" + h + "时" + m + "分" + s + "秒";
 			};
-			showTime();
-			setInterval(showTime, 1000);
+			
+			// 延迟执行,确保DOM已渲染
+			nextTick(() => {
+				showTime();
+				setInterval(showTime, 1000);
+			});
 		};
 		//
 		/* function echarts_3() {

+ 109 - 6
src/views/system/login/component/account.vue

@@ -52,12 +52,23 @@
 			</el-col>
 		</el-form-item>
 		<el-form-item>
-			<el-checkbox v-model="state.agreePolicy">
-				已阅读并同意
-				<a href="/user-agreement" target="_blank" class="login-link">《用户服务协议》</a>
-				与
-				<a href="/privacy-policy" target="_blank" class="login-link">《隐私协议》</a>
-			</el-checkbox>
+			<!-- <el-row :gutter="20">
+				<el-col :span="24"> -->
+					<el-checkbox v-model="state.rememberPassword">
+						记住密码
+					</el-checkbox>
+				<!-- </el-col>
+			</el-row> -->
+			<!-- <el-row style="margin-top: 10px;">
+				<el-col :span="24">
+					<el-checkbox v-model="state.agreePolicy">
+						已阅读并同意
+						<a href="/user-agreement" target="_blank" class="login-link">《用户服务协议》</a>
+						与
+						<a href="/privacy-policy" target="_blank" class="login-link">《隐私协议》</a>
+					</el-checkbox>
+				</el-col>
+			</el-row> -->
 		</el-form-item>
 		<el-form-item class="login-animation4">
 			<el-button type="primary" class="login-content-submit" round @click="loginClick" :loading="loading.signIn" :disabled="!state.agreePolicy">
@@ -119,6 +130,7 @@ export default defineComponent({
 				signIn: false,
 			},
 			agreePolicy: true,
+			rememberPassword: false,
 		});
 		const rules = reactive<FormRules>({
 			//merchant_code: [{ required: true, message: '请填写商户号', trigger: 'blur' }],
@@ -164,6 +176,89 @@ export default defineComponent({
 				state.ruleForm.captchaKey = ret.data.key;
 			});
 		};
+		
+		// 简单的加密函数(使用异或加密 + Base64编码)
+		const simpleEncrypt = (text: string, key: string): string => {
+			let encrypted = '';
+			for (let i = 0; i < text.length; i++) {
+				const textChar = text.charCodeAt(i);
+				const keyChar = key.charCodeAt(i % key.length);
+				encrypted += String.fromCharCode(textChar ^ keyChar);
+			}
+			// 使用Base64进一步编码
+			return btoa(encrypted);
+		};
+
+		// 简单的解密函数(Base64解码 + 异或解密)
+		const simpleDecrypt = (encryptedText: string, key: string): string => {
+			try {
+				// 先进行Base64解码
+				const decoded = atob(encryptedText);
+				let decrypted = '';
+				for (let i = 0; i < decoded.length; i++) {
+					const encryptedChar = decoded.charCodeAt(i);
+					const keyChar = key.charCodeAt(i % key.length);
+					decrypted += String.fromCharCode(encryptedChar ^ keyChar);
+				}
+				return decrypted;
+			} catch (error) {
+				console.warn('解密失败,可能是数据损坏');
+				return '';
+			}
+		};
+
+		// 生成加密密钥(基于用户名和固定字符串)
+		const generateEncryptionKey = (username: string): string => {
+			const fixedKey = 'DVA_ADMIN_2024';
+			return fixedKey + username;
+		};
+
+		// 处理记住密码功能
+		const handleRememberPassword = () => {
+			if (state.rememberPassword) {
+				// 记住用户名和加密后的密码
+				const encryptionKey = generateEncryptionKey(state.ruleForm.username);
+				const encryptedPassword = simpleEncrypt(state.ruleForm.password, encryptionKey);
+				
+				localStorage.setItem('rememberedUsername', state.ruleForm.username);
+				localStorage.setItem('rememberedPassword', encryptedPassword);
+				localStorage.setItem('rememberPasswordChecked', 'true');
+				
+				console.log('密码已加密存储');
+			} else {
+				// 清除记住的用户名和密码
+				localStorage.removeItem('rememberedUsername');
+				localStorage.removeItem('rememberedPassword');
+				localStorage.removeItem('rememberPasswordChecked');
+			}
+		};
+		
+		// 初始化记住密码数据
+		const initRememberPassword = () => {
+			const rememberedUsername = localStorage.getItem('rememberedUsername');
+			const rememberedPassword = localStorage.getItem('rememberedPassword');
+			const rememberPasswordChecked = localStorage.getItem('rememberPasswordChecked');
+			
+			if (rememberPasswordChecked === 'true' && rememberedUsername && rememberedPassword) {
+				state.ruleForm.username = rememberedUsername;
+				
+				// 解密密码
+				const encryptionKey = generateEncryptionKey(rememberedUsername);
+				const decryptedPassword = simpleDecrypt(rememberedPassword, encryptionKey);
+				
+				if (decryptedPassword) {
+					state.ruleForm.password = decryptedPassword;
+					state.rememberPassword = true;
+					console.log('已成功加载并解密记住的密码');
+				} else {
+					// 解密失败,清除存储的数据
+					localStorage.removeItem('rememberedUsername');
+					localStorage.removeItem('rememberedPassword');
+					localStorage.removeItem('rememberPasswordChecked');
+					console.warn('密码解密失败,已清除存储数据');
+				}
+			}
+		};
 		const loginClick = async () => {
 			if (!formRef.value) return;
 			await formRef.value.validate((valid: any) => {
@@ -177,6 +272,10 @@ export default defineComponent({
 								Session.set('token', res.data.access);
 								Session.set('merchant_info', res.data.merchant_info);
 								useUserInfo().setPwdChangeCount(data.pwd_change_count);
+								
+								// 处理记住密码逻辑
+								handleRememberPassword();
+								
 								/* if (data.pwd_change_count == 0) {
 									return router.push('/login');
 								} */
@@ -236,6 +335,8 @@ export default defineComponent({
 			getCaptcha();
 			//获取系统配置
 			SystemConfigStore().getSystemConfigs();
+			// 初始化记住密码功能
+			initRememberPassword();
 		});
 		// 是否显示申请试用按钮
 		const showApply = () => {
@@ -252,6 +353,8 @@ export default defineComponent({
 			rules,
 			applyBtnClick,
 			showApply,
+			handleRememberPassword,
+			initRememberPassword,
 			...toRefs(state),
 		};
 	},

+ 1 - 1
src/views/system/menu/components/MenuButtonCom/crud.tsx

@@ -85,7 +85,7 @@ export const createCrudOptions = function ({crudExpose, context}: CreateCrudOpti
                 }
             },
             pagination:{
-                show:false
+                show:true
             },
             search: {
                 container: {

+ 1 - 1
src/views/system/menu/components/MenuFieldCom/crud.tsx

@@ -71,7 +71,7 @@ const toggleRowSelection = () => {
 				delRequest,
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},
 			actionbar: {
 				buttons: {

+ 1 - 1
src/views/system/noticelist/crud.tsx

@@ -59,7 +59,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 110 - 3
src/views/system/screenconsole/component/BorrowRankingList.vue

@@ -19,7 +19,7 @@
             @change="fetchRanking" />
         </el-col>
         <el-col :span="6">
-          <el-select multiple clearable v-model="deviceTagIds" placeholder="标签名" style="margin-left: 30%; width: 100px;"
+          <el-select multiple clearable v-model="deviceTagIds" placeholder="标签名" collapse-tags style="margin-left: 30%; width: 100px;"
             @change="fetchRanking">
             <el-option v-for="item in labelType" :key="item.id" :label="item.name" :value="item.id" >
               <template #default>
@@ -58,7 +58,7 @@
 import { ref, onMounted } from 'vue'
 import * as api from '../api'
 import { GetList } from '../../devicelabel/api'
-import { Session } from '/@/utils/storage';
+import { Session, Local } from '/@/utils/storage';
 
 interface RankingItem {
   user_id: number
@@ -68,6 +68,11 @@ interface RankingItem {
   total_quantity: number
 }
 
+interface LabelItem {
+  id: number
+  name: string
+}
+
 const borrowType = ref('all')
 const dateRange = ref<[string, string] | null>(null)
 const keyword = ref('')
@@ -75,6 +80,9 @@ const rankingData = ref<RankingItem[]>([])
 // const deviceTagId = ref('')
 const deviceTagIds = ref<number[]>([])
 
+// 本地存储相关配置
+const STORAGE_KEY = 'borrow_ranking_filters'
+
 
 const fetchRanking = async () => {
   const params: Record<string, any> = {
@@ -103,9 +111,12 @@ const fetchRanking = async () => {
   } else {
     rankingData.value = []
   }
+  
+  // 保存当前筛选条件到本地存储
+  saveFiltersToStorage()
 }
 
-const labelType = ref([])
+const labelType = ref<LabelItem[]>([])
 const getList = async () => {
   const res = await GetList({
     page: 1,
@@ -116,7 +127,103 @@ const getList = async () => {
   }
 }
 
+// 保存筛选条件到本地存储(无加密版本)
+const saveFiltersToStorage = () => {
+  try {
+    const userInfo = Session.get('userInfo')
+    if (!userInfo?.username) return
+    
+    const filters = {
+      borrowType: borrowType.value,
+      dateRange: dateRange.value,
+      deviceTagIds: deviceTagIds.value,
+      timestamp: Date.now(), // 添加时间戳用于数据有效期控制
+      version: '1.0' // 版本号用于后续数据结构升级
+    }
+    
+    // 使用用户名作为存储键的一部分,实现用户级别的数据隔离
+    const storageKey = `${STORAGE_KEY}_${userInfo.username}`
+    Local.set(storageKey, filters)
+    
+    console.log('筛选条件已保存到本地存储',filters)
+  } catch (error) {
+    console.error('保存筛选条件失败:', error)
+  }
+}
+
+// 从本地存储恢复筛选条件(无加密版本)
+const loadFiltersFromStorage = () => {
+  try {
+    const userInfo = Session.get('userInfo')
+    if (!userInfo?.username) return
+    
+    const storageKey = `${STORAGE_KEY}_${userInfo.username}`
+    const storedData = Local.get(storageKey)
+    
+    if (!storedData) return
+    
+    // 检查数据有效期(7天)
+    const now = Date.now()
+    const maxAge = 7 * 24 * 60 * 60 * 1000 // 7天
+    if (storedData.timestamp && (now - storedData.timestamp) > maxAge) {
+      Local.remove(storageKey)
+      console.log('筛选条件已过期,已清除本地数据')
+      return
+    }
+    
+    // 恢复筛选条件
+    if (storedData.borrowType) {
+      borrowType.value = storedData.borrowType
+    }
+    if (storedData.dateRange) {
+      dateRange.value = storedData.dateRange
+    }
+    if (storedData.deviceTagIds && Array.isArray(storedData.deviceTagIds)) {
+      deviceTagIds.value = storedData.deviceTagIds
+    }
+    
+    console.log('筛选条件已从本地存储恢复')
+  } catch (error) {
+    console.error('恢复筛选条件失败:', error)
+    // 发生错误时清除可能损坏的数据
+    const userInfo = Session.get('userInfo')
+    if (userInfo?.username) {
+      const storageKey = `${STORAGE_KEY}_${userInfo.username}`
+      Local.remove(storageKey)
+    }
+  }
+}
+
+// 清除本地存储的筛选条件
+const clearStoredFilters = () => {
+  try {
+    const userInfo = Session.get('userInfo')
+    if (!userInfo?.username) return
+    
+    const storageKey = `${STORAGE_KEY}_${userInfo.username}`
+    Local.remove(storageKey)
+    console.log('已清除本地存储的筛选条件')
+  } catch (error) {
+    console.error('清除筛选条件失败:', error)
+  }
+}
+
+// 重置筛选条件
+const resetFilters = () => {
+  borrowType.value = 'all'
+  dateRange.value = null
+  deviceTagIds.value = []
+  
+  // 清除本地存储
+  clearStoredFilters()
+  
+  // 重新获取数据
+  fetchRanking()
+}
+
 onMounted(() => {
+  // 先恢复筛选条件,再获取数据
+  loadFiltersFromStorage()
   fetchRanking()
   if(Session.get('userInfo').username =='平台管理员') return
   getList()

+ 15 - 13
src/views/system/screenconsole/component/InfoCards.vue

@@ -8,9 +8,10 @@
       <div v-for="(item, index) in infoList" :key="index" @click="handleClick(item)" :class="item.class" class="stat-card"
         data-animate="slideInRight">
         <div class="stat-icon">
-          <el-icon :size="40" class="card-icon" :style="{ color: item.color }">
+          <!-- <el-icon :size="40" class="card-icon" :style="{ color: item.color }">
             <component :is="item.icon" />
-          </el-icon>
+          </el-icon> -->
+           <i class="fas" :class="item.iconFont"></i>
         </div>
         <div class="stat-content">
           <span class="stat-number" data-target="423">{{ item.value }}</span>
@@ -111,14 +112,14 @@ const props = defineProps({
   }
 })
 
-const infoList = computed(() => [
-  { label: '设备总库存数', value: props.summaryData.total_devices, icon: Goods, color: '#409EFF',class:'blue' },
-  { label: '在借数', value: props.summaryData.borrowed_devices, icon: Box, color: '#F56C6C',class:'red' },
-  { label: '在库数', value: props.summaryData.available_devices, icon: Collection, color: '#67C23A',class:'green' },
-  { label: '今日借出', value: props.summaryData.today_borrowed, icon: Timer, color: '#E6A23C',class:'yellow' },
-  { label: '今日归还', value: props.summaryData.today_returned, icon: RefreshRight, color: '#909399',class:'gray' },
-  { label: '累计借用人次', value: props.summaryData.total_borrowers, icon: User, color: '#3498DB',class:'purple' },
-  { label: '累计借用次数', value: props.summaryData.total_borrows, icon: DataLine, color: '#9B59B6',class:'teal' },
+const infoList = computed(() => [//
+  { label: '设备总库存数', value: props.summaryData.total_devices, icon: Goods, color: '#409EFF',class:'blue',iconFont:'fa-shopping-bag' },
+  { label: '在借数', value: props.summaryData.borrowed_devices, icon: Box, color: '#F56C6C',class:'red',iconFont:'fa-calendar-alt' },
+  { label: '在库数', value: props.summaryData.available_devices, icon: Collection, color: '#67C23A',class:'green',iconFont:'fa-chart-line' },
+  { label: '今日借出', value: props.summaryData.today_borrowed, icon: Timer, color: '#E6A23C',class:'yellow',iconFont:'fa-clock' },
+  { label: '今日归还', value: props.summaryData.today_returned, icon: RefreshRight, color: '#909399',class:'gray',iconFont:'fa-sync-alt' },
+  { label: '累计借用人次', value: props.summaryData.total_borrowers, icon: User, color: '#3498DB',class:'purple',iconFont:'fa-users' },
+  { label: '累计借用次数', value: props.summaryData.total_borrows, icon: DataLine, color: '#9B59B6',class:'teal',iconFont:'fa-chart-bar' },
 
 ]);
 function handleClick(item: any) {
@@ -212,10 +213,10 @@ function handleClick(item: any) {
   box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
   transition: all 0.3s ease;
   cursor: pointer;
-
- transform: translateY(15px);
+ transform: translateY(30px);
   position: relative;
   overflow: hidden;
+  min-height: 90px;
 }
 
 .stat-card::before {
@@ -275,8 +276,9 @@ function handleClick(item: any) {
   align-items: center;
   justify-content: center;
   margin-right: 12px;
-/*   background: var(--card-color); */
+  background: var(--card-color);
   color: #fff;
+  font-size: 20px;
 }
 
 .stat-content {

+ 1 - 1
src/views/system/screenconsole/component/StatusCards.vue

@@ -179,7 +179,7 @@ function handleClick(item: any) {
     display: grid;
     grid-template-columns: 1fr 1fr;
     grid-template-rows: 1fr 1fr;
-    gap: 20px;
+    gap: 30px;
     height: 200px;
 }
 .pending-item {

+ 1 - 1
src/views/system/storelist/crud.tsx

@@ -42,7 +42,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				}
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/studentInfo/crud.tsx

@@ -59,7 +59,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				}
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/teacherInfor/crud.tsx

@@ -50,7 +50,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				},
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {
 				_index: {

+ 1 - 1
src/views/system/timetablemanage/crud.tsx

@@ -47,7 +47,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				},
 			},
 			pagination: {
-				show: false,
+				show: true,
 			},		
 			columns: {