feat: add desktop-ui frontend
This commit is contained in:
263
desktop-ui/src/views/Standard.vue
Normal file
263
desktop-ui/src/views/Standard.vue
Normal file
@@ -0,0 +1,263 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user