Browse Source

feat: 设备管理 - 设备页面

main
刘凯 1 year ago
parent
commit
5e9b36b0ad
  1. 29
      src/api/device-manage/device/index.ts
  2. 15
      src/api/device-manage/device/types.ts
  3. 55
      src/views/device-manage/device/DeviceFormModal.vue
  4. 123
      src/views/device-manage/device/data.ts
  5. 5
      src/views/device-manage/device/detail.vue
  6. 85
      src/views/device-manage/device/index.vue

29
src/api/device-manage/device/index.ts

@ -0,0 +1,29 @@
import type { Device, GetDeviceListParams } from './types'
import { defHttp } from '@/utils/http/axios'
export function getDeviceList(params: GetDeviceListParams) {
return defHttp.get<PageResult<Device>>({
url: '/device/page',
params,
})
}
export function createDevice(data: Partial<Device>) {
return defHttp.post({
url: '/device/save',
data,
})
}
export function updateDevice(data: Partial<Device>) {
return defHttp.post({
url: '/device/update',
data,
})
}
export function deleteDevice(id: string) {
return defHttp.post({
url: `/device/remove?id=${id}`,
})
}

15
src/api/device-manage/device/types.ts

@ -0,0 +1,15 @@
export interface GetDeviceListParams extends PageParam {
productId?: string
deviceSn?: string
deviceName?: string
isOnline?: BooleanFlag
}
export interface Device {
id: string
productId: string
deviceSn: string
deviceName: string
deviceDesc: string
isOnline: BooleanFlag
}

55
src/views/device-manage/device/DeviceFormModal.vue

@ -0,0 +1,55 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { getFormSchema } from './data'
import { useMessage } from '@/hooks/web/useMessage'
import { BasicForm, useForm } from '@/components/Form'
import { BasicModal, useModalInner } from '@/components/Modal'
import { createDevice, updateDevice } from '@/api/device-manage/device'
import type { Device } from '@/api/device-manage/device/types'
defineOptions({ name: 'DeviceFormModal' })
const emit = defineEmits(['success', 'register'])
const isUpdate = ref(false)
const [registerForm, { setFieldsValue, validate }] = useForm({
labelWidth: 100,
baseColProps: { span: 24 },
schemas: getFormSchema(isUpdate),
showActionButtonGroup: false,
actionColOptions: { span: 23 },
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data: Device) => {
isUpdate.value = true
setFieldsValue({ ...data })
})
async function handleSubmit() {
try {
const values = await validate<Device>()
setModalProps({ confirmLoading: true })
await (isUpdate.value ? updateDevice(values) : createDevice(values))
closeModal()
emit('success')
useMessage().createMessage.success('保存成功')
}
finally {
setModalProps({ confirmLoading: false })
}
}
</script>
<template>
<BasicModal
v-bind="$attrs"
width="30%"
:min-height="100"
:title="isUpdate ? '编辑' : '新增'"
:after-close="() => isUpdate = false"
@register="registerModal"
@ok="handleSubmit"
>
<BasicForm @register="registerForm" />
</BasicModal>
</template>

123
src/views/device-manage/device/data.ts

@ -0,0 +1,123 @@
import { Tag } from 'ant-design-vue'
import type { Ref } from 'vue'
import { h } from 'vue'
import type { BasicColumn, FormSchema } from '@/components/Table'
import { getAllProducts } from '@/api/product'
import { getAllTenants } from '@/api/system/tenant'
export const columns: BasicColumn[] = [
{
title: '所属产品',
dataIndex: 'productName',
},
{
title: '设备名称',
dataIndex: 'deviceName',
},
{
title: '设备序列号',
dataIndex: 'deviceSn',
},
{
title: '设备描述',
dataIndex: 'deviceDesc',
},
{
title: '是否在线',
dataIndex: 'isOnline',
customRender({ value }) {
return h(Tag, {
color: value ? 'green' : 'default',
}, () => value ? '在线' : '离线')
},
},
]
export const searchFormSchemas: FormSchema[] = [
{
label: '所属租户',
field: 'tenantId',
component: 'ApiSelect',
componentProps: {
api: getAllTenants,
valueField: 'tenantId',
labelField: 'tenantName',
},
colProps: { span: 6 },
},
{
label: '所属产品',
field: 'productId',
component: 'ApiSelect',
componentProps: {
api: getAllProducts,
valueField: 'id',
labelField: 'productName',
},
colProps: { span: 6 },
},
{
label: '设备序列号',
field: 'deviceSn',
component: 'Input',
colProps: { span: 6 },
},
{
label: '设备名称',
field: 'deviceName',
component: 'Input',
colProps: { span: 6 },
},
{
label: '是否在线',
field: 'isOnline',
component: 'Select',
componentProps: {
options: [
{ label: '在线', value: 1 },
{ label: '离线', value: 0 },
],
},
colProps: { span: 6 },
},
]
export function getFormSchema(isUpdate: Ref<boolean>): FormSchema[] {
return [
{
field: 'id',
show: false,
component: 'Input',
},
{
label: '设备名称',
field: 'deviceName',
component: 'Input',
required: true,
},
{
label: '设备序列号',
field: 'deviceSn',
component: 'Input',
required: true,
ifShow: () => !isUpdate.value,
},
{
label: '所属产品',
field: 'productId',
component: 'ApiSelect',
required: true,
ifShow: () => !isUpdate.value,
componentProps: {
api: getAllProducts,
valueField: 'id',
labelField: 'productName',
},
},
{
label: '设备描述',
field: 'deviceDesc',
component: 'InputTextArea',
},
]
}

5
src/views/device-manage/device/detail.vue

@ -0,0 +1,5 @@
<template>
<div>
Detail
</div>
</template>

85
src/views/device-manage/device/index.vue

@ -0,0 +1,85 @@
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue'
import { columns, searchFormSchemas } from './data'
import DeviceFormModal from './DeviceFormModal.vue'
import { useModal } from '@/components/Modal'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { deleteDevice, getDeviceList } from '@/api/device-manage/device'
import type { Device } from '@/api/device-manage/device/types'
import { useMessage } from '@/hooks/web/useMessage'
defineOptions({ name: 'Device' })
const [registerModal, { openModal }] = useModal<Device>()
const [register, { reload }] = useTable({
api: getDeviceList,
columns,
formConfig: {
schemas: searchFormSchemas,
labelWidth: 80,
},
bordered: true,
canResize: false,
useSearchForm: true,
actionColumn: {
width: 220,
title: '操作',
dataIndex: 'action',
fixed: 'right',
},
})
async function handleDelete(id: string) {
try {
await deleteDevice(id)
useMessage().createMessage.success('删除成功')
reload()
}
catch {}
}
</script>
<template>
<div>
<BasicTable :api="async () => ([] as Device[])" @register="register">
<template #tableTitle>
<a-button type="primary" @click="openModal(true)">
<PlusOutlined />
新建
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'i-ant-design:file-search-outlined',
label: '详情',
onClick: () => $router.push(`/device-manage/device/detail/${record.id}`),
},
{
icon: 'i-ant-design:edit-outlined',
label: '编辑',
onClick: () => openModal(true, record),
},
{
icon: 'i-ant-design:delete-outlined',
danger: true,
label: '删除',
popConfirm: {
title: '是否要删除数据?',
placement: 'left',
confirm: () => handleDelete(record.id),
},
},
]"
/>
</template>
</template>
</BasicTable>
<DeviceFormModal @register="registerModal" @success="reload" />
</div>
</template>
Loading…
Cancel
Save