Files
labmanager/desktop-ui/src/views/Standard.vue

263 lines
8.2 KiB
Vue
Raw Normal View History

2026-05-11 16:04:31 +08:00
<script setup>
import { ref, computed, onMounted } from "vue"
import { getCurrentInstance } from "vue"
import { ElMessage, ElMessageBox } from "element-plus"
const { $http } = getCurrentInstance().appContext.config.globalProperties
const isAdmin = localStorage.getItem('role') === 'admin'
function formatDate(date) {
if (!date) return "-"
const d = new Date(date)
const y = d.getFullYear()
const m = String(d.getMonth() + 1).padStart(2, "0")
const day = String(d.getDate()).padStart(2, "0")
return `${y}-${m}-${day}`
}
const data = ref([])
const dialogVisible = ref(false)
const editing = ref(false)
const form = ref({
batch: "",
im: "",
ass: "",
calibration_date: "",
expire_date: "",
location: "",
})
// 有效期筛查天数0=全部)
const filterDays = ref(0)
const filteredData = computed(() => {
if (!filterDays.value || filterDays.value <= 0) return data.value
const now = new Date()
const limit = new Date(now.getTime() + filterDays.value * 86400000)
return data.value.filter((item) => {
if (!item.expire_date) return false
const expire = new Date(item.expire_date)
return expire >= now && expire <= limit
})
})
function rowClass({ row }) {
if (!row.expire_date) return ""
const today = new Date()
today.setHours(0, 0, 0, 0)
const expire = new Date(row.expire_date)
expire.setHours(0, 0, 0, 0)
return expire < today ? "row-expired" : ""
}
function rowStyle({ row }) {
if (!row.expire_date) return {}
const today = new Date()
today.setHours(0, 0, 0, 0)
const expire = new Date(row.expire_date)
expire.setHours(0, 0, 0, 0)
if (expire < today) {
return { color: "#dc2626" }
}
return {}
}
async function refresh() {
try {
const res = await $http.get("/standard")
data.value = res.data || []
} catch {
data.value = []
}
}
function openCreate() {
editing.value = false
form.value = { batch: "", im: "", ass: "", calibration_date: "", expire_date: "", location: "" }
dialogVisible.value = true
}
function openEdit(row) {
editing.value = true
form.value = { ...row }
dialogVisible.value = true
}
async function save() {
if (!form.value.batch) {
ElMessage.error("批号不能为空")
return
}
try {
if (editing.value) {
await $http.patch(`/standard/${form.value._id}`, form.value)
ElMessage.success("更新成功")
} else {
await $http.post("/standard", form.value)
ElMessage.success("创建成功")
}
dialogVisible.value = false
await refresh()
} catch (error) {
ElMessage.error(error.response?.data?.message || "操作失败")
}
}
async function remove(row) {
try {
await ElMessageBox.confirm(`确定要删除批号为"${row.batch}"的对照品吗?`, "确认删除", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
await $http.delete(`/standard/${row._id}`)
ElMessage.success("删除成功")
await refresh()
} catch {
// cancelled
}
}
onMounted(refresh)
</script>
<template>
<div class="page-container">
<div class="actions-bar">
<div class="actions-left">
<el-button @click="refresh">刷新</el-button>
<el-button type="primary" @click="openCreate">新增对照品</el-button>
</div>
<div class="actions-right">
<span class="filter-label">有效期</span>
<el-input-number v-model="filterDays" :min="0" :max="365" :step="7" size="small"
controls-position="right" style="width: 100px" />
<span class="filter-unit">天内到期</span>
<el-tag v-if="filterDays > 0" type="warning" size="small" effect="plain">
显示 {{ filteredData.length }}
</el-tag>
<el-button v-if="filterDays > 0" size="small" text type="info" @click="filterDays = 0">
清除
</el-button>
</div>
</div>
<el-table :data="filteredData" stripe border style="width: 100%" :row-class-name="rowClass"
:row-style="rowStyle">
<el-table-column prop="batch" label="批号" min-width="180" />
<el-table-column prop="im" label="含量(%)" width="100" />
<el-table-column prop="ass" label="纯度(%)" width="100" />
<el-table-column prop="calibration_date" label="标定日期" width="120">
<template #default="{ row }">
{{ formatDate(row.calibration_date) }}
</template>
</el-table-column>
<el-table-column prop="expire_date" label="有效期" width="120">
<template #default="{ row }">
{{ formatDate(row.expire_date) }}
</template>
</el-table-column>
<el-table-column prop="location" label="存放位置" min-width="140" />
<el-table-column label="操作" width="180" fixed="right">
<template #default="{ row }">
<el-button size="small" @click="openEdit(row)">编辑</el-button>
<el-button size="small" type="danger" :disabled="!isAdmin" @click="remove(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog v-model="dialogVisible" :title="editing ? '编辑对照品' : '新增对照品'" width="520px" align-center>
<el-form :model="form" label-position="top">
<el-form-item label="批号" required>
<el-input v-model="form.batch" />
</el-form-item>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="含量(%)">
<el-input v-model="form.im" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="纯度(%)">
<el-input v-model="form.ass" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="标定日期">
<el-date-picker v-model="form.calibration_date" type="date" style="width: 100%"
value-format="YYYY-MM-DD" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="有效期">
<el-date-picker v-model="form.expire_date" type="date" style="width: 100%"
value-format="YYYY-MM-DD" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="存放位置">
<el-input v-model="form.location" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</template>
</el-dialog>
</div>
</template>
<style scoped>
.page-container {
padding: 24px;
}
.actions-bar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
flex-wrap: wrap;
gap: 8px;
}
.actions-left {
display: flex;
align-items: center;
gap: 8px;
}
.actions-right {
display: flex;
align-items: center;
gap: 6px;
}
.filter-label {
font-size: 13px;
color: #8896a8;
white-space: nowrap;
}
.filter-unit {
font-size: 13px;
color: #3d4a5c;
white-space: nowrap;
}
/* 过期行文字红色 */
:deep(.el-table .row-expired) {
color: #dc2626 !important;
font-weight: 500;
}
:deep(.row-expired:hover) {
background-color: #fee2e2 !important;
}
:deep(.row-expired .el-table__cell) {
color: #dc2626;
}
</style>