first commit
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,880 @@
|
||||
<template>
|
||||
<view class="statistics-container">
|
||||
<!-- 使用子头部组件 -->
|
||||
<sub-header
|
||||
title="考勤统计"
|
||||
@goBack="goBack"
|
||||
@showMoreOptions="showMoreOptions"
|
||||
/>
|
||||
|
||||
<!-- 页面内容 -->
|
||||
<scroll-view scroll-y class="statistics-content">
|
||||
|
||||
<!-- 导出报表 -->
|
||||
<view class="export-card card">
|
||||
<view class="export-title">导出报表</view>
|
||||
<view class="exports">
|
||||
<view class="btn-export" @click="exportReport"> 导出 </view>
|
||||
<i class="fas fa-angle-right" style="font-size: 20rpx; color: var(--tab-inactive);position: relative;top: 4rpx;"></i>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 统计数据 -->
|
||||
<view class="stats-card card">
|
||||
<!-- Tabbar -->
|
||||
<view class="stat-tabs">
|
||||
<view
|
||||
v-for="t in tabs"
|
||||
:key="t.value"
|
||||
class="stat-tab"
|
||||
:class="{ active: statTab === t.value }"
|
||||
@click="statTab = t.value"
|
||||
>{{ t.label }}</view
|
||||
>
|
||||
</view>
|
||||
|
||||
<!-- 日统计(显示日历) -->
|
||||
<view v-if="statTab === 'day'" class="tab-content">
|
||||
<view class="calendar">
|
||||
<view class="cal-title">
|
||||
{{ today.getFullYear() }}年{{ today.getMonth() + 1 }}月
|
||||
</view>
|
||||
<view class="cal-week-head">
|
||||
<text
|
||||
v-for="w in ['日', '一', '二', '三', '四', '五', '六']"
|
||||
:key="w"
|
||||
>{{ w }}</text
|
||||
>
|
||||
</view>
|
||||
<view class="cal-body">
|
||||
<view
|
||||
v-for="(week, weekIndex) in calendarWeeks"
|
||||
:key="weekIndex"
|
||||
class="cal-row"
|
||||
>
|
||||
<view
|
||||
v-for="day in week"
|
||||
:key="day.key"
|
||||
class="cal-cell"
|
||||
:class="{
|
||||
empty: day.empty,
|
||||
selected:
|
||||
!day.empty && calendarSelected.includes(day.fullDate),
|
||||
}"
|
||||
@click="
|
||||
!day.empty &&
|
||||
selectDay({
|
||||
fullDate: day.fullDate,
|
||||
day: day.day,
|
||||
month: day.month,
|
||||
year: day.year,
|
||||
})
|
||||
"
|
||||
>{{ day.empty ? "" : day.day }}</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 选中日期的数据显示卡片 -->
|
||||
<view v-if="selectedDayInfo" class="day-data-card">
|
||||
<view class="day-data-header">
|
||||
<view class="day-data-title">
|
||||
<i class="fas fa-calendar-day"></i>
|
||||
<text>{{ selectedDayInfo.year }}年{{ selectedDayInfo.month }}月{{ selectedDayInfo.day }}日</text>
|
||||
</view>
|
||||
<view class="day-data-subtitle">考勤详情</view>
|
||||
</view>
|
||||
|
||||
<view class="day-data-content">
|
||||
<view
|
||||
class="day-data-item"
|
||||
v-for="(item, index) in dailyStats"
|
||||
:key="index"
|
||||
>
|
||||
<view class="day-data-icon" :class="item.status || 'default'">
|
||||
<i :class="item.icon"></i>
|
||||
</view>
|
||||
<view class="day-data-info">
|
||||
<view class="day-data-label">{{ item.title }}</view>
|
||||
<view class="day-data-value" :class="item.status || 'default'">
|
||||
{{ item.value }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 周统计 -->
|
||||
<view v-if="statTab === 'week'" class="tab-content">
|
||||
<view class="bar-tabs">
|
||||
<view
|
||||
class="bar-tab"
|
||||
v-for="(item, index) in weekTabs"
|
||||
:key="item.value"
|
||||
:class="{ active: weekTab === item.value }"
|
||||
@click="weekTab = item.value"
|
||||
>{{ item.label }}</view
|
||||
>
|
||||
</view>
|
||||
<view class="count-list">
|
||||
<view
|
||||
class="count-item"
|
||||
v-for="(item, idx) in (weekStats[weekTab] || [])"
|
||||
:key="idx"
|
||||
>
|
||||
<view class="c-value">{{ item.value }}</view>
|
||||
<view class="c-title">{{ item.title }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 月统计 -->
|
||||
<view v-if="statTab === 'month'" class="tab-content">
|
||||
<view class="month-grid">
|
||||
<view
|
||||
class="month-item"
|
||||
v-for="(item, index) in monthTabs"
|
||||
:key="item.value"
|
||||
:class="{ active: monthTab === item.value }"
|
||||
@click="monthTab = item.value"
|
||||
>
|
||||
<view class="month-label">{{ item.label }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="count-list">
|
||||
<view
|
||||
class="count-item"
|
||||
v-for="(item, idx) in (monthStats[monthTab] || [])"
|
||||
:key="idx"
|
||||
>
|
||||
<view class="c-value">{{ item.value }}</view>
|
||||
<view class="c-title">{{ item.title }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SubHeader from '../../components/subHeader.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SubHeader
|
||||
},
|
||||
data() {
|
||||
const today = new Date();
|
||||
return {
|
||||
today: today,
|
||||
tabs: [
|
||||
{ label: "日统计", value: "day" },
|
||||
{ label: "周统计", value: "week" },
|
||||
{ label: "月统计", value: "month" },
|
||||
],
|
||||
statTab: "day",
|
||||
calendarSelected: [
|
||||
`${today.getFullYear()}-${String(today.getMonth() + 1).padStart(
|
||||
2,
|
||||
"0"
|
||||
)}-${String(today.getDate()).padStart(2, "0")}`,
|
||||
],
|
||||
weekTabs: [
|
||||
{ label: "第1周", value: "1" },
|
||||
{ label: "第2周", value: "2" },
|
||||
{ label: "第3周", value: "3" },
|
||||
{ label: "第4周", value: "4" },
|
||||
],
|
||||
weekTab: "1",
|
||||
monthTabs: Array.from({ length: 12 }, (_, i) => ({
|
||||
label: `${i + 1}月`,
|
||||
value: String(i + 1),
|
||||
})),
|
||||
monthTab: String(today.getMonth() + 1),
|
||||
baseStat: [
|
||||
{ title: "平均工时", value: "7.8h" },
|
||||
{ title: "迟到次数", value: "1" },
|
||||
{ title: "早退次数", value: "0" },
|
||||
{ title: "缺卡次数", value: "0" },
|
||||
{ title: "旷工次数", value: "0" },
|
||||
{ title: "外勤次数", value: "2" },
|
||||
{ title: "加班时长", value: "4h" },
|
||||
{ title: "调休时长", value: "2h" },
|
||||
],
|
||||
selectedDayData: null, // 选中日期的数据
|
||||
selectedDayInfo: null, // 选中日期的基本信息
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
weekStats() {
|
||||
try {
|
||||
return {
|
||||
"1": this.baseStat || [],
|
||||
"2": (this.baseStat || []).map((item, i) =>
|
||||
i === 1 ? { ...item, value: "0" } : item
|
||||
),
|
||||
"3": (this.baseStat || []).map((item, i) =>
|
||||
i === 3 ? { ...item, value: "1" } : item
|
||||
),
|
||||
"4": (this.baseStat || []).map((item, i) =>
|
||||
i === 5 ? { ...item, value: "3" } : item
|
||||
),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('周统计数据生成错误:', error);
|
||||
return {};
|
||||
}
|
||||
},
|
||||
monthStats() {
|
||||
try {
|
||||
const stats = {};
|
||||
(this.monthTabs || []).forEach((_, i) => {
|
||||
stats[String(i + 1)] = (this.baseStat || []).map((item) => ({
|
||||
...item,
|
||||
value: String(
|
||||
Math.floor(Math.random() * 3) +
|
||||
(item.value.includes("h") ? "h" : "")
|
||||
),
|
||||
}));
|
||||
});
|
||||
return stats;
|
||||
} catch (error) {
|
||||
console.error('月统计数据生成错误:', error);
|
||||
return {};
|
||||
}
|
||||
},
|
||||
// 日历相关计算属性
|
||||
days() {
|
||||
const d = new Date(
|
||||
this.today.getFullYear(),
|
||||
this.today.getMonth() + 1,
|
||||
0
|
||||
).getDate();
|
||||
return Array.from({ length: d }, (_, i) => i + 1);
|
||||
},
|
||||
firstDay() {
|
||||
return new Date(
|
||||
this.today.getFullYear(),
|
||||
this.today.getMonth(),
|
||||
1
|
||||
).getDay();
|
||||
},
|
||||
calendarWeeks() {
|
||||
try {
|
||||
const year = this.today.getFullYear();
|
||||
const month = this.today.getMonth();
|
||||
const firstDay = new Date(year, month, 1).getDay();
|
||||
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
||||
|
||||
const weeks = [];
|
||||
let currentWeek = [];
|
||||
|
||||
// 添加空白日期(上个月的末尾几天)
|
||||
for (let i = 0; i < firstDay; i++) {
|
||||
currentWeek.push({
|
||||
key: `empty-${i}`,
|
||||
empty: true,
|
||||
day: "",
|
||||
fullDate: "",
|
||||
month: month,
|
||||
year: year,
|
||||
});
|
||||
}
|
||||
|
||||
// 添加当前月的日期
|
||||
for (let day = 1; day <= daysInMonth; day++) {
|
||||
const fullDate = `${year}-${String(month + 1).padStart(
|
||||
2,
|
||||
"0"
|
||||
)}-${String(day).padStart(2, "0")}`;
|
||||
currentWeek.push({
|
||||
key: `day-${day}`,
|
||||
empty: false,
|
||||
day: day,
|
||||
fullDate: fullDate,
|
||||
month: month + 1,
|
||||
year: year,
|
||||
});
|
||||
|
||||
// 如果一周满了(7天),开始新的一周
|
||||
if (currentWeek.length === 7) {
|
||||
weeks.push([...currentWeek]);
|
||||
currentWeek = [];
|
||||
}
|
||||
}
|
||||
|
||||
// 如果最后一周不满7天,用空白日期填充
|
||||
while (currentWeek.length > 0 && currentWeek.length < 7) {
|
||||
currentWeek.push({
|
||||
key: `empty-end-${currentWeek.length}`,
|
||||
empty: true,
|
||||
day: "",
|
||||
fullDate: "",
|
||||
month: month,
|
||||
year: year,
|
||||
});
|
||||
}
|
||||
|
||||
// 如果还有未完成的周,添加到结果中
|
||||
if (currentWeek.length > 0) {
|
||||
weeks.push(currentWeek);
|
||||
}
|
||||
|
||||
return weeks;
|
||||
} catch (error) {
|
||||
console.error('日历生成错误:', error);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
isMobile() {
|
||||
return getApp().globalData.isMobile;
|
||||
},
|
||||
// 生成每日数据
|
||||
dailyStats() {
|
||||
if (!this.selectedDayInfo) return [];
|
||||
|
||||
const { year, month, day } = this.selectedDayInfo;
|
||||
const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
||||
|
||||
// 模拟不同日期的不同数据
|
||||
const randomSeed = year * 10000 + month * 100 + day;
|
||||
const random = (seed) => {
|
||||
const x = Math.sin(seed) * 10000;
|
||||
return x - Math.floor(x);
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
title: "上班时间",
|
||||
value: `${String(Math.floor(random(randomSeed) * 2) + 8).padStart(2, '0')}:${String(Math.floor(random(randomSeed + 1) * 60)).padStart(2, '0')}`,
|
||||
icon: "fas fa-clock"
|
||||
},
|
||||
{
|
||||
title: "下班时间",
|
||||
value: `${String(Math.floor(random(randomSeed + 2) * 2) + 17).padStart(2, '0')}:${String(Math.floor(random(randomSeed + 3) * 60)).padStart(2, '0')}`,
|
||||
icon: "fas fa-clock"
|
||||
},
|
||||
{
|
||||
title: "迟到状态",
|
||||
value: random(randomSeed + 5) > 0.8 ? "迟到" : "正常",
|
||||
icon: random(randomSeed + 5) > 0.8 ? "fas fa-exclamation-triangle" : "fas fa-check-circle",
|
||||
status: random(randomSeed + 5) > 0.8 ? "warning" : "success"
|
||||
},
|
||||
{
|
||||
title: "早退状态",
|
||||
value: random(randomSeed + 6) > 0.9 ? "早退" : "正常",
|
||||
icon: random(randomSeed + 6) > 0.9 ? "fas fa-exclamation-triangle" : "fas fa-check-circle",
|
||||
status: random(randomSeed + 6) > 0.9 ? "warning" : "success"
|
||||
},
|
||||
{
|
||||
title: "工作时长",
|
||||
value: `${(random(randomSeed + 4) * 4 + 6).toFixed(1)}h`,
|
||||
icon: "fas fa-hourglass-half"
|
||||
},
|
||||
{
|
||||
title: "外勤次数",
|
||||
value: Math.floor(random(randomSeed + 7) * 3).toString(),
|
||||
icon: "fas fa-map-marker-alt"
|
||||
},
|
||||
{
|
||||
title: "加班时长",
|
||||
value: random(randomSeed + 8) > 0.6 ? `${(random(randomSeed + 8) * 3).toFixed(1)}h` : "0h",
|
||||
icon: "fas fa-moon"
|
||||
},
|
||||
{
|
||||
title: "调休时长",
|
||||
value: random(randomSeed + 9) > 0.7 ? `${(random(randomSeed + 9) * 2).toFixed(1)}h` : "0h",
|
||||
icon: "fas fa-calendar-alt"
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
console.log('统计页面初始化');
|
||||
console.log('当前月份:', this.today.getMonth() + 1);
|
||||
console.log('基础数据:', this.baseStat);
|
||||
console.log('周标签:', this.weekTabs);
|
||||
console.log('月标签:', this.monthTabs);
|
||||
console.log('当前周标签值:', this.weekTab, typeof this.weekTab);
|
||||
console.log('当前月标签值:', this.monthTab, typeof this.monthTab);
|
||||
console.log('周统计数据:', this.weekStats);
|
||||
console.log('月统计数据:', this.monthStats);
|
||||
console.log('周统计键:', Object.keys(this.weekStats));
|
||||
console.log('月统计键:', Object.keys(this.monthStats));
|
||||
console.log('周统计访问测试:', this.weekStats[this.weekTab]);
|
||||
console.log('月统计访问测试:', this.monthStats[this.monthTab]);
|
||||
|
||||
// 初始化默认选中今天
|
||||
this.selectedDayInfo = {
|
||||
year: this.today.getFullYear(),
|
||||
month: this.today.getMonth() + 1,
|
||||
day: this.today.getDate(),
|
||||
fullDate: `${this.today.getFullYear()}-${String(this.today.getMonth() + 1).padStart(2, '0')}-${String(this.today.getDate()).padStart(2, '0')}`
|
||||
};
|
||||
console.log('默认选中今天:', this.selectedDayInfo);
|
||||
},
|
||||
methods: {
|
||||
selectDay(day) {
|
||||
this.calendarSelected = [day.fullDate];
|
||||
this.selectedDayInfo = {
|
||||
year: day.year,
|
||||
month: day.month,
|
||||
day: day.day,
|
||||
fullDate: day.fullDate
|
||||
};
|
||||
console.log('选择日期:', day);
|
||||
console.log('选中日期信息:', this.selectedDayInfo);
|
||||
},
|
||||
exportReport() {
|
||||
uni.showToast({ title: "导出功能暂未开放" });
|
||||
},
|
||||
goBack() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
showMoreOptions() {
|
||||
uni.showActionSheet({
|
||||
itemList: ['刷新数据', '导出报表', '设置'],
|
||||
success: (res) => {
|
||||
if (res.tapIndex === 0) {
|
||||
uni.showToast({ title: '刷新成功' });
|
||||
} else if (res.tapIndex === 1) {
|
||||
this.exportReport();
|
||||
} else if (res.tapIndex === 2) {
|
||||
uni.showToast({ title: '设置功能暂未开放' });
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.statistics-container {
|
||||
background: #f7f8fa;
|
||||
min-height: 100vh;
|
||||
padding-top: calc(var(--status-bar-height) + 88rpx);
|
||||
}
|
||||
|
||||
/* 支持安全区域的设备 */
|
||||
@supports (padding: max(0px)) {
|
||||
.statistics-container {
|
||||
padding-top: calc(var(--status-bar-height) + 88rpx + env(safe-area-inset-top));
|
||||
}
|
||||
}
|
||||
|
||||
.statistics-content {
|
||||
padding: 32rpx 0;
|
||||
min-height: calc(100vh - 88rpx);
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 16rpx 0 rgba(0, 0, 0, 0.04);
|
||||
margin: 0 32rpx 32rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
.export-card {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.export-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn-export {
|
||||
// background: #3c9cff;
|
||||
color: var(--tab-inactive);
|
||||
font-size: 28rpx;
|
||||
border: none;
|
||||
// padding: 4rpx 40rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.exports {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.btn-export {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.stats-card {
|
||||
.stat-tabs {
|
||||
display: flex;
|
||||
margin-bottom: 32rpx;
|
||||
.stat-tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-muted);
|
||||
padding-bottom: 16rpx;
|
||||
border-bottom: 4rpx solid transparent;
|
||||
transition: all 0.2s;
|
||||
&.active {
|
||||
color: var(--primary-color);
|
||||
font-weight: 600;
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
.tab-content {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
// 月统计网格布局
|
||||
.month-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 12rpx;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.month-item {
|
||||
background: var(--gray-lighter);
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx 12rpx;
|
||||
text-align: center;
|
||||
border: 1rpx solid var(--border-light);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
|
||||
.month-label {
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: var(--shadow-md);
|
||||
transform: translateY(-2rpx);
|
||||
|
||||
.month-label {
|
||||
color: var(--white);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.active):active {
|
||||
background: var(--primary-light);
|
||||
transform: scale(0.98);
|
||||
|
||||
.month-label {
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bar-tabs {
|
||||
display: flex;
|
||||
background: var(--gray-lighter);
|
||||
border-radius: 12rpx;
|
||||
padding: 6rpx;
|
||||
margin-bottom: 24rpx;
|
||||
position: relative;
|
||||
|
||||
.bar-tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
padding: 16rpx 12rpx;
|
||||
border-radius: 8rpx;
|
||||
margin: 0 2rpx;
|
||||
background: transparent;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
|
||||
&.active {
|
||||
color: var(--primary-color);
|
||||
background: var(--surface);
|
||||
font-weight: 600;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-1rpx);
|
||||
}
|
||||
|
||||
&:not(.active):active {
|
||||
background: rgba(60, 156, 255, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bar-tabs-scroll {
|
||||
background: #f8f9fa;
|
||||
border-radius: 12rpx;
|
||||
padding: 6rpx;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.bar-scroll {
|
||||
white-space: nowrap;
|
||||
|
||||
.bar-tab {
|
||||
display: inline-block;
|
||||
min-width: 120rpx;
|
||||
margin: 0 4rpx;
|
||||
padding: 16rpx 20rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
border-radius: 8rpx;
|
||||
background: transparent;
|
||||
transition: all 0.3s ease;
|
||||
font-weight: 500;
|
||||
|
||||
&.active {
|
||||
color: #3c9cff;
|
||||
background: #fff;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-1rpx);
|
||||
}
|
||||
|
||||
&:not(.active):active {
|
||||
background: rgba(60, 156, 255, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 日统计数据显示卡片
|
||||
.day-data-card {
|
||||
margin-top: 24rpx;
|
||||
background: var(--surface);
|
||||
border-radius: 16rpx;
|
||||
box-shadow: var(--shadow-md);
|
||||
overflow: hidden;
|
||||
border: 1rpx solid var(--border);
|
||||
|
||||
.day-data-header {
|
||||
background: var(--gradient-primary);
|
||||
padding: 32rpx 24rpx;
|
||||
color: var(--white);
|
||||
|
||||
.day-data-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8rpx;
|
||||
color: var(--white);
|
||||
|
||||
i {
|
||||
margin-right: 12rpx;
|
||||
font-size: 28rpx;
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
|
||||
.day-data-subtitle {
|
||||
font-size: 24rpx;
|
||||
opacity: 0.9;
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
|
||||
.day-data-content {
|
||||
padding: 24rpx;
|
||||
background: var(--surface);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.day-data-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 16rpx;
|
||||
width: 48%;
|
||||
margin-bottom: 16rpx;
|
||||
background: var(--gray-lighter);
|
||||
border-radius: 12rpx;
|
||||
border: 1rpx solid var(--border-light);
|
||||
box-sizing: border-box;
|
||||
|
||||
&:nth-child(odd) {
|
||||
margin-right: 2%;
|
||||
}
|
||||
|
||||
&:nth-child(even) {
|
||||
margin-left: 2%;
|
||||
}
|
||||
|
||||
.day-data-icon {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 12rpx;
|
||||
flex-shrink: 0;
|
||||
|
||||
i {
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
&.default {
|
||||
background: var(--gray-light);
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
&.success {
|
||||
background: var(--success-light);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background: var(--warning-light);
|
||||
color: var(--warning);
|
||||
}
|
||||
}
|
||||
|
||||
.day-data-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
.day-data-label {
|
||||
font-size: 22rpx;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 6rpx;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.day-data-value {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
|
||||
&.default {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
&.success {
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
color: var(--warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.count-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 16rpx;
|
||||
justify-content: space-between;
|
||||
.count-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 48%;
|
||||
margin-bottom: 16rpx;
|
||||
padding: 24rpx;
|
||||
background: var(--gray-lighter);
|
||||
border-radius: 12rpx;
|
||||
box-sizing: border-box;
|
||||
border: 1rpx solid var(--border-light);
|
||||
.c-title {
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 8rpx;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
.c-value {
|
||||
color: var(--text-color);
|
||||
font-size: 40rpx;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 日历样式 */
|
||||
.calendar {
|
||||
background: var(--surface);
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
margin-top: 16rpx;
|
||||
border: 1rpx solid var(--border);
|
||||
box-shadow: var(--shadow);
|
||||
|
||||
.cal-title {
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
font-size: 32rpx;
|
||||
color: var(--title-color);
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.cal-week-head {
|
||||
display: flex;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
text {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-muted);
|
||||
font-weight: 500;
|
||||
padding: 12rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cal-body {
|
||||
.cal-row {
|
||||
display: flex;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
.cal-cell {
|
||||
flex: 1;
|
||||
height: 64rpx;
|
||||
line-height: 64rpx;
|
||||
text-align: center;
|
||||
border-radius: 8rpx;
|
||||
margin: 0 4rpx;
|
||||
background: var(--gray-lighter);
|
||||
font-size: 28rpx;
|
||||
color: var(--text-color);
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background: var(--primary-color);
|
||||
color: var(--white);
|
||||
font-weight: 600;
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
&.empty {
|
||||
background: transparent;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:not(.empty):not(.selected):hover {
|
||||
background: var(--primary-light);
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep() {
|
||||
.uni-scroll-view {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user