|
@@ -0,0 +1,208 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="page-container">
|
|
|
|
|
+ <!-- 操作按钮 -->
|
|
|
|
|
+ <div class="table-actions">
|
|
|
|
|
+ <el-button type="primary" :icon="Plus" @click="handleAdd">新增机器</el-button>
|
|
|
|
|
+ <el-button type="success" :icon="Refresh" @click="getList">刷新列表</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 数据表格 -->
|
|
|
|
|
+ <el-table v-loading="loading" :data="machineList" border>
|
|
|
|
|
+ <el-table-column type="index" label="序号" width="60" align="center" />
|
|
|
|
|
+ <el-table-column prop="machineId" label="机器ID" min-width="120" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column prop="name" label="名称" min-width="120" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column prop="location" label="位置" min-width="120" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column prop="description" label="描述" min-width="150" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column prop="cameraCount" label="摄像头数" width="100" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag type="info">{{ row.cameraCount || 0 }}</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="enabled" label="启用" width="80" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag :type="row.enabled ? 'success' : 'info'">
|
|
|
|
|
+ {{ row.enabled ? '是' : '否' }}
|
|
|
|
|
+ </el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="createdAt" label="创建时间" width="170" align="center" />
|
|
|
|
|
+ <el-table-column label="操作" width="150" align="center" fixed="right">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-button type="primary" link :icon="Edit" @click="handleEdit(row)">编辑</el-button>
|
|
|
|
|
+ <el-button type="danger" link :icon="Delete" @click="handleDelete(row)">删除</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 新增/编辑弹窗 -->
|
|
|
|
|
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px" destroy-on-close>
|
|
|
|
|
+ <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
|
|
|
|
|
+ <el-form-item label="机器ID" prop="machineId">
|
|
|
|
|
+ <el-input v-model="form.machineId" placeholder="请输入机器ID" :disabled="isEdit" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="名称" prop="name">
|
|
|
|
|
+ <el-input v-model="form.name" placeholder="请输入名称" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="位置" prop="location">
|
|
|
|
|
+ <el-input v-model="form.location" placeholder="请输入位置" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="描述" prop="description">
|
|
|
|
|
+ <el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入描述" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="isEdit" label="启用状态">
|
|
|
|
|
+ <el-switch v-model="form.enabled" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
|
|
+ <el-button type="primary" :loading="submitLoading" @click="handleSubmit">确定</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { ref, reactive, onMounted, computed } from 'vue'
|
|
|
|
|
+import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
|
|
|
|
+import { Refresh, Plus, Edit, Delete } from '@element-plus/icons-vue'
|
|
|
|
|
+import { listMachines, addMachine, updateMachine, deleteMachine } from '@/api/machine'
|
|
|
|
|
+import type { MachineDTO, MachineAddRequest, MachineUpdateRequest } from '@/types'
|
|
|
|
|
+
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+const submitLoading = ref(false)
|
|
|
|
|
+const machineList = ref<MachineDTO[]>([])
|
|
|
|
|
+const dialogVisible = ref(false)
|
|
|
|
|
+const formRef = ref<FormInstance>()
|
|
|
|
|
+
|
|
|
|
|
+const form = reactive<{
|
|
|
|
|
+ id?: number
|
|
|
|
|
+ machineId: string
|
|
|
|
|
+ name: string
|
|
|
|
|
+ location: string
|
|
|
|
|
+ description: string
|
|
|
|
|
+ enabled: boolean
|
|
|
|
|
+}>({
|
|
|
|
|
+ machineId: '',
|
|
|
|
|
+ name: '',
|
|
|
|
|
+ location: '',
|
|
|
|
|
+ description: '',
|
|
|
|
|
+ enabled: true
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const isEdit = computed(() => !!form.id)
|
|
|
|
|
+const dialogTitle = computed(() => (isEdit.value ? '编辑机器' : '新增机器'))
|
|
|
|
|
+
|
|
|
|
|
+const rules: FormRules = {
|
|
|
|
|
+ machineId: [{ required: true, message: '请输入机器ID', trigger: 'blur' }],
|
|
|
|
|
+ name: [{ required: true, message: '请输入名称', trigger: 'blur' }]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function getList() {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await listMachines()
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ machineList.value = res.data
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleAdd() {
|
|
|
|
|
+ Object.assign(form, {
|
|
|
|
|
+ id: undefined,
|
|
|
|
|
+ machineId: '',
|
|
|
|
|
+ name: '',
|
|
|
|
|
+ location: '',
|
|
|
|
|
+ description: '',
|
|
|
|
|
+ enabled: true
|
|
|
|
|
+ })
|
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleEdit(row: MachineDTO) {
|
|
|
|
|
+ Object.assign(form, {
|
|
|
|
|
+ id: row.id,
|
|
|
|
|
+ machineId: row.machineId,
|
|
|
|
|
+ name: row.name,
|
|
|
|
|
+ location: row.location || '',
|
|
|
|
|
+ description: row.description || '',
|
|
|
|
|
+ enabled: row.enabled
|
|
|
|
|
+ })
|
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function handleDelete(row: MachineDTO) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await ElMessageBox.confirm(`确定要删除机器 "${row.name}" 吗?`, '提示', {
|
|
|
|
|
+ type: 'warning'
|
|
|
|
|
+ })
|
|
|
|
|
+ const res = await deleteMachine(row.id)
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ ElMessage.success('删除成功')
|
|
|
|
|
+ getList()
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ if (error !== 'cancel') {
|
|
|
|
|
+ console.error('删除失败', error)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function handleSubmit() {
|
|
|
|
|
+ if (!formRef.value) return
|
|
|
|
|
+
|
|
|
|
|
+ await formRef.value.validate(async (valid) => {
|
|
|
|
|
+ if (valid) {
|
|
|
|
|
+ submitLoading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (isEdit.value) {
|
|
|
|
|
+ const updateData: MachineUpdateRequest = {
|
|
|
|
|
+ id: form.id!,
|
|
|
|
|
+ name: form.name,
|
|
|
|
|
+ location: form.location || undefined,
|
|
|
|
|
+ description: form.description || undefined,
|
|
|
|
|
+ enabled: form.enabled
|
|
|
|
|
+ }
|
|
|
|
|
+ const res = await updateMachine(updateData)
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ ElMessage.success('修改成功')
|
|
|
|
|
+ dialogVisible.value = false
|
|
|
|
|
+ getList()
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const addData: MachineAddRequest = {
|
|
|
|
|
+ machineId: form.machineId,
|
|
|
|
|
+ name: form.name,
|
|
|
|
|
+ location: form.location || undefined,
|
|
|
|
|
+ description: form.description || undefined
|
|
|
|
|
+ }
|
|
|
|
|
+ const res = await addMachine(addData)
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ ElMessage.success('新增成功')
|
|
|
|
|
+ dialogVisible.value = false
|
|
|
|
|
+ getList()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ submitLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ getList()
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+.page-container {
|
|
|
|
|
+ padding: 20px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.table-actions {
|
|
|
|
|
+ margin-bottom: 15px;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|