浏览代码

refactor(mine): 优化代码结构
feat(mine/edit,pwdEdit):新增数据校验

HMY 1 年之前
父节点
当前提交
b036b371c9

+ 89 - 74
pages/mine/checkIn/checkIn.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="attendance-page">
+		
 		<view class="header">
 			<text class="title">我的考勤记录</text>
 			<picker mode="selector" :range="timeRanges" @change="onTimeRangeChange">
@@ -9,6 +10,7 @@
 			</picker>
 		</view>
 
+		<!-- 数据统计区域 -->
 		<view class="statistics" :class="{'show': chartShow}">
 			<view class="statistic-card">
 				<view class="statistic-title">考勤统计</view>
@@ -35,6 +37,7 @@
 			</view>
 		</view>
 
+		<!-- 今日签到信息区域 -->
 		<view class="todayCheckIn" :class="{'show': shouldShow}">
 			<view class="check-in-container">
 				<text class="title2">今日签到信息</text>
@@ -56,6 +59,8 @@
 				</view>
 			</view>
 		</view>
+
+		<!-- 图表区域 -->
 		<view class="chart-container" :class="{'show': chartShow}">
 			<view class="">
 				<text class="chart-title">考勤趋势图</text>
@@ -64,6 +69,7 @@
 				</view>
 			</view>
 		</view>
+		
 	</view>
 </template>
 
@@ -75,103 +81,110 @@
 	} from 'vue';
 
 
+	// 创建一个响应式对象记录今天的考勤数据
 	const todayData = reactive({
-		day: '2024-11-11',
-		startTime: '08:59:59',
-		endTime: '',
-		status: '待补卡'
+		day: '2024-11-11', // 当前日期
+		startTime: '08:59:59', // 晨签到时间
+		endTime: '', // 晚签到时间
+		status: '待补卡' // 签到状态
 	})
-	const shouldShow = ref(true)
-	const chartShow = ref(false)
-	//图表类型
-	const chartsType = ref('pie')
-	//图表要填充的数据
-	const chartData = ref({})
+
+	// 控制今日签到信息和图表显示的状态
+	const shouldShow = ref(true) // 今日签到信息是否显示
+	const chartShow = ref(false) // 图表是否显示
+
+	// 图表类型的响应式引用
+	const chartsType = ref('') 
+
+	// 图表要填充的数据
+	const chartData = ref({}) 
+
+	// 图表配置选项
 	const opts = ref({
-		color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
-		padding: [15, 15, 0, 5],
-		enableScroll: false,
-		legend: {},
+		color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"], // 设定图表颜色
+		padding: [15, 15, 0, 5], 
+		enableScroll: false, // 禁用滚动
+		legend: {}, // 图例设置
 		xAxis: {
-			disableGrid: true
+			disableGrid: true // 禁用网格线
 		},
 		yAxis: {
 			data: [{
-				min: 0
+				min: 0 // y轴最小值
 			}]
 		},
 		extra: {
 			column: {
-				type: "group",
-				width: 30,
-				activeBgColor: "#000000",
-				activeBgOpacity: 0.08
+				type: "group", 
+				width: 30, 
+				activeBgColor: "#000000", 
+				activeBgOpacity: 0.08 
 			}
 		}
 	});
+
+	// 时间范围选择数组
 	const timeRanges = ref(['日', '周', '月']);
-	const selectedTimeRange = ref('日');
-
-	//出勤...补卡统计
-	const attendanceCount = ref(0);
-	const leaveCount = ref(0);
-	const businessTripCount = ref(0);
-	const clockInCount = ref(0);
-	const makeUpCount = ref(0);
+	const selectedTimeRange = ref('日'); // 初始化选择的时间范围为“日”
+
+	// 考勤相关统计数据
+	const attendanceCount = ref(0); // 出勤次数
+	const leaveCount = ref(0); // 请假次数
+	const businessTripCount = ref(0); // 出差次数
+	const clockInCount = ref(0); // 打卡次数
+	const makeUpCount = ref(0); // 补卡次数
 	
-	const arr=ref([])
 
 	const currentData = ref({
-		attendance: 0,
-		leave: 0,
-		businessTrip: 0,
-		clockIn: 0,
-		makeUp: 0,
-		res: {},
+		attendance: 0, // 出勤
+		leave: 0, // 请假
+		businessTrip: 0, // 出差
+		clockIn: 0, // 打卡
+		makeUp: 0, // 补卡
+		res: {}, // 记录详细数据
 	});
 
-
 	onMounted(() => {
-		//初始化数据
 		fetchAttendanceData();
 	});
 
-	//日周月切换
+	// 时间范围切换事件
 	function onTimeRangeChange(event) {
-
-		const selectedIndex = event.detail.value;
-		console.log('selectedIndex', selectedIndex)
-		selectedTimeRange.value = timeRanges.value[selectedIndex];
-		fetchAttendanceData();
+		const selectedIndex = event.detail.value; 
+		selectedTimeRange.value = timeRanges.value[selectedIndex]; // 设置选择的时间范围(日周月)
+		fetchAttendanceData(); // 获取考勤数据
+		// 根据选择的时间范围更新展示内容
 		switch (selectedTimeRange.value) {
 			case '日':
-				showDay();
+				showDay(); // 显示今日考勤
 				break;
 			case '周':
-				chartsType.value = 'pie';
-				showWeekAndMonth();
+				chartsType.value = 'pie'; // 设置图表类型为饼图
+				showWeekAndMonth(); // 显示周考勤
 				break;
 			case '月':
-				chartsType.value = 'column';
-				showWeekAndMonth();
+				chartsType.value = 'column'; // 设置图表类型为柱状图
+				showWeekAndMonth(); // 显示月考勤
 				break;
-
 		}
-
 	};
 
+	// 显示今日考勤数据
 	function showDay() {
-		shouldShow.value = true;
-		chartShow.value = false;
+		shouldShow.value = true; // 显示今日签到信息
+		chartShow.value = false; // 隐藏图表
 	}
 
+	// 显示周或者月考勤
 	function showWeekAndMonth() {
-		shouldShow.value = false;
-		chartShow.value = true;
-		getData();
+		shouldShow.value = false; // 隐藏今日签到信息
+		chartShow.value = true; // 显示图表
+		getData(); // 获取图表数据
 	}
 
+	// 获取考勤数据的函数
 	function fetchAttendanceData() {
+		// 模拟考勤数据
 		const mockData = {
 			日: {
 				attendance: 5,
@@ -217,45 +230,46 @@
 				clockIn: 105,
 				makeUp: 3,
 				res: {
-					categories: ["第1周", "第2周", "第3周", "第4周"],
+					categories: ["第1周", "第2周", "第3周", "第4周"], 
 					series: [{
-							name: "出勤",
-							data: [35, 8, 25, 37]
-						},
-						{
-							name: "出差",
-							data: [70, 40, 65, 100]
-						},
-						{
-							name: "请假",
-							data: [100, 80, 95, 10]
-						}
-					]
+						name: "出勤",
+						data: [35, 8, 25, 37] 
+					},
+					{
+						name: "出差",
+						data: [70, 40, 65, 100]
+					},
+					{
+						name: "请假",
+						data: [100, 80, 95, 10] 
+					}]
 				},
 			}
 		};
 
+		// 获取当前选择时间范围的考勤数据
 		const currentData1 = mockData[selectedTimeRange.value];
-		currentData.value = currentData1;
+		currentData.value = currentData1; // 更新当前数据
 
+		// 更新统计数据
 		if (currentData1) {
 			attendanceCount.value = currentData1.attendance;
 			leaveCount.value = currentData1.leave;
 			businessTripCount.value = currentData1.businessTrip;
 			clockInCount.value = currentData1.clockIn;
 			makeUpCount.value = currentData1.makeUp;
-
 		} else {
-			console.error('没有找到相关的考勤数据:', selectedTimeRange.value);
+			console.error('没有找到相关的考勤数据:', selectedTimeRange.value); // 错误处理
 		}
 	}
 
+	// 获取图表数据
 	function getData() {
-		let res = currentData.value.res;
-		chartData.value = JSON.parse(JSON.stringify(res));
+		let res = currentData.value.res; // 获取当前数据的额外信息
+		chartData.value = JSON.parse(JSON.stringify(res)); // 更新图表数据
 	}
 	
-	//计算数组和
+	// 计算数组和的辅助函数 (未使用)
 	function countArr(arr){
 		const sum=0;
 		for (var i = 0; i < arr.length; i++) {
@@ -265,6 +279,7 @@
 	}
 </script>
 
+
 <style scoped>
 	.attendance-page {
 		padding: 20px;

+ 97 - 112
pages/mine/clockIn/clockIn.vue

@@ -1,10 +1,12 @@
 <template>
 	<view class="container">
+		<!-- 时间日期信息 -->
 		<view class="header">
 			<text class="day">{{ currentDay }}</text>
 			<text class="date">{{ currentDate }}</text>
 			<text class="status">{{clockInStatus}}</text>
 		</view>
+		<!-- 打卡记录 -->
 		<view class="record">
 			<view class="record-item">
 				<image :src="goToWorkImg" class="icon"></image>
@@ -22,6 +24,7 @@
 				<text class="time">{{ address ||'点击获取定位'}}</text>
 			</view>
 		</view>
+		<!-- 地图 -->
 		<atl-map :mapKey="mapKey" :mapType="mapType" @confirm="confirm" :marker="marker" :polygons="polygons"
 			:isPolygons="true">
 			<template v-slot:content>
@@ -31,6 +34,7 @@
 				</view>
 			</template>
 		</atl-map>
+		<!-- 打卡按钮 -->
 		<view class="footer">
 			<button type="primary" @click="signIn">上班签到</button>
 			<button type="default" @click="signOut">下班签退</button>
@@ -46,121 +50,98 @@
 		ref
 	} from 'vue';
 
+	// 导入图片资源
 	import goToWorkImg from "/static/images/mine/goToWork.png";
 	import afterWorkImg from "/static/images/mine/afterWork.png";
 	import locationImg from "/static/images/mine/location.png";
 
+	// 导入地理位置相关函数
 	import booleanPointInPolygon from "@turf/boolean-point-in-polygon";
-	import {
-		point,
-		polygon
-	} from "@turf/helpers";
-	// const UniMap = require('@/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common');
-
-	const mapKey = ref('KJBBZ-5JCLZ-3NLXD-742CK-Y26UZ-X7BJN');
-	const mapType = ref('tmap');
-	const address = ref('');
-
-	const currentDate = ref('2023-04-01');
-	const currentDay = ref('星期三');
-	const clockInStatus = ref('');
-	const weekArr = reactive(['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']);
-	const signInTime = ref('09:00');
-	const signOutTime = ref('');
-
-	const longitude = ref(0);
-	const latitude = ref(0);
-	const marker = reactive({
-		id: 1,
-		latitude: 25.958812,
-		longitude: 119.213036,
-		// iconPath: locationImg,
-		width: 50, // 标记的宽度
-		height: 50, // 标记的高度
-		title: '宇光同行'
-	})
-	const polygons = reactive([{
-		points: [{
-				latitude: 25.9591401,
-				longitude: 119.21292356
-			},
-			{
-				latitude: 25.95828592,
-				longitude: 119.21261955
-			},
-			{
-				latitude: 25.9576709,
-				longitude: 119.21458294
-			},
-			{
-				latitude: 25.95845106,
-				longitude: 119.21486162
-			},
-			{
-				latitude: 25.9591401,
-				longitude: 119.21292356
-			}
-
-		],
-		strokeWidth: 1,
-		strokeColor: "#ff000066",
-		fillColor: "#ff000016",
-	}, ])
-
+	import { point, polygon } from "@turf/helpers";
 
+	
 
+	// 组件挂载后初始化当前日期与位置
 	onMounted(() => {
-		dateInit();
-		getlocation();
+		dateInit(); 
+		getlocation(); 
 	});
 
 
+	// 当前日期和时间相关信息
+	const currentDate = ref('2023-04-01');
+	const currentDay = ref('星期三'); 
+	const clockInStatus = ref(''); // 打卡状态
+	const weekArr = reactive(['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']); // 星期数组
+	const signInTime = ref('09:00'); // 上班签到时间
+	const signOutTime = ref(''); // 下班签到时间
 
+	// 初始化日期
 	function dateInit() {
-		const nowDate = new Date();
-		const year = nowDate.getFullYear();
-		const month = nowDate.getMonth() + 1; // 月份是从0开始的,所以需要加1
-		const day = nowDate.getDate();
+		const nowDate = new Date(); 
+		const year = nowDate.getFullYear(); // 获取年份
+		const month = nowDate.getMonth() + 1; // 获取月份
+		const day = nowDate.getDate(); // 获取日期
 		// 格式化月份和日期为两位数
 		const formattedMonth = month < 10 ? '0' + month : month;
 		const formattedDay = day < 10 ? '0' + day : day;
-		currentDate.value = `${year}-${formattedMonth}-${formattedDay}`;
-		const dayOfWeek = nowDate.getDay();
-		currentDay.value = weekArr[dayOfWeek];
+		currentDate.value = `${year}-${formattedMonth}-${formattedDay}`; // 设置当前日期
+		const dayOfWeek = nowDate.getDay(); // 获取当前星期
+		currentDay.value = weekArr[dayOfWeek]; // 设置当前星期
 	}
 
+	// 上班签到
 	function signIn() {
-		getlocation();
-		tranAddress();
-		clockIn();
+		getlocation(); // 获取当前位置
+		tranAddress(); // 转换地址
+		clockIn(); // 执行打卡
 	};
 
+	// 下班签退
 	function signOut() {
-		getlocation();
-		tranAddress();
-		const flag= clockIn();	
-		if(flag){
+		getlocation(); // 获取当前位置
+		tranAddress(); // 转换地址
+		const flag = clockIn(); // 执行打卡并获取结果
+		if (flag) {
 			var now = new Date();
 			var hours = now.getHours();
 			var minutes = now.getMinutes();
-			signOutTime.value=hours+':'+minutes;
+			signOutTime.value = hours + ':' + minutes; // 获取当前时间作为下班时间
 		}
 	};
 
 
-	//获取当前定位经纬度
+	// 地图配置信息
+	const mapKey = ref('KJBBZ-5JCLZ-3NLXD-742CK-Y26UZ-X7BJN'); // 地图API密钥
+	const mapType = ref('tmap'); // 地图类型
+	const address = ref(''); // 初始化地址
+
+	// 打卡定位信息
+	const longitude = ref(0); // 经度
+	const latitude = ref(0); // 纬度
+
+	// 标记信息
+	const marker = reactive({
+		id: 1,
+		latitude: 25.958812,
+		longitude: 119.213036,
+		width: 50, // 标记宽度
+		height: 50, // 标记高度
+		title: '宇光同行' // 标记标题
+	});
+
+	// 获取当前定位经纬度
 	function getlocation() {
 		wx.getLocation({
 			type: 'gcj02',
 			success: (res) => {
-				console.log(res);
 				console.log('当前位置的经度:' + res.longitude);
 				console.log('当前位置的纬度:' + res.latitude);
-				longitude.value=res.longitude;
-				latitude.value=res.latitude;
+				longitude.value = res.longitude; // 保存经度
+				latitude.value = res.latitude; // 保存纬度
 			},
-			// 若用户点击拒绝获取位置则弹出提示
 			fail: (err) => {
+				// 获取位置失败时提示用户打开权限
 				uni.showModal({
 					content: '检测到您没打开获取位置功能权限,是否去设置打开?',
 					confirmText: "确认",
@@ -172,12 +153,12 @@
 									uni.showToast({
 										title: '授权后请重新打开此页面',
 										icon: 'none'
-									})
+									});
 								},
 								fail: (err) => {
-									console.log(err)
+									console.log(err);
 								}
-							})
+							});
 						} else {
 							uni.showToast({
 								title: '获取地理位置授权失败',
@@ -188,49 +169,55 @@
 										uni.showToast({
 											title: "返回上一页",
 											icon: 'none'
-										})
-										// uni.navigateBack({
-										//   delta: 1
-										// })
-									}, 500)
+										});
+									}, 500);
 								}
-							})
+							});
 						}
 					}
-				})
+				});
 			},
 		});
-		
 	}
 
-	//获取当前精确地址
-    async function getAddress() {
-		getlocation();
-		// console.log(latitude.value)
-		tranAddress();
+	// 获取当前位置地址
+	async function getAddress() {
+		getlocation(); // 获取当前位置
+		tranAddress(); // 执行地址转换
 	}
 	
-	//经纬度转地址
-	function tranAddress(){
-		let locationStr = latitude.value+','+longitude.value
+	// 经纬度转地址
+	function tranAddress() {
+		let locationStr = latitude.value + ',' + longitude.value; // 组合经纬度
 		uni.request({
-			url: 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + locationStr + '&key=' + mapKey.value +
-				'&get_poi=1',
+			url: 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + locationStr + '&key=' + mapKey.value + '&get_poi=1',
 			method: 'GET',
-			data: {
-				// 这里可以添加一些GET请求的参数
-			},
 			success: function(res) {
 				console.log('请求成功', res.data);
-				address.value = res.data.result.address;
+				address.value = res.data.result.address; // 保存地址
 			},
 			fail: function(err) {
-				console.error('请求失败', err);
+				console.error('请求失败', err); // 请求错误处理
 			}
 		});
 	}
 
-	//打卡
+
+	// 多边形区域设置
+	const polygons = reactive([{
+		points: [
+			{ latitude: 25.9591401, longitude: 119.21292356 },
+			{ latitude: 25.95828592, longitude: 119.21261955 },
+			{ latitude: 25.9576709, longitude: 119.21458294 },
+			{ latitude: 25.95845106, longitude: 119.21486162 },
+			{ latitude: 25.9591401, longitude: 119.21292356 }
+		],
+		strokeWidth: 1, // 边框宽度
+		strokeColor: "#ff000066", // 边框颜色
+		fillColor: "#ff000016", // 填充颜色
+	}]);
+
+	// 打卡
 	function clockIn() {
 		const _polygons = polygons.map((polygon) => {
 			return polygon.points.map((i) => [
@@ -238,22 +225,20 @@
 				Number(i.latitude),
 			]);
 		});
-		const _point = point([longitude.value, latitude.value]);
-		const _polygon = polygon(_polygons);
-		// 根据电子围栏判断否禁用
-		const f = booleanPointInPolygon(_point, _polygon);
-		// console.log(f);
+		const _point = point([longitude.value, latitude.value]); // 创建点
+		const _polygon = polygon(_polygons); // 创建多边形
+		const f = booleanPointInPolygon(_point, _polygon); // 判断点是否在多边形内
 		if (f) {
 			uni.showToast({
 				title: "打卡成功",
 				icon: 'none'
 			});
-			return true;
+			return true; // 打卡成功
 		} else {
 			uni.showToast({
 				title: "未在指定范围,打卡失败",
 				icon: 'none'
-			})
+			});
 		}
 	}
 </script>

+ 38 - 23
pages/mine/edit/edit.vue

@@ -1,7 +1,5 @@
 <template>
 	<view class="container">
-
-
 		<!-- 手机号码输入框 -->
 		<view class="input-group">
 			<text>手机号码:</text>
@@ -14,18 +12,11 @@
 			<input type="text" v-model="userInfo.email" placeholder="请输入邮箱地址" />
 		</view>
 
-
-		
-
 		<!-- 用户生日输入框 -->
 		<view class="input-group">
-
-
 			<text>用户生日:</text>
-
 			<view class="example-body">
-				<uni-datetime-picker type="date" :clear-icon="false" v-model="userInfo.birthday"
-					@maskClick="maskClick" />
+				<uni-datetime-picker type="date" :clear-icon="false" v-model="userInfo.birthday" @maskClick="maskClick" />
 			</view>
 		</view>
 		
@@ -48,9 +39,7 @@
 		<view class="primaryBtn">
 			<button type="primary" @click="handleSubmit">提交</button>
 		</view>
-
 	</view>
-
 </template>
 
 <script setup>
@@ -58,21 +47,48 @@
 		ref,
 		reactive
 	} from 'vue';
-
+	// 定义用户信息的响应式对象
 	const userInfo = reactive({
 		phone: '13145672389',
 		email: '',
 		gender: 'male',
 		birthday: '2000-01-10'
-
 	});
 	
-	function handleGenderChange(event){
-		userInfo.gender=event.detail.value;
-		// console.log(userInfo.birthday,userInfo.gender)
+	function handleGenderChange(event) {
+		userInfo.gender = event.detail.value; // 更新性别
 	};
 	
-	function handleSubmit(){
+	// 校验手机号码格式
+	function validatePhone(phone) {
+		const phoneRegex = /^1[3-9]\d{9}$/; // 手机号码格式正则(以1开头,11位数字)
+		return phoneRegex.test(phone);
+	}
+
+	// 校验邮箱格式
+	function validateEmail(email) {
+		const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; // 邮箱格式正则
+		return emailRegex.test(email);
+	}
+
+	// 处理提交事件
+	function handleSubmit() {
+		if (!validatePhone(userInfo.phone)) {
+			uni.showToast({
+				title: '手机号码格式不正确',
+				icon: 'none'
+			});
+			return; // 终止提交
+		}
+		
+		if (!validateEmail(userInfo.email)) {
+			uni.showToast({
+				title: '邮箱格式不正确',
+				icon: 'none'
+			});
+			return; // 终止提交
+		}
+
 		uni.showToast({
 			title: '提交成功',
 			icon: 'none'
@@ -94,11 +110,11 @@
 	.genderLabel {
 		padding-left: 20rpx;
 		margin: 20rpx auto;
-		
 		height: 70rpx;
 	}
-	.input-group input{
-		border: 1rpx, solid, gainsboro;
+
+	.input-group input {
+		border: 1rpx solid gainsboro; /* 修改边框样式 */
 		background-color: white;
 	}
 
@@ -109,10 +125,9 @@
 
 	.gender-selector label {
 		margin-right: 15rpx;
-		
 	}
 
 	.primaryBtn {
 		margin-top: 70rpx;
 	}
-</style>
+</style>

+ 121 - 70
pages/mine/index.vue

@@ -1,56 +1,68 @@
 <template>
 	<view class="content">
 		<!-- 用户信息部分 -->
-		<view class="user-info">
-			<image :src="headImg" class="avatar"></image>
-			<view class="info-detail">
-				<view>
-					<text>{{ userInfo.name}}</text>
+		<uni-card margin="0" spacing="0">
+			<view class="headImg">
+				<image :src="headImg" class="avatar"></image>
+			</view>
+			<view class="user-info">
+				<view class="info-detail">
+					<view class="name">
+						<text>姓名: {{ userInfo.name}}</text>
+					</view>
+					<view>
+						<text>ID: {{ userInfo.id }}</text>
+					</view>
+					<!-- 部门切换框 -->
+					<view class="uni-list-cell">
+						<view class="uni-list-cell-left">
+							部门:
+						</view>
+						<view class="uni-list-cell-db">
+							<picker @change="bindPickerChange" :value="index" :range="array">
+								<view class="uni-input">{{array[index]}}</view>
+							</picker>
+						</view>
+					</view>
+					<view>
+						<text> 职务: {{ userInfo.department[index].position }}</text>
+					</view>
+
 				</view>
-				<view>
-					<text>ID: {{ userInfo.id }}</text>
+				<uni-icons @click="lookMsg()" type="forward" size="50" style="margin-right: 30rpx;"></uni-icons>
+			</view>
+		</uni-card>
+
+		<uni-card margin="0" spacing="0">
+			<!-- 功能按钮区 -->
+			<view class="function-list">
+				<view class="function-item" @click="editData">
+					<image :src="messageEditImg" class="icon"></image>
+					<text class="title">编辑资料</text>
+					<text class="desc">></text>
 				</view>
-				<view>部门:
-					<uni-data-select v-model="value" :localdata="userInfo.department" @change="changeS1" :clear="false"
-						class="select1"></uni-data-select>
+				<view class="function-item" @click="waitWork">
+					<image :src="waitWorkImg" class="icon"></image>
+					<text class="title">待办事项</text>
+					<text class="desc">></text>
 				</view>
-				<view>
-					<text> 职务: {{ userInfo.department[value].position }}</text>
+				<view class="function-item" @click="checkIn">
+					<image :src="checkInImg" class="icon"></image>
+					<text class="title">我的考勤</text>
+					<text class="desc">></text>
+				</view>
+				<view class="function-item" @click="setting">
+					<image :src="settingImg" class="icon"></image>
+					<text class="title">应用设置</text>
+					<text class="desc">></text>
+				</view>
+				<view class="function-item" @click="clockIn">
+					<image :src="clockInImg" class="icon"></image>
+					<text class="title">我的打卡</text>
+					<text class="desc">></text>
 				</view>
-
-			</view>
-			<uni-icons @click="lookMsg()" type="forward" size="50" style="margin-right: 30rpx;"></uni-icons>
-
-		</view>
-
-		<!-- 功能按钮区 -->
-		<view class="function-list">
-			<view class="function-item" @click="handleButtonClick1">
-				<image :src="messageEdit" class="icon"></image>
-				<text class="title">编辑资料</text>
-				<text class="desc">></text>
-			</view>
-			<view class="function-item" @click="handleButtonClick2">
-				<image :src="waitWork" class="icon"></image>
-				<text class="title">待办事项</text>
-				<text class="desc">></text>
-			</view>
-			<view class="function-item" @click="handleButtonClick3">
-				<image :src="checkIn" class="icon"></image>
-				<text class="title">我的考勤</text>
-				<text class="desc">></text>
-			</view>
-			<view class="function-item" @click="handleButtonClick4">
-				<image :src="setting" class="icon"></image>
-				<text class="title">应用设置</text>
-				<text class="desc">></text>
-			</view>
-			<view class="function-item" @click="handleButtonClick5">
-				<image :src="waitWork" class="icon"></image>
-				<text class="title">打卡</text>
-				<text class="desc">></text>
 			</view>
-		</view>
+		</uni-card>
 
 
 	</view>
@@ -64,51 +76,68 @@
 	} from 'vue';
 
 	import headImg from "/static/images/mine/headImg.jpg"
-	import setting from "/static/images/mine/setting.png"
-	import checkIn from "/static/images/mine/checkIn.png"
-	import waitWork from "/static/images/mine/waitWork.png"
-	import messageEdit from "/static/images/mine/edit.png"
+	import settingImg from "/static/images/mine/setting.png"
+	import checkInImg from "/static/images/mine/checkIn.png"
+	import waitWorkImg from "/static/images/mine/waitWork.png"
+	import messageEditImg from "/static/images/mine/edit.png"
+	import clockInImg from "/static/images/mine/clockIn.png"
 	import $tab from "../../plugins/tab.js"
+
+
+	// 用户信息的响应式对象
 	const userInfo = reactive({
-		id: '123',
+		id: '123321',
 		name: '张三',
 		department: [{
-				value: 0,
 				text: "研发部",
 				position: '软件开发工程师'
 			},
 			{
-				value: 1,
 				text: "业务部",
 				position: '销售经理'
 			},
+			{
+				text: '法务部',
+				position: '法律顾问'
+			}
 		],
 	});
-	const value = ref(0);
+	// 部门数组
+	const array = ref(['研发部', '业务部', '法务部']);
+	const index = ref(0);
 
-	function changeS1(e) {
-		//部门切换事件
-		console.log(e)
+	// 部门切换事件
+	function bindPickerChange(e) {
+		index.value = e.detail.value; // 更新选择的部门索引
 	};
 
+	// 查看个人信息的函数
 	function lookMsg() {
-		$tab.navigateTo('/pages/mine/personal_message/personal_message')
+		$tab.navigateTo('/pages/mine/personal_message/personal_message?id=' + userInfo.id + '&name=' + userInfo.name);
 	};
 
-	function handleButtonClick1() {
+	// 编辑资料的函数
+	function editData() {
 		$tab.navigateTo('/pages/mine/edit/edit')
 	};
-	
-	function handleButtonClick2(){
+
+	// 待办事项的函数
+	function waitWork() {
 		$tab.navigateTo('/pages/mine/waitWork/waitWork')
 	}
-	function handleButtonClick3(){
+
+	// 我的考勤的函数
+	function checkIn() {
 		$tab.navigateTo('/pages/mine/checkIn/checkIn')
 	}
-	function handleButtonClick4() {
+
+	// 应用设置的函数
+	function setting() {
 		$tab.navigateTo('/pages/mine/setting/setting')
 	};
-	function handleButtonClick5() {
+
+	// 打卡的函数
+	function clockIn() {
 		$tab.navigateTo('/pages/mine/clockIn/clockIn')
 	};
 </script>
@@ -119,10 +148,7 @@
 		display: flex;
 		flex-direction: column;
 	}
-//样式穿透
-	::v-deep .uni-select__selector-item text,.uni-select__input-text {
-		font-size: larger;
-	}
+
 
 	.user-info {
 		display: flex;
@@ -131,17 +157,24 @@
 		border-bottom: 1rpx solid #ddd;
 	}
 
+
 	.avatar {
-		width: 120rpx;
-		height: 120rpx;
-		margin-right: 20rpx;
+		width: 200rpx;
+		height: 200rpx;
 		border-radius: 50%;
 	}
 
 	.info-detail {
 		flex-grow: 1;
+		font-size: 28rpx;
+	}
+
+	.name {
+		padding: 15rpx 0;
 	}
 
+
+
 	.function-list {
 		margin-bottom: 60rpx;
 	}
@@ -176,5 +209,23 @@
 	.select1 {
 		display: inline-block;
 		width: 50%;
+		margin-top: 10rpx;
+	}
+
+	.headImg {
+		text-align: center;
+	}
+
+	//样式穿透
+	::v-deep .uni-list-cell-left {
+		padding: 0 0;
+	}
+
+	::v-deep .uni-list-cell::after {
+		background-color: white;
+	}
+
+	::v-deep .uni-input {
+		padding: 15rpx 8rpx;
 	}
 </style>

+ 2 - 2
pages/mine/personal_message/personal_message.vue

@@ -54,6 +54,7 @@
 	import {
 		onLoad
 	} from '@dcloudio/uni-app'
+	// 监听页面加载
 	onLoad((options) => {
 		// 获取传入的标题参数
 		const name = options.name;
@@ -67,15 +68,14 @@
 		userInfo.value.name = name
 		}
 	})
+	// 定义个人信息数据
 	const userInfo = ref({
 		name: "张三",
 		department: [{
-				value: 0,
 				departmentName: "研发部",
 				position: '软件开发工程师'
 			},
 			{
-				value: 1,
 				departmentName: "业务部",
 				position: '销售经理'
 			},

+ 48 - 22
pages/mine/setting/pwdEdit/pwdEdit.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<!-- 旧密码输入框 -->
 		<view class="uni-input-wrapper">
 			<input class="uni-input" placeholder="请输入旧密码" :password="showPassword1" 
 			v-model="oldPassword" />
@@ -7,6 +8,7 @@
 				@click="changePassword1">&#xe568;</text>
 		</view>
 		
+		<!-- 新密码输入框 -->
 		<view class="uni-input-wrapper">
 			<input class="uni-input" placeholder="请输入新密码" :password="showPassword2" 
 			v-model="newPassword" />
@@ -14,15 +16,15 @@
 				@click="changePassword2">&#xe568;</text>
 		</view>
 		
+		<!-- 确认新密码输入框 -->
 		<view class="uni-input-wrapper">
 			<input class="uni-input" placeholder="请确认新密码" :password="showPassword3" 
 			v-model="confirmPassword" />
 			<text class="uni-icon" :class="[!showPassword3 ? 'uni-eye-active' : '']"
 				@click="changePassword3">&#xe568;</text>
 		</view>
-		
-
 
+		<!-- 提交按钮 -->
 		<button @click="submit" class="submitBtn">提交</button>
 	</view>
 </template>
@@ -30,37 +32,61 @@
 <script setup>
 	import { ref } from 'vue';
 	
-	const oldPassword = ref('');
-	const newPassword = ref('');
-	const confirmPassword = ref('');
-	const showPassword1 = ref(true);
-	const showPassword2 = ref(true);
-	const showPassword3 = ref(true);
+	const oldPassword = ref(''); // 旧密码
+	const newPassword = ref(''); // 新密码
+	const confirmPassword = ref(''); // 确认新密码
+	const showPassword1 = ref(true); // 旧密码可见性
+	const showPassword2 = ref(true); // 新密码可见性
+	const showPassword3 = ref(true); // 确认密码可见性
 	
+	// 提交逻辑
 	function submit() {
-	  if (newPassword.value !== confirmPassword.value) {
-	    uni.showToast({
-	    	title: '新密码和确认密码不一致',
-	    	icon: 'none'
-	    });
-	    return;
-	  }
-	  
+		// 检查新密码和确认密码是否一致
+		if (newPassword.value !== confirmPassword.value) {
+			uni.showToast({
+				title: '新密码和确认密码不一致',
+				icon: 'none'
+			});
+			return; // 终止提交
+		}
+		
+		// 检查新密码强度
+		if (!validatePassword(newPassword.value)) {
+			uni.showToast({
+				title: '新密码必须包含至少8个字符、一个大写字母、一个小写字母和一个数字',
+				icon: 'none'
+			});
+			return; // 终止提交
+		}
+
+		// 通过校验后,提示提交成功
+		uni.showToast({
+			title: '提交成功',
+			icon: 'none'
+		});
 	}
-	
+
+	// 校验密码强度
+	function validatePassword(password) {
+		// 密码至少有8个字符,包含大写字母、小写字母和数字
+		const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$/;
+		return passwordRegex.test(password);
+	}
+
+	// 切换旧密码可见性
 	function changePassword1() {
-	  showPassword1.value = !showPassword1.value;
+		showPassword1.value = !showPassword1.value;
 	}
 	
-	
+	// 切换新密码可见性
 	function changePassword2() {
-	  showPassword2.value = !showPassword2.value;
+		showPassword2.value = !showPassword2.value;
 	}
 	
+	// 切换确认密码可见性
 	function changePassword3() {
-	  showPassword3.value = !showPassword3.value;
+		showPassword3.value = !showPassword3.value;
 	}
-	
 </script>
 
 <style>

+ 44 - 6
pages/mine/setting/setting.vue

@@ -9,22 +9,23 @@
 			</view>
 			<text>></text>
 		</view>
-		<view class="list-item" @click="">
+		<view class="list-item" @click="checkUpdate">
 			<view>
 				<uni-icons type="refreshempty" size="20"></uni-icons>
 				<text>检查更新</text>
 			</view>
 			<text>></text>
 		</view>
-		<view class="list-item" @click="">
+		<view class="list-item" @click="clearCache">
 			<view>
 				<uni-icons type="trash" size="20"></uni-icons>
 				<text>清理缓存</text>
 			</view>
 			<text>></text>
 		</view>
+		<!-- 退出登录按钮 -->
 		<view class="uni-padding-wrap uni-common-mt">
-			<button type="warn" @click="showModal">退出登录</button>
+			<button type="warn" @click="logOut">退出登录</button>
 		</view>
 
 		
@@ -35,7 +36,8 @@
 
 <script setup>
 	import $tab from "../../../plugins/tab.js"
-	function showModal() {
+	// 退出登录
+	function logOut() {
 		uni.showModal({
 		    title: '系统提示',
 		    content: '确定注销并退出系统吗?',
@@ -48,16 +50,52 @@
 		    }
 		});
 	};
-	
+	// 清理缓存
+	function clearCache() {
+      uni.clearStorageSync();
+      // 提示用户缓存清理成功
+      uni.showToast({
+        title: '缓存清理成功',
+        icon: 'success',
+        duration: 2000
+      });
+    }
+	// 修改密码
 	function pwdEdit(){
 		$tab.navigateTo('/pages/mine/setting/pwdEdit/pwdEdit');
 	};
+	// 检查更新
+	function checkUpdate(){
+		const updateManager = uni.getUpdateManager();
+		updateManager.onCheckForUpdate(function (res) {
+		  // 请求完新版本信息的回调
+		  if(res.hasUpdate){
+			  updateManager.onUpdateReady(function (res) {
+			    uni.showModal({
+			      title: '更新提示',
+			      content: '新版本已经准备好,是否重启应用?',
+			      success(res) {
+			        if (res.confirm) {
+			          // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
+			          updateManager.applyUpdate();
+			        }
+			      }
+			    });
+			  
+			  });
+		  }else{
+			  uni.showToast({
+			    title: '暂无版本更新',
+			    icon: 'none'
+			  });
+		  }
+		});
+	}
 
 	
 </script>
 
 <style lang="scss" scoped>
-	/* 添加必要的样式 */
 	.container {
 		padding: 20px;
 	}

+ 155 - 171
pages/mine/waitWork/waitWork.vue

@@ -1,14 +1,13 @@
 <template>
 	<view class="container">
+		<!-- 待办任务与流程统计 -->
 		<view class="stats-container">
 			<view class="stat-item" @click="goToTodos">
-
-
 				<image :src="waitWorkImg" style="width: 120rpx;height: 120rpx;"></image>
 				<text class="stat-label">
 					待办任务
 					<text class="stat-value">{{ todoCount }}</text>
-					</text>
+				</text>
 			</view>
 			<view class="divider"></view>
 			<view class="stat-item" @click="goToProcesses">
@@ -20,6 +19,8 @@
 				</text>
 			</view>
 		</view>
+
+		<!-- 待办任务列表 -->
 		<view class="tasks-section">
 			<view class="section-header">
 				<text class="section-title">任务列表</text>
@@ -30,11 +31,12 @@
 						<image :src="waitWorkImg" style="width: 30rpx;height: 30rpx;margin-right: 30rpx;"></image>
 						<text class="task-content">{{ todo.content }}</text>
 					</view>
-					
+
 					<text class="task-detail-icon">›</text>
 				</view>
 			</scroll-view>
 		</view>
+		<!-- 流程列表 -->
 		<view class="processes-section">
 			<view class="section-header">
 				<text class="section-title">流程列表</text>
@@ -46,7 +48,6 @@
 						<image :src="processImg" style="width: 30rpx;height: 30rpx;margin-right: 30rpx;"></image>
 						<text class="process-content">{{ process.content }}</text>
 					</view>
-					
 					<text class="process-detail-icon">›</text>
 				</view>
 			</scroll-view>
@@ -55,177 +56,160 @@
 </template>
 
 <script setup>
-	import {
-		ref,
-		computed,
-		reactive,
-	} from 'vue';
+import {
+	ref,
+	computed,
+	reactive,
+} from 'vue';
 
 import waitWorkImg from "/static/images/mine/waitWork2.png";
 import processImg from "/static/images/mine/process.png";
-
-	const todos = reactive([{
-			id: 1,
-			content: '完成报告1',
-			detail: '完成11月5日的今日报告'
-		},
-		{
-			id: 2,
-			content: '参加会议2',
-			detail: '参加11月5日下午5点的会议'
-		},
-		{
-			id: 3,
-			content: '回复邮件3',
-			detail: '详细描述...'
-		},
-		{
-			id: 4,
-			content: '完成报告4',
-			detail: '详细描述...'
-		},
-		{
-			id: 5,
-			content: '参加会议5',
-			detail: '详细描述...'
-		},
-		{
-			id: 6,
-			content: '回复邮件6',
-			detail: '详细描述...'
-		},
-	]);
-
-	const processes = ref([{
-			id: 1,
-			content: '审批流程',
-			detail: '来自张三的请假申请'
-		},
-		{
-			id: 2,
-			content: '财务流程',
-			detail: '详细描述...'
-		},
-	]);
-
-	const todoCount = computed(() => todos.length);
-	const processCount = computed(() => processes.value.length);
-
-	function goToTodos() {
-		// 跳转到待办任务列表页面
-	}
-
-	function goToProcesses() {
-		// 跳转到流程列表页面
-	}
-
-	function showTaskDetail(todo) {
-		// 显示待办任务详情
-		uni.showModal({
-			title: '任务详情',
-			content: todo.detail,
-			cancelText:'完成',
-			success: function (res) {
-					if (res.confirm) {
-						console.log('用户点击确定');
-					} else if (res.cancel) {
-						console.log('用户点击完成',todo);
-						// 找到要移除的对象的索引
-						let index = todos.findIndex(item => item.id === todo.id);
-						// 如果找到了,使用splice移除它
-						if (index > -1) {
-						  todos.splice(index, 1);
-						}
-						
-					}
+import $tabs from "../../../plugins/tab.js"
+// 定义待办任务数据
+const todos = reactive([{
+	id: 1,
+	content: '完成报告1',
+	detail: '完成11月5日的今日报告'
+},
+{
+	id: 2,
+	content: '参加会议2',
+	detail: '参加11月5日下午5点的会议'
+},
+]);
+// 定义流程数据
+const processes = reactive([{
+	id: 1,
+	content: '审批流程',
+	detail: '来自张三的请假申请'
+},
+{
+	id: 2,
+	content: '财务流程',
+	detail: '来自张三的报销申请'
+},
+]);
+// 计算待办任务数量
+const todoCount = computed(() => todos.length);
+// 计算流程数量
+const processCount = computed(() => processes.length);
+
+// 显示待办任务详情
+function showTaskDetail(todo) {
+	uni.showModal({
+		title: '任务详情',
+		content: todo.detail,
+		cancelText: '完成',
+		success: function (res) {
+			if (res.confirm) {
+				console.log('用户点击确定');
+			} else if (res.cancel) {
+				console.log('用户点击完成', todo);
+				// 找到要移除的对象的索引
+				let index = todos.findIndex(item => item.id === todo.id);
+				// 如果找到了,使用splice移除它
+				if (index > -1) {
+					todos.splice(index, 1);
 				}
-			
-		});
-	}
-
-	function showProcessDetail(process) {
-		// 显示流程详情
-		uni.showModal({
-			title: '流程详情',
-			content: process.detail,
-			showCancel: false
-		});
-	}
+
+			}
+		}
+
+	});
+}
+// 显示流程详情
+function showProcessDetail(process) {
+	uni.showModal({
+		title: '流程详情',
+		content: process.detail,
+		showCancel: false
+	});
+}
+
+function goToTodos() {
+	// 跳转到待办任务列表详情页面
+	$tabs.switchTab('/pages/work/index');
+}
+
+function goToProcesses() {
+	// 跳转到流程列表详情页面
+	$tabs.switchTab('/pages/process/index');
+}
 </script>
 
 <style scoped>
-	.container {
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		background-color: #f5f5f5;
-		height: 100%;
-	}
-
-
-	.stats-container {
-		display: flex;
-		justify-content: space-around;
-		width: 100%;
-		margin-top: 20px;
-		background-color: white;
-		border-radius: 10px;
-		padding: 10px 0;
-	}
-
-	.stat-item {
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		width: 50%;
-	}
-
-	.stat-value {
-		font-size: 24px;
-		font-weight: bold;
-		color: #333;
-	}
-
-	.stat-label {
-		font-size: 16px;
-		color: #666;
-	}
-
-	.divider {
-		width: 1px;
-		height: 40px;
-		background-color: #e5e5e5;
-	}
-
-	.tasks-section,
-	.processes-section {
-		width: 100%;
-		margin-top: 20px;
-	}
-
-	.section-header {
-		padding: 10px;
-		background-color: #f8f8f8;
-		border-bottom: 1px solid #e5e5e5;
-	}
-
-	.section-title {
-		font-size: 20px;
-		font-weight: bold;
-	}
-
-	.task-list,
-	.process-list {
-		height: 200px;
-		background-color: white;
-	}
-
-	.task-item,
-	.process-item {
-		display: flex;
-		justify-content: space-between;
-		align-items: center;
-		padding: 15px;
-
-	}
+.container {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	background-color: #f5f5f5;
+	height: 100%;
+}
+
+
+.stats-container {
+	display: flex;
+	justify-content: space-around;
+	width: 100%;
+	margin-top: 20px;
+	background-color: white;
+	border-radius: 10px;
+	padding: 10px 0;
+}
+
+.stat-item {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	width: 50%;
+}
+
+.stat-value {
+	font-size: 24px;
+	font-weight: bold;
+	color: #333;
+}
+
+.stat-label {
+	font-size: 16px;
+	color: #666;
+}
+
+.divider {
+	width: 1px;
+	height: 40px;
+	background-color: #e5e5e5;
+}
+
+.tasks-section,
+.processes-section {
+	width: 100%;
+	margin-top: 20px;
+}
+
+.section-header {
+	padding: 10px;
+	background-color: #f8f8f8;
+	border-bottom: 1px solid #e5e5e5;
+}
+
+.section-title {
+	font-size: 20px;
+	font-weight: bold;
+}
+
+.task-list,
+.process-list {
+	height: 200px;
+	background-color: white;
+}
+
+.task-item,
+.process-item {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 15px;
+
+}
 </style>

二进制
static/images/mine/clockIn.png


二进制
static/images/mine/process.png