hn_platform_h5/src/pages/leader-home/components/PerformanceStandard.vue

210 lines
5.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="standard-container">
<view class="standard-header">
<text class="standard-title">履职标准</text>
<view>
<DatePicker
:modelValue="dateTimestamp"
format="YYYY年MM月"
:showIcon="true"
:showArrow="false"
iconColor="#333"
@change="handleDateChange"
/>
</view>
</view>
<view class="standard-cards">
<view class="standard-card">
<text class="card-label">现场履职</text>
<text class="card-value">实到: {{ standardDataInfo.real_xclz_num }}</text>
</view>
<view class="standard-card">
<text class="card-label">班组履职</text>
<text class="card-value">实到: {{ standardDataInfo.real_bzlz_num }}</text>
</view>
<view class="standard-card problem-card" @tap="handleProblemClick">
<text class="card-label">发现问题</text>
<text class="card-value problem-value">{{ standardDataInfo.problemNum }}</text>
</view>
</view>
<view class="standard-note">
<text class="note-text">*单日督察多个现场统计为1次</text>
</view>
</view>
</template>
<script setup>
import { computed, ref } from 'vue'
import dayjs from 'dayjs'
import DatePicker from '@/components/DatePicker/index.vue'
import { getHomeStatisticsApi } from '@/services/leader/home'
/**
* 履职标准组件
* 业务背景:展示当前月份的履职标准数据,包括现场履职、班组履职和发现问题数量
* 设计决策:
* 1. 支持日期选择,查看不同月份的数据
* 2. 三个指标卡片横向排列,使用绿色背景突出显示
* 3. 发现问题数量可点击,进入详情页面
* 4. 底部显示说明文字,解释统计规则
*/
const standardDataInfo = ref({
bzlz_unit_type: '次',
problemNum: 0,
real_bzlz_num: 0,
real_xclz_num: 0,
xclz_unit_type: '次',
})
const props = defineProps({
// 选中的日期YYYY-MM格式
selectedDate: {
type: String,
required: true,
},
// 履职标准数据
standardData: {
type: Object,
required: true,
default: () => ({
onSitePerformance: { actual: 0, required: 0 },
teamPerformance: { actual: 0, required: 0 },
problemsFound: { count: 0 },
}),
},
})
const emit = defineEmits(['date-change', 'problem-click'])
/**
* 计算日期时间戳
* 业务背景DatePicker 组件需要时间戳格式
* 设计决策:将 YYYY-MM 格式转换为时间戳
*/
const dateTimestamp = computed(() => {
return dayjs(props.selectedDate).valueOf()
})
/**
* 处理日期变更
* @param {Number} timestamp - 时间戳
*/
const handleDateChange = (timestamp) => {
emit('date-change', timestamp)
getPerformanceStandardData()
}
/**
* 处理发现问题点击
* 业务背景:点击发现问题数量后,进入详情页面
*/
const handleProblemClick = () => {
emit('problem-click')
}
// 获取履职标准数据
const getPerformanceStandardData = async () => {
const res = await getHomeStatisticsApi({
yyyyMM: props.selectedDate.split('-').join(''),
})
if (res.code === 200) {
standardDataInfo.value = res.data
}
}
getPerformanceStandardData()
</script>
<style lang="scss" scoped>
.standard-container {
margin: 0 32rpx 32rpx;
background: #fff;
border-radius: 20rpx;
padding: 40rpx 32rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
}
.standard-header {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 32rpx;
padding-bottom: 24rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.standard-title {
font-size: 32rpx;
font-weight: 700;
color: #333;
letter-spacing: 0.5rpx;
}
.standard-cards {
display: flex;
gap: 20rpx;
margin-bottom: 24rpx;
}
.standard-card {
flex: 1;
background: linear-gradient(135deg, #07c160 0%, #06a050 100%);
border-radius: 16rpx;
padding: 36rpx 20rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 180rpx;
box-shadow: 0 4rpx 12rpx rgba(7, 193, 96, 0.25);
transition: all 0.3s ease;
}
.problem-card {
cursor: pointer;
transition: all 0.3s ease;
}
.problem-card:active {
transform: translateY(-2rpx) scale(0.98);
box-shadow: 0 6rpx 16rpx rgba(7, 193, 96, 0.35);
}
.card-label {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.95);
margin-bottom: 20rpx;
font-weight: 600;
letter-spacing: 0.5rpx;
}
.card-value {
font-size: 36rpx;
color: #fff;
font-weight: 700;
letter-spacing: 1rpx;
}
.problem-value {
color: #fff;
background: rgba(255, 68, 68, 0.9);
padding: 4rpx 16rpx;
border-radius: 8rpx;
font-size: 32rpx;
}
.standard-note {
margin-top: 16rpx;
}
.note-text {
font-size: 24rpx;
color: #999;
line-height: 1.5;
}
</style>