|
|
@@ -20,13 +20,34 @@ interface ClockInData {
|
|
|
status: '已打卡' | '未打卡'
|
|
|
clockInTime?: string
|
|
|
clockOutTime?: string
|
|
|
+ displayTime?: string
|
|
|
+ date?: string
|
|
|
+}
|
|
|
+
|
|
|
+// 格式化当前时间
|
|
|
+const formatCurrentTime = (): string => {
|
|
|
+ const now = new Date()
|
|
|
+ return `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`
|
|
|
+}
|
|
|
+
|
|
|
+// 格式化当前日期
|
|
|
+const formatCurrentDate = (): string => {
|
|
|
+ const now = new Date()
|
|
|
+ const weekdays = ['日', '一', '二', '三', '四', '五', '六']
|
|
|
+ const year = now.getFullYear()
|
|
|
+ const month = now.getMonth() + 1
|
|
|
+ const date = now.getDate()
|
|
|
+ const weekday = weekdays[now.getDay()]
|
|
|
+ return `${year}年${month}月${date}日 星期${weekday}`
|
|
|
}
|
|
|
|
|
|
// 模拟通知数据
|
|
|
interface Notification {
|
|
|
id: number
|
|
|
+ iconClass: string
|
|
|
+ iconColor: 'blue' | 'green' | 'yellow' | 'red'
|
|
|
title: string
|
|
|
- time: string
|
|
|
+ subtitle: string
|
|
|
}
|
|
|
|
|
|
const Dashboard: React.FC = () => {
|
|
|
@@ -38,16 +59,18 @@ const Dashboard: React.FC = () => {
|
|
|
const clockInData: ClockInData = {
|
|
|
status: '已打卡',
|
|
|
clockInTime: '08:30',
|
|
|
- clockOutTime: '18:00'
|
|
|
+ clockOutTime: '--:--',
|
|
|
+ displayTime: formatCurrentTime(),
|
|
|
+ date: formatCurrentDate()
|
|
|
}
|
|
|
|
|
|
// 模拟通知数据
|
|
|
const notifications: Notification[] = [
|
|
|
- { id: 1, title: '本月工资已发放', time: '2025-12-20' },
|
|
|
- { id: 2, title: '考勤异常提醒', time: '2025-12-18' },
|
|
|
- { id: 3, title: '企业通知:下周培训安排', time: '2025-12-15' },
|
|
|
- { id: 4, title: '系统维护通知', time: '2025-12-10' },
|
|
|
- { id: 5, title: '福利政策更新', time: '2025-12-05' }
|
|
|
+ { id: 1, iconClass: 'i-heroicons-banknote-20-solid', iconColor: 'green', title: '薪资发放通知', subtitle: '11月薪资已发放,请查收' },
|
|
|
+ { id: 2, iconClass: 'i-heroicons-exclamation-circle-20-solid', iconColor: 'blue', title: '考勤异常提醒', subtitle: '11月20日考勤异常,请及时处理' },
|
|
|
+ { id: 3, iconClass: 'i-heroicons-building-office-2-20-solid', iconColor: 'yellow', title: '企业通知', subtitle: '下周培训安排已更新' },
|
|
|
+ { id: 4, iconClass: 'i-heroicons-wrench-screwdriver-20-solid', iconColor: 'red', title: '系统维护通知', subtitle: '系统将于12月1日维护' },
|
|
|
+ { id: 5, iconClass: 'i-heroicons-document-text-20-solid', iconColor: 'blue', title: '福利政策更新', subtitle: '最新福利政策已发布' }
|
|
|
]
|
|
|
|
|
|
// 加载个人信息
|
|
|
@@ -154,6 +177,12 @@ const Dashboard: React.FC = () => {
|
|
|
}}
|
|
|
>
|
|
|
<View className="flex items-center mb-4">
|
|
|
+ {/* 圆形头像显示(用户姓名首字) */}
|
|
|
+ <View className="w-15 h-15 rounded-full bg-white/20 border-2 border-white flex items-center justify-center mr-3">
|
|
|
+ <Text className="text-white text-xl font-semibold">
|
|
|
+ {(user?.personInfo?.name || user?.name || '人才用户').charAt(0)}
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
<View className="flex-1">
|
|
|
<Text className="text-white text-xl font-semibold block mb-1">
|
|
|
{user?.personInfo?.name || user?.name || '人才用户'}
|
|
|
@@ -162,51 +191,81 @@ const Dashboard: React.FC = () => {
|
|
|
{user?.personInfo?.disabilityType || '残疾类型未填写'}
|
|
|
</Text>
|
|
|
</View>
|
|
|
+ {/* 右侧二维码按钮图标 */}
|
|
|
+ <View
|
|
|
+ className="w-10 h-10 rounded-full bg-white/20 flex items-center justify-center"
|
|
|
+ onClick={() => Taro.showToast({ title: '二维码功能开发中', icon: 'none' })}
|
|
|
+ >
|
|
|
+ <View className="i-heroicons-qr-code-20-solid text-white text-lg" />
|
|
|
+ </View>
|
|
|
</View>
|
|
|
|
|
|
- <View className="grid grid-cols-2 gap-4 mt-4">
|
|
|
- <View className="bg-white/20 rounded-lg p-3 backdrop-blur-sm">
|
|
|
+ {/* 3列统计数据 */}
|
|
|
+ <View className="grid grid-cols-3 gap-3 mt-4">
|
|
|
+ <View className="bg-white/20 rounded-lg p-3 backdrop-blur-sm text-center">
|
|
|
<Text className="text-white/80 text-xs block mb-1">本月出勤</Text>
|
|
|
- <Text className="text-white text-2xl font-bold">20<Text className="text-sm ml-1">天</Text></Text>
|
|
|
+ <Text className="text-white text-xl font-bold">28</Text>
|
|
|
</View>
|
|
|
- <View className="bg-white/20 rounded-lg p-3 backdrop-blur-sm">
|
|
|
+ <View className="bg-white/20 rounded-lg p-3 backdrop-blur-sm text-center">
|
|
|
+ <Text className="text-white/80 text-xs block mb-1">异常记录</Text>
|
|
|
+ <Text className="text-white text-xl font-bold">0</Text>
|
|
|
+ </View>
|
|
|
+ <View className="bg-white/20 rounded-lg p-3 backdrop-blur-sm text-center">
|
|
|
<Text className="text-white/80 text-xs block mb-1">本月薪资</Text>
|
|
|
- <Text className="text-white text-2xl font-bold">3,000<Text className="text-sm ml-1">元</Text></Text>
|
|
|
+ <Text className="text-white text-xl font-bold">4,800</Text>
|
|
|
</View>
|
|
|
</View>
|
|
|
</View>
|
|
|
|
|
|
{/* 打卡状态模块 */}
|
|
|
<View className="bg-white rounded-2xl p-5 mb-4 shadow-sm">
|
|
|
- <View className="flex items-center justify-between mb-4">
|
|
|
- <Text className="text-lg font-semibold text-gray-800">今日打卡</Text>
|
|
|
- <View
|
|
|
- className={`px-3 py-1 rounded-full text-sm ${
|
|
|
- clockInData.status === '已打卡' ? 'bg-green-100 text-green-600' : 'bg-gray-100 text-gray-600'
|
|
|
- }`}
|
|
|
- >
|
|
|
- {clockInData.status}
|
|
|
- </View>
|
|
|
+ {/* 模块标题 */}
|
|
|
+ <Text className="text-lg font-semibold text-gray-800 block mb-4">今日打卡</Text>
|
|
|
+
|
|
|
+ {/* 打卡状态指示器 */}
|
|
|
+ <View className="flex items-center justify-center mb-4">
|
|
|
+ <View className="w-3 h-3 rounded-full bg-green-500 mr-2 animate-pulse" />
|
|
|
+ <Text className="text-green-500 font-medium">已打卡</Text>
|
|
|
</View>
|
|
|
|
|
|
- {clockInData.status === '已打卡' && (
|
|
|
- <View className="grid grid-cols-2 gap-4 mb-4">
|
|
|
- <View className="bg-blue-50 rounded-lg p-3">
|
|
|
- <Text className="text-gray-600 text-xs block mb-1">上班打卡</Text>
|
|
|
- <Text className="text-blue-600 text-xl font-semibold">{clockInData.clockInTime}</Text>
|
|
|
+ {/* 大号时间显示 */}
|
|
|
+ <Text className="text-2xl font-bold text-center text-gray-800 mb-1">
|
|
|
+ {clockInData.displayTime || '09:27'}
|
|
|
+ </Text>
|
|
|
+
|
|
|
+ {/* 当前日期显示 */}
|
|
|
+ <Text className="text-sm text-center text-gray-500 mb-4">
|
|
|
+ {clockInData.date || '2023年11月25日 星期六'}
|
|
|
+ </Text>
|
|
|
+
|
|
|
+ {/* 上班/下班卡片 */}
|
|
|
+ <View className="grid grid-cols-2 gap-4 mb-4">
|
|
|
+ {/* 上班打卡 */}
|
|
|
+ <View className="flex flex-col items-center">
|
|
|
+ <View className="w-12 h-12 rounded-full bg-blue-100 flex items-center justify-center mb-2">
|
|
|
+ <Text className="text-xl">→</Text>
|
|
|
</View>
|
|
|
- <View className="bg-blue-50 rounded-lg p-3">
|
|
|
- <Text className="text-gray-600 text-xs block mb-1">下班打卡</Text>
|
|
|
- <Text className="text-blue-600 text-xl font-semibold">{clockInData.clockOutTime}</Text>
|
|
|
+ <Text className="text-xs text-gray-600">上班打卡</Text>
|
|
|
+ <Text className="text-sm font-semibold text-gray-800">{clockInData.clockInTime}</Text>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 下班打卡 */}
|
|
|
+ <View className="flex flex-col items-center">
|
|
|
+ <View className="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mb-2">
|
|
|
+ <Text className="text-xl">←</Text>
|
|
|
</View>
|
|
|
+ <Text className="text-xs text-gray-600">下班打卡</Text>
|
|
|
+ <Text className="text-sm font-semibold text-gray-800">{clockInData.clockOutTime}</Text>
|
|
|
</View>
|
|
|
- )}
|
|
|
+ </View>
|
|
|
|
|
|
+ {/* 远程打卡按钮 */}
|
|
|
<View
|
|
|
- className="bg-blue-500 text-white text-center py-3 rounded-lg font-medium"
|
|
|
+ className="bg-blue-500 text-white text-center py-3 rounded-lg font-medium flex items-center justify-center"
|
|
|
onClick={handleClockIn}
|
|
|
>
|
|
|
- 远程打卡
|
|
|
+ <View className="i-heroicons-device-phone-mobile-20-solid text-lg mr-1" />
|
|
|
+ <Text>小程序远程打卡</Text>
|
|
|
</View>
|
|
|
</View>
|
|
|
|
|
|
@@ -215,42 +274,34 @@ const Dashboard: React.FC = () => {
|
|
|
<Text className="text-lg font-semibold text-gray-800 block mb-4">快捷功能</Text>
|
|
|
<View className="grid grid-cols-2 gap-4">
|
|
|
<View
|
|
|
- className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl"
|
|
|
+ className="flex flex-col items-center justify-center p-4 bg-blue-50 rounded-xl"
|
|
|
onClick={() => handleQuickAction('personal-info')}
|
|
|
>
|
|
|
- <View className="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mb-2">
|
|
|
- <Text className="text-2xl">👤</Text>
|
|
|
- </View>
|
|
|
+ <View className="i-heroicons-user-20-solid text-blue-500 text-2xl mb-2" />
|
|
|
<Text className="text-gray-700 text-sm">个人信息</Text>
|
|
|
</View>
|
|
|
|
|
|
<View
|
|
|
- className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl"
|
|
|
+ className="flex flex-col items-center justify-center p-4 bg-green-50 rounded-xl"
|
|
|
onClick={() => handleQuickAction('attendance')}
|
|
|
>
|
|
|
- <View className="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center mb-2">
|
|
|
- <Text className="text-2xl">📅</Text>
|
|
|
- </View>
|
|
|
+ <View className="i-heroicons-calendar-days-20-solid text-green-500 text-2xl mb-2" />
|
|
|
<Text className="text-gray-700 text-sm">考勤记录</Text>
|
|
|
</View>
|
|
|
|
|
|
<View
|
|
|
- className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl"
|
|
|
+ className="flex flex-col items-center justify-center p-4 bg-purple-50 rounded-xl"
|
|
|
onClick={() => handleQuickAction('employment')}
|
|
|
>
|
|
|
- <View className="w-12 h-12 bg-purple-100 rounded-full flex items-center justify-center mb-2">
|
|
|
- <Text className="text-2xl">💰</Text>
|
|
|
- </View>
|
|
|
+ <View className="i-heroicons-banknote-20-solid text-purple-500 text-2xl mb-2" />
|
|
|
<Text className="text-gray-700 text-sm">薪资查询</Text>
|
|
|
</View>
|
|
|
|
|
|
<View
|
|
|
- className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl"
|
|
|
+ className="flex flex-col items-center justify-center p-4 bg-yellow-50 rounded-xl"
|
|
|
onClick={() => handleQuickAction('company')}
|
|
|
>
|
|
|
- <View className="w-12 h-12 bg-orange-100 rounded-full flex items-center justify-center mb-2">
|
|
|
- <Text className="text-2xl">🏢</Text>
|
|
|
- </View>
|
|
|
+ <View className="i-heroicons-building-office-2-20-solid text-yellow-600 text-2xl mb-2" />
|
|
|
<Text className="text-gray-700 text-sm">企业信息</Text>
|
|
|
</View>
|
|
|
</View>
|
|
|
@@ -269,18 +320,36 @@ const Dashboard: React.FC = () => {
|
|
|
</View>
|
|
|
|
|
|
<View className="space-y-3">
|
|
|
- {notifications.map((notification) => (
|
|
|
- <View
|
|
|
- key={notification.id}
|
|
|
- className="flex items-start justify-between py-3 border-b border-gray-100 last:border-0"
|
|
|
- >
|
|
|
- <View className="flex-1">
|
|
|
- <Text className="text-gray-800 text-sm block mb-1">{notification.title}</Text>
|
|
|
- <Text className="text-gray-400 text-xs">{notification.time}</Text>
|
|
|
+ {notifications.map((notification) => {
|
|
|
+ const iconBgClass = {
|
|
|
+ blue: 'bg-blue-100',
|
|
|
+ green: 'bg-green-100',
|
|
|
+ yellow: 'bg-yellow-100',
|
|
|
+ red: 'bg-red-100'
|
|
|
+ }[notification.iconColor] || 'bg-gray-100'
|
|
|
+
|
|
|
+ const iconColorClass = {
|
|
|
+ blue: 'text-blue-500',
|
|
|
+ green: 'text-green-500',
|
|
|
+ yellow: 'text-yellow-600',
|
|
|
+ red: 'text-red-500'
|
|
|
+ }[notification.iconColor] || 'text-gray-500'
|
|
|
+
|
|
|
+ return (
|
|
|
+ <View
|
|
|
+ key={notification.id}
|
|
|
+ className="flex items-start py-3 border-b border-gray-100 last:border-0"
|
|
|
+ >
|
|
|
+ <View className={`w-10 h-10 rounded-full ${iconBgClass} flex items-center justify-center mr-3 mt-1 flex-shrink-0`}>
|
|
|
+ <View className={`${notification.iconClass} ${iconColorClass} text-lg`} />
|
|
|
+ </View>
|
|
|
+ <View className="flex-1">
|
|
|
+ <Text className="text-gray-800 text-sm font-medium block mb-1">{notification.title}</Text>
|
|
|
+ <Text className="text-gray-500 text-xs">{notification.subtitle}</Text>
|
|
|
+ </View>
|
|
|
</View>
|
|
|
- <View className="w-2 h-2 bg-red-500 rounded-full mt-1" />
|
|
|
- </View>
|
|
|
- ))}
|
|
|
+ )
|
|
|
+ })}
|
|
|
</View>
|
|
|
</View>
|
|
|
</View>
|