laobinghu 4df5c13976 refactor: simplify dark mode with VueUse + Element Plus
Remove custom CSS variable overrides, use Element Plus built-in dark mode with VueUse useDark
2026-03-22 16:22:35 +08:00

239 lines
6.4 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>
<div class="checkins-container">
<el-card>
<template #header>
<div class="card-header">
<span>机位到位打卡</span>
<el-button type="primary" @click="showAddDialog = true">添加打卡</el-button>
</div>
</template>
<el-form :inline="true" class="filter-form">
<!-- 机位号筛选 -->
<el-form-item label="机位号">
<el-select v-model="filters.position_number" placeholder="全部" clearable @change="loadCheckins">
<el-option v-for="p in positionOptions" :key="p.value" :label="p.label" :value="p.value"></el-option>
</el-select>
</el-form-item>
<!-- 状态筛选 -->
<el-form-item label="状态">
<el-select v-model="filters.status" placeholder="全部" clearable @change="loadCheckins">
<el-option v-for="s in statusOptions" :key="s.value" :label="s.label" :value="s.value"></el-option>
</el-select>
</el-form-item>
</el-form>
<el-table :data="checkins" border stripe class="checkins-table">
<el-table-column prop="id" label="ID" width="80"></el-table-column>
<el-table-column prop="position_number" label="机位号" width="100"></el-table-column>
<el-table-column prop="status" label="状态" width="120">
<template #default="{ row }">
<el-tag :type="getStatusType(row.status)">{{ row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="created_at" label="打卡时间">
<template #default="{ row }">
{{ formatDate(row.created_at) }}
</template>
</el-table-column>
<el-table-column prop="notes" label="备注"></el-table-column>
</el-table>
</el-card>
<el-dialog v-model="showAddDialog" title="添加打卡" width="500px">
<el-form :model="form" label-width="100px">
<el-form-item label="机位号">
<el-select v-model="form.position_number" placeholder="请选择机位号">
<el-option v-for="p in positionOptions" :key="p.value" :label="p.label" :value="p.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="form.status" placeholder="请选择状态">
<el-option v-for="s in statusOptions" :key="s.value" :label="s.label" :value="s.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.notes" type="textarea" placeholder="请输入备注(可选)"></el-input>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showAddDialog = false">取消</el-button>
<el-button type="primary" @click="addCheckin">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { ref, onMounted } from 'vue'
const checkins = ref([])
const showAddDialog = ref(false)
// 机位选项1-6号
const positionOptions = [
{ value: 1, label: '1号心晴空间固定机位' },
{ value: 2, label: '2号AB栋固定机位' },
{ value: 3, label: '3号游走机位' },
{ value: 4, label: '4号游走机位' },
{ value: 5, label: '5号游走机位' },
{ value: 6, label: '6号游走机位' }
]
// 状态选项
const statusOptions = [
{ value: '到位', label: '到位' },
{ value: '离开', label: '离开' },
{ value: '休息/轮换', label: '休息/轮换' },
{ value: '异常', label: '异常' }
]
const filters = ref({
position_number: null as number | null,
status: '' as string
})
const form = ref({
position_number: null as number | null,
status: '',
notes: ''
})
const loadCheckins = async () => {
try {
const params = new URLSearchParams()
if (filters.value.position_number !== null && filters.value.position_number !== undefined) {
params.append('position_number', filters.value.position_number.toString())
}
if (filters.value.status) {
params.append('status', filters.value.status)
}
const res = await $fetch(`/api/checkins?${params}`)
checkins.value = res.data
} catch (error) {
ElMessage.error('加载数据失败')
}
}
const addCheckin = async () => {
if (!form.value.position_number || !form.value.status) {
ElMessage.error('请填写完整信息')
return
}
try {
await $fetch('/api/checkins', {
method: 'POST',
body: {
position_number: form.value.position_number,
status: form.value.status,
notes: form.value.notes || ''
}
})
ElMessage.success('添加成功')
showAddDialog.value = false
form.value = { position_number: null, status: '', notes: '' }
loadCheckins()
} catch (error) {
ElMessage.error('添加失败')
}
}
const formatDate = (dateStr: string) => {
return new Date(dateStr).toLocaleString('zh-CN')
}
const getStatusType = (status: string) => {
const types: Record<string, string> = {
'到位': 'success',
'离开': 'info',
'休息/轮换': 'warning',
'异常': 'danger'
}
return types[status] || 'info'
}
onMounted(() => {
loadCheckins()
})
</script>
<style scoped>
.checkins-container {
max-width: 1200px;
margin: 0 auto;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.card-header span {
color: var(--el-text-color-primary);
font-size: 18px;
font-weight: 600;
}
.filter-form {
margin-bottom: 20px;
}
/* 确保表格和表单在暗色模式下文字清晰 */
:deep(.el-card) {
background-color: var(--header-bg);
color: var(--el-text-color-primary);
}
:deep(.el-card .el-card__header) {
border-bottom-color: var(--el-border-color);
}
:deep(.el-form-item__label) {
color: var(--el-text-color-primary) !important;
}
:deep(.el-table) {
color: var(--el-text-color-primary);
}
:deep(.el-table th) {
background-color: var(--header-bg);
color: var(--el-text-color-primary);
}
:deep(.el-table tr) {
background-color: var(--header-bg);
}
:deep(.el-table td) {
color: var(--el-text-color-primary);
}
@media (max-width: 900px) {
.card-header {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.filter-form :deep(.el-form-item) {
margin-right: 0;
width: 100%;
}
.filter-form :deep(.el-select) {
width: 100%;
}
.checkins-table :deep(.col-notes) {
display: none;
}
}
</style>