<template>
|
<view class="inspection-page">
|
<!-- 顶部显示机台信息与年份选择 -->
|
<view class="header">
|
<view class="machine-info">
|
<text>当前机台:</text>
|
<text class="machine-text">{{ machineNo || '未绑定' }}</text>
|
</view>
|
<view class="year-picker">
|
<text class="year-label">点检年份</text>
|
<picker mode="selector"
|
:range="yearOptions"
|
:value="yearPickerIndex"
|
@change="handleYearChange">
|
<view class="picker-trigger">{{ currentYear }} 年</view>
|
</picker>
|
</view>
|
</view>
|
|
<view class="section">
|
<view class="section-title">日点检(31 天)</view>
|
<view class="grid days-grid">
|
<view v-for="(day, index) in days"
|
:key="`day-${day}`"
|
class="grid-cell"
|
:class="{ checked: dailyChecks[index] }"
|
@click="toggleDay(index)">
|
<text class="grid-text">{{ day }}日</text>
|
</view>
|
</view>
|
<view class="summary">已点检:{{ checkedDaysCount }}/31</view>
|
</view>
|
|
<view class="section">
|
<view class="section-title">月点检(12 月)</view>
|
<view class="grid months-grid">
|
<view v-for="(month, index) in months"
|
:key="`month-${month}`"
|
class="grid-cell"
|
:class="{ checked: monthlyChecks[index] }"
|
@click="toggleMonth(index)">
|
<text class="grid-text">{{ month }}月</text>
|
</view>
|
</view>
|
<view class="summary">已点检:{{ checkedMonthsCount }}/12</view>
|
</view>
|
|
<view class="actions">
|
<button class="btn-primary"
|
:loading="saving"
|
:disabled="saving || !machineNo"
|
@click="handleSave">
|
保存
|
</button>
|
<button class="btn-secondary"
|
:disabled="saving"
|
@click="resetChecks">
|
清空
|
</button>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
import { queryEquipmentInspection, saveEquipmentInspection } from '@/utils/equipmentInspection.js'
|
|
export default {
|
name: 'EquipmentInspection',
|
props: {
|
machineNo: {
|
type: String,
|
required: true
|
}
|
},
|
data() {
|
const currentYear = new Date().getFullYear()
|
return {
|
// 当前年份用于区分不同年度的点检表
|
currentYear,
|
yearOptions: this.buildYearOptions(currentYear),
|
dailyChecks: Array(31).fill(false),
|
monthlyChecks: Array(12).fill(false),
|
saving: false,
|
loading: false,
|
dirty: false
|
}
|
},
|
computed: {
|
yearPickerIndex() {
|
const index = this.yearOptions.indexOf(this.currentYear)
|
return index >= 0 ? index : 0
|
},
|
days() {
|
return Array.from({ length: 31 }, (_, idx) => idx + 1)
|
},
|
months() {
|
return Array.from({ length: 12 }, (_, idx) => idx + 1)
|
},
|
checkedDaysCount() {
|
return this.dailyChecks.filter(Boolean).length
|
},
|
checkedMonthsCount() {
|
return this.monthlyChecks.filter(Boolean).length
|
}
|
},
|
watch: {
|
machineNo: {
|
immediate: true,
|
handler(newVal) {
|
if (!newVal) {
|
this.$showMessage('请先绑定机台')
|
return
|
}
|
this.loadInspectionData()
|
}
|
}
|
},
|
methods: {
|
buildYearOptions(baseYear) {
|
// 生成前后各两年的年份列表,方便切换历史记录
|
const range = []
|
for (let offset = -2; offset <= 2; offset += 1) {
|
range.push(baseYear + offset)
|
}
|
return range
|
},
|
handleYearChange(event) {
|
// 切换年份后读取对应的点检数据
|
const index = Number(event.detail.value || 0)
|
const selected = this.yearOptions[index]
|
if (selected === this.currentYear) {
|
return
|
}
|
this.currentYear = selected
|
this.loadInspectionData()
|
},
|
async loadInspectionData() {
|
// 从后台或本地缓存加载点检记录
|
if (!this.machineNo) {
|
return
|
}
|
this.loading = true
|
try {
|
const record = await queryEquipmentInspection(this, {
|
machineNo: this.machineNo,
|
year: this.currentYear
|
}, { mock: true, showLoading: true })
|
this.dailyChecks = record.dailyChecks || Array(31).fill(false)
|
this.monthlyChecks = record.monthlyChecks || Array(12).fill(false)
|
this.dirty = false
|
} catch (error) {
|
console.error('加载设备点检信息失败', error)
|
this.$showMessage('点检记录加载失败')
|
} finally {
|
this.loading = false
|
}
|
},
|
toggleDay(index) {
|
// 切换日点检的勾选状态
|
if (!this.machineNo) {
|
this.$showMessage('请先绑定机台')
|
return
|
}
|
this.$set(this.dailyChecks, index, !this.dailyChecks[index])
|
this.dirty = true
|
},
|
toggleMonth(index) {
|
// 切换月点检的勾选状态
|
if (!this.machineNo) {
|
this.$showMessage('请先绑定机台')
|
return
|
}
|
this.$set(this.monthlyChecks, index, !this.monthlyChecks[index])
|
this.dirty = true
|
},
|
async handleSave() {
|
// 保存当前点检表,预留后台 POST 接口
|
if (!this.machineNo) {
|
this.$showMessage('请先绑定机台')
|
return
|
}
|
if (this.saving) {
|
return
|
}
|
this.saving = true
|
try {
|
const response = await saveEquipmentInspection(this, {
|
machineNo: this.machineNo,
|
year: this.currentYear,
|
dailyChecks: this.dailyChecks,
|
monthlyChecks: this.monthlyChecks
|
}, { mock: true, showLoading: true })
|
|
if (response && response.success) {
|
uni.showToast({ title: '保存成功', icon: 'success' })
|
this.dirty = false
|
} else {
|
this.$showMessage('保存失败,请稍后再试')
|
}
|
} catch (error) {
|
console.error('保存设备点检失败', error)
|
this.$showMessage('保存失败,请检查网络')
|
} finally {
|
this.saving = false
|
}
|
},
|
resetChecks() {
|
// 一键清空勾选状态,便于重新录入
|
this.dailyChecks = Array(31).fill(false)
|
this.monthlyChecks = Array(12).fill(false)
|
this.dirty = true
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.inspection-page {
|
display: flex;
|
flex-direction: column;
|
padding: 2vh 2vw;
|
font-size: 1.4vw;
|
color: #333333;
|
}
|
|
.header {
|
display: flex;
|
flex-direction: row;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 2vh;
|
}
|
|
.machine-info {
|
display: flex;
|
flex-direction: row;
|
align-items: center;
|
font-size: 1.6vw;
|
}
|
|
.machine-text {
|
font-weight: bold;
|
margin-left: 0.5vw;
|
}
|
|
.year-picker {
|
display: flex;
|
flex-direction: row;
|
align-items: center;
|
}
|
|
.year-label {
|
margin-right: 1vw;
|
}
|
|
.picker-trigger {
|
border: 1px solid #d8d8d8;
|
border-radius: 0.8vw;
|
padding: 0.6vh 1.4vw;
|
background-color: #ffffff;
|
font-size: 1.4vw;
|
}
|
|
.section {
|
margin-bottom: 3vh;
|
background-color: #ffffff;
|
border-radius: 1vw;
|
padding: 2vh 1.5vw;
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
|
}
|
|
.section-title {
|
font-size: 1.8vw;
|
font-weight: bold;
|
margin-bottom: 1.5vh;
|
}
|
|
.grid {
|
display: grid;
|
grid-gap: 1vh;
|
}
|
|
.days-grid {
|
grid-template-columns: repeat(7, 1fr);
|
}
|
|
.months-grid {
|
grid-template-columns: repeat(4, 1fr);
|
}
|
|
.grid-cell {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
height: 6vh;
|
background-color: #f5f7fa;
|
border-radius: 0.8vw;
|
border: 1px solid #dcdfe6;
|
color: #606266;
|
transition: all 0.2s ease-in-out;
|
}
|
|
.grid-cell.checked {
|
background-color: #0faeff;
|
color: #ffffff;
|
border-color: transparent;
|
}
|
|
.grid-cell:active {
|
transform: scale(0.98);
|
}
|
|
.grid-text {
|
font-size: 1.4vw;
|
}
|
|
.summary {
|
margin-top: 1.5vh;
|
font-size: 1.3vw;
|
color: #909399;
|
}
|
|
.actions {
|
display: flex;
|
flex-direction: row;
|
justify-content: flex-end;
|
gap: 1vw;
|
}
|
|
.btn-primary,
|
.btn-secondary {
|
min-width: 12vw;
|
padding: 1.2vh 1vw;
|
font-size: 1.4vw;
|
border-radius: 0.8vw;
|
border: none;
|
text-align: center;
|
}
|
|
.btn-primary {
|
background-color: #0faeff;
|
color: #ffffff;
|
}
|
|
.btn-secondary {
|
background-color: #ffffff;
|
color: #0faeff;
|
border: 1px solid #0faeff;
|
}
|
|
.btn-secondary:active,
|
.btn-primary:active {
|
opacity: 0.8;
|
}
|
</style>
|