Compare commits
2 Commits
c99bc16533
...
3e58485d2f
Author | SHA1 | Date | |
---|---|---|---|
3e58485d2f | |||
840adcafce |
@ -1,51 +1,55 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
// 设备 VO
|
// 设备 VO
|
||||||
export interface DeviceVO {
|
export interface DeviceVO {
|
||||||
id: number // 主键ID
|
id: number // 主键ID
|
||||||
devicename: string // 设备名称
|
devicename: string // 设备名称
|
||||||
devicecode: string // 设备ID/编号
|
devicecode: number // 设备ID/编号
|
||||||
devicetype: string // 设备类型
|
devicetype: string // 设备类型
|
||||||
location: string // 设备位置
|
location: string // 设备位置
|
||||||
devicestatus: number // 设备状态(0:待激活 1 在线 2 离线 ,3 禁用 )
|
devicestatus: number // 设备状态(0:待激活 1 在线 2 离线 ,3 禁用 )
|
||||||
orgid: number // 机构ID
|
orgid: number // 机构ID
|
||||||
orgname: string // 机构名称
|
orgname: string // 机构名称
|
||||||
description: string // 设备描述
|
description: string // 设备描述
|
||||||
createtime: Date // 创建时间
|
createtime: Date // 创建时间
|
||||||
updatetime: Date // 更新时间
|
updatetime: Date // 更新时间
|
||||||
createby: string // 创建人
|
createby: string // 创建人
|
||||||
updateby: string // 更新人
|
updateby: string // 更新人
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设备 API
|
// 设备 API
|
||||||
export const DeviceApi = {
|
export const DeviceApi = {
|
||||||
// 查询设备分页
|
// 查询设备分页
|
||||||
getDevicePage: async (params: any) => {
|
getDevicePage: async (params: any) => {
|
||||||
return await request.get({ url: `/system/device/page`, params })
|
return await request.get({ url: `/system/device/page`, params })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 查询设备详情
|
// 查询设备详情
|
||||||
getDevice: async (id: number) => {
|
getDevice: async (id: number) => {
|
||||||
return await request.get({ url: `/system/device/get?id=` + id })
|
return await request.get({ url: `/system/device/get?id=` + id })
|
||||||
},
|
},
|
||||||
|
// 查询设备详情
|
||||||
// 新增设备
|
getDeviceId: async (devicecode: number) => {
|
||||||
createDevice: async (data: DeviceVO) => {
|
return await request.get({ url: `/system/device/getDeviceId?devicecode=` + devicecode })
|
||||||
return await request.post({ url: `/system/device/create`, data })
|
},
|
||||||
},
|
|
||||||
|
// 新增设备
|
||||||
// 修改设备
|
createDevice: async (data: DeviceVO) => {
|
||||||
updateDevice: async (data: DeviceVO) => {
|
return await request.post({ url: `/system/device/create`, data })
|
||||||
return await request.put({ url: `/system/device/update`, data })
|
},
|
||||||
},
|
|
||||||
|
// 修改设备
|
||||||
// 删除设备
|
updateDevice: async (data: DeviceVO) => {
|
||||||
deleteDevice: async (id: number) => {
|
return await request.put({ url: `/system/device/update`, data })
|
||||||
return await request.delete({ url: `/system/device/delete?id=` + id })
|
},
|
||||||
},
|
|
||||||
|
// 删除设备
|
||||||
// 导出设备 Excel
|
deleteDevice: async (id: number) => {
|
||||||
exportDevice: async (params) => {
|
return await request.delete({ url: `/system/device/delete?id=` + id })
|
||||||
return await request.download({ url: `/system/device/export-excel`, params })
|
},
|
||||||
},
|
|
||||||
}
|
// 导出设备 Excel
|
||||||
|
exportDevice: async (params) => {
|
||||||
|
return await request.download({ url: `/system/device/export-excel`, params })
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -244,5 +244,8 @@ export enum DICT_TYPE {
|
|||||||
IOT_PLUGIN_STATUS = 'iot_plugin_status', // IOT 插件状态
|
IOT_PLUGIN_STATUS = 'iot_plugin_status', // IOT 插件状态
|
||||||
IOT_PLUGIN_TYPE = 'iot_plugin_type', // IOT 插件类型
|
IOT_PLUGIN_TYPE = 'iot_plugin_type', // IOT 插件类型
|
||||||
IOT_DATA_BRIDGE_DIRECTION_ENUM = 'iot_data_bridge_direction_enum', // 桥梁方向
|
IOT_DATA_BRIDGE_DIRECTION_ENUM = 'iot_data_bridge_direction_enum', // 桥梁方向
|
||||||
IOT_DATA_BRIDGE_TYPE_ENUM = 'iot_data_bridge_type_enum' // 桥梁类型
|
IOT_DATA_BRIDGE_TYPE_ENUM = 'iot_data_bridge_type_enum', // 桥梁类型
|
||||||
|
//===================设备类型===================
|
||||||
|
IOT_DEVICE_TYPE = 'iot_device_type', // 设备类型
|
||||||
|
IOT_DEVICE_STATUS = 'iot_device_status', // 设备状态
|
||||||
}
|
}
|
||||||
|
@ -8,25 +8,25 @@
|
|||||||
:disabled="true"
|
:disabled="true"
|
||||||
>
|
>
|
||||||
<el-form-item label="设备ID">
|
<el-form-item label="设备ID">
|
||||||
<span>{{ formData.deviceKey }}</span>
|
<span>{{ formData.devicecode }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备名称">
|
<el-form-item label="设备名称">
|
||||||
<span>{{ formData.deviceName }}</span>
|
<span>{{ formData.devicename }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="所属机构">
|
<el-form-item label="所属机构">
|
||||||
<span>{{ getOrgName(formData.productId) }}</span>
|
<span>{{ formData.orgname }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备类型">
|
<el-form-item label="设备类型">
|
||||||
<span>{{ getDeviceTypeName(formData.deviceType) }}</span>
|
<span>{{ getDeviceTypeName(formData.devicetype) }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备位置">
|
<el-form-item label="设备位置">
|
||||||
<span>{{ formData.address }}</span>
|
<span>{{ formData.location }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备状态">
|
<el-form-item label="设备状态">
|
||||||
<span>{{ getDeviceStateName(formData.state) }}</span>
|
<span>{{ getDeviceStatusName(formData.devicestatus) }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备描述">
|
<el-form-item label="设备描述">
|
||||||
<span>{{ formData.description || '-' }}</span>
|
<span>{{ formData.description }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -36,67 +36,46 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DeviceApi } from '@/api/device'
|
||||||
import * as DeviceApi from '@/api/iot/device/device'
|
import { ElMessage } from 'element-plus'
|
||||||
import * as ProductApi from '@/api/iot/product/product'
|
|
||||||
import { DeviceStateEnum } from '@/api/iot/device/device'
|
|
||||||
|
|
||||||
defineOptions({ name: 'DeviceDetailsForm' })
|
defineOptions({ name: 'DeviceDetailsForm' })
|
||||||
|
|
||||||
|
// 设备类型映射
|
||||||
|
const getDeviceTypeName = (type: string) => {
|
||||||
|
const typeMap: Record<string, string> = {
|
||||||
|
'ECG': '心电设备',
|
||||||
|
'BP': '血压设备',
|
||||||
|
'SPO2': '血氧设备',
|
||||||
|
'TEMP': '体温设备',
|
||||||
|
'WEIGHT': '体重设备'
|
||||||
|
}
|
||||||
|
return typeMap[type] || type
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备状态映射
|
||||||
|
const getDeviceStatusName = (status: string | number) => {
|
||||||
|
const statusMap: Record<string | number, string> = {
|
||||||
|
0: '待激活',
|
||||||
|
1: '在线',
|
||||||
|
2: '离线'
|
||||||
|
}
|
||||||
|
return statusMap[status] || '未知状态'
|
||||||
|
}
|
||||||
|
|
||||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
const dialogTitle = ref('') // 弹窗的标题
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
const formLoading = ref(false) // 表单的加载中
|
const formLoading = ref(false) // 表单的加载中
|
||||||
const formData = ref<DeviceApi.DeviceVO>({
|
const formData = ref({
|
||||||
id: 0,
|
devicecode: undefined,
|
||||||
deviceKey: '',
|
devicename: '',
|
||||||
deviceName: '',
|
orgname: '',
|
||||||
productId: 0,
|
devicetype: '',
|
||||||
productKey: '',
|
location: '',
|
||||||
deviceType: 0,
|
devicestatus: '',
|
||||||
nickname: '',
|
description: ''
|
||||||
gatewayId: 0,
|
|
||||||
state: DeviceStateEnum.INACTIVE,
|
|
||||||
onlineTime: new Date(),
|
|
||||||
offlineTime: new Date(),
|
|
||||||
activeTime: new Date(),
|
|
||||||
createTime: new Date(),
|
|
||||||
ip: '',
|
|
||||||
firmwareVersion: '',
|
|
||||||
deviceSecret: '',
|
|
||||||
mqttClientId: '',
|
|
||||||
mqttUsername: '',
|
|
||||||
mqttPassword: '',
|
|
||||||
authType: '',
|
|
||||||
latitude: 0,
|
|
||||||
longitude: 0,
|
|
||||||
areaId: 0,
|
|
||||||
address: '',
|
|
||||||
serialNumber: '',
|
|
||||||
config: '',
|
|
||||||
description: '',
|
|
||||||
groupIds: []
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const productList = ref<ProductApi.ProductVO[]>([]) // 产品列表
|
|
||||||
|
|
||||||
// 获取机构名称
|
|
||||||
const getOrgName = (productId: number) => {
|
|
||||||
const product = productList.value.find(item => item.id === productId)
|
|
||||||
return product?.name || '-'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取设备类型名称
|
|
||||||
const getDeviceTypeName = (type: number) => {
|
|
||||||
const dict = getIntDictOptions(DICT_TYPE.IOT_DEVICE_TYPE).find(item => item.value === type)
|
|
||||||
return dict?.label || '-'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取设备状态名称
|
|
||||||
const getDeviceStateName = (state: number) => {
|
|
||||||
const dict = getIntDictOptions(DICT_TYPE.IOT_DEVICE_STATE).find(item => item.value === state)
|
|
||||||
return dict?.label || '-'
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async (id: number) => {
|
const open = async (id: number) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
@ -106,38 +85,8 @@ const open = async (id: number) => {
|
|||||||
if (id) {
|
if (id) {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
// 这里模拟获取设备数据,实际项目中应该调用API
|
const res = await DeviceApi.getDeviceId(id)
|
||||||
const mockDeviceData = {
|
formData.value = res
|
||||||
id: id,
|
|
||||||
deviceKey: 'Device' + id,
|
|
||||||
deviceName: '测试设备' + id,
|
|
||||||
deviceType: 1,
|
|
||||||
state: DeviceStateEnum.INACTIVE,
|
|
||||||
address: '北京市/海淀区/中关村',
|
|
||||||
description: '这是一个测试设备的描述信息',
|
|
||||||
productId: 1,
|
|
||||||
productKey: 'product_key_' + id,
|
|
||||||
nickname: '设备昵称' + id,
|
|
||||||
gatewayId: 1,
|
|
||||||
onlineTime: new Date(),
|
|
||||||
offlineTime: new Date(),
|
|
||||||
activeTime: new Date(),
|
|
||||||
createTime: new Date(),
|
|
||||||
ip: '192.168.1.1',
|
|
||||||
firmwareVersion: '1.0.0',
|
|
||||||
deviceSecret: 'secret_' + id,
|
|
||||||
mqttClientId: 'client_' + id,
|
|
||||||
mqttUsername: 'username_' + id,
|
|
||||||
mqttPassword: 'password_' + id,
|
|
||||||
authType: 'password',
|
|
||||||
latitude: 39.123456,
|
|
||||||
longitude: 117.123456,
|
|
||||||
areaId: 1,
|
|
||||||
serialNumber: 'SN' + id,
|
|
||||||
config: '{}',
|
|
||||||
groupIds: []
|
|
||||||
}
|
|
||||||
formData.value = mockDeviceData
|
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
@ -148,34 +97,13 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|||||||
/** 重置表单 */
|
/** 重置表单 */
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
id: 0,
|
devicecode: undefined,
|
||||||
deviceKey: '',
|
devicename: '',
|
||||||
deviceName: '',
|
orgname: '',
|
||||||
productId: 0,
|
devicetype: '',
|
||||||
productKey: '',
|
location: '',
|
||||||
deviceType: 0,
|
devicestatus: '',
|
||||||
nickname: '',
|
description: ''
|
||||||
gatewayId: 0,
|
|
||||||
state: DeviceStateEnum.INACTIVE,
|
|
||||||
onlineTime: new Date(),
|
|
||||||
offlineTime: new Date(),
|
|
||||||
activeTime: new Date(),
|
|
||||||
createTime: new Date(),
|
|
||||||
ip: '',
|
|
||||||
firmwareVersion: '',
|
|
||||||
deviceSecret: '',
|
|
||||||
mqttClientId: '',
|
|
||||||
mqttUsername: '',
|
|
||||||
mqttPassword: '',
|
|
||||||
authType: '',
|
|
||||||
latitude: 0,
|
|
||||||
longitude: 0,
|
|
||||||
areaId: 0,
|
|
||||||
address: '',
|
|
||||||
serialNumber: '',
|
|
||||||
config: '',
|
|
||||||
description: '',
|
|
||||||
groupIds: []
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,64 +1,77 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-card class="device-card" :body-style="{ padding: '20px' }" :data-status="deviceInfo.status">
|
<!-- 设备卡片组件 -->
|
||||||
|
<el-card class="device-card" :body-style="{ padding: '20px' }" :data-status="deviceInfo.devicestatus">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
<!-- 设备基本信息区域 -->
|
||||||
<div class="device-info">
|
<div class="device-info">
|
||||||
|
<!-- 设备名称和操作按钮区域 -->
|
||||||
<div class="name-section">
|
<div class="name-section">
|
||||||
<h3 class="device-name">{{ deviceInfo.name }}</h3>
|
<h3 class="device-name">{{ deviceInfo.devicename }}</h3>
|
||||||
<el-button
|
<!-- 详情和数据按钮 -->
|
||||||
type="primary"
|
<div class="button-group">
|
||||||
size="small"
|
<el-button
|
||||||
class="detail-btn"
|
type="primary"
|
||||||
text
|
size="small"
|
||||||
@click="handleAction('details')"
|
class="detail-btn"
|
||||||
>
|
text
|
||||||
详情
|
@click="handleAction('details')"
|
||||||
</el-button>
|
>
|
||||||
<el-button
|
详情
|
||||||
type="primary"
|
</el-button>
|
||||||
size="small"
|
<el-button
|
||||||
class="data-btn"
|
type="primary"
|
||||||
text
|
size="small"
|
||||||
@click="handleAction('data')"
|
class="data-btn"
|
||||||
>
|
text
|
||||||
数据
|
@click="handleAction('data')"
|
||||||
</el-button>
|
>
|
||||||
|
数据
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="device-status" :class="deviceInfo.status">
|
<!-- 设备状态显示 -->
|
||||||
{{ deviceInfo.statusText }}
|
<p class="device-status" :class="getStatusClass(deviceInfo.devicestatus)">
|
||||||
|
{{ getStatusText(deviceInfo.devicestatus) }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 设备详细信息区域 -->
|
||||||
<div class="device-details">
|
<div class="device-details">
|
||||||
<p class="detail-item">
|
<p class="detail-item">
|
||||||
<span class="label">设备ID:</span>
|
<span class="label">设备ID:</span>
|
||||||
<span class="value">{{ deviceInfo.id }}</span>
|
<span class="value">{{ deviceInfo.devicecode }}</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="detail-item">
|
<p class="detail-item">
|
||||||
<span class="label">类型:</span>
|
<span class="label">类型:</span>
|
||||||
<span class="value">{{ deviceInfo.type }}</span>
|
<span class="value">{{ getDeviceTypeName(deviceInfo.devicetype) }}</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="detail-item">
|
<p class="detail-item">
|
||||||
<span class="label">位置:</span>
|
<span class="label">位置:</span>
|
||||||
<span class="value">{{ deviceInfo.address }}</span>
|
<span class="value">{{ deviceInfo.location }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 分隔线 -->
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
|
<!-- 设备操作按钮区域 -->
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
|
<!-- 启用按钮 -->
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
:disabled="deviceInfo.status === 'normal'"
|
:disabled="deviceInfo.devicestatus === 1"
|
||||||
@click="handleAction('enable')"
|
@click="handleAction('enable')"
|
||||||
>
|
>
|
||||||
启用
|
启用
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<!-- 停用按钮 -->
|
||||||
<el-button
|
<el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
size="small"
|
size="small"
|
||||||
:disabled="deviceInfo.status === 'error'"
|
:disabled="deviceInfo.devicestatus === 2"
|
||||||
@click="handleAction('disable')"
|
@click="handleAction('disable')"
|
||||||
>
|
>
|
||||||
停用
|
停用
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<!-- 设置按钮 -->
|
||||||
<el-button
|
<el-button
|
||||||
type="success"
|
type="success"
|
||||||
size="small"
|
size="small"
|
||||||
@ -66,6 +79,7 @@
|
|||||||
>
|
>
|
||||||
设置
|
设置
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<!-- 删除按钮 -->
|
||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
plain
|
plain
|
||||||
@ -79,27 +93,73 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="ts" setup>
|
||||||
import { defineProps, defineEmits } from 'vue'
|
import { defineProps, defineEmits } from 'vue'
|
||||||
import { Delete } from '@element-plus/icons-vue'
|
import { Delete } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
// 定义组件属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
deviceInfo: {
|
deviceInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
default: () => ({
|
default: () => ({
|
||||||
id: '',
|
id: '', // 设备ID
|
||||||
name: '',
|
devicename: '', // 设备名称
|
||||||
type: '',
|
devicetype: '', // 设备类型
|
||||||
address: '',
|
location: '', // 设备位置
|
||||||
status: 'normal',
|
devicestatus: 0, // 设备状态:0-待激活,1-在线,2-离线,3-禁用
|
||||||
statusText: '正常'
|
statusText: '待激活' // 状态文本
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 定义事件
|
||||||
const emit = defineEmits(['action'])
|
const emit = defineEmits(['action'])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备状态文本
|
||||||
|
* @param {number} status - 设备状态码
|
||||||
|
* @returns {string} 状态文本
|
||||||
|
*/
|
||||||
|
const getStatusText = (status) => {
|
||||||
|
switch (status) {
|
||||||
|
case 0:
|
||||||
|
return '待激活'
|
||||||
|
case 1:
|
||||||
|
return '在线'
|
||||||
|
case 2:
|
||||||
|
return '离线'
|
||||||
|
case 3:
|
||||||
|
return '禁用'
|
||||||
|
default:
|
||||||
|
return '未知'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备状态对应的样式类名
|
||||||
|
* @param {number} status - 设备状态码
|
||||||
|
* @returns {string} 样式类名
|
||||||
|
*/
|
||||||
|
const getStatusClass = (status) => {
|
||||||
|
switch (status) {
|
||||||
|
case 0:
|
||||||
|
return 'warning' // 待激活状态 - 黄色
|
||||||
|
case 1:
|
||||||
|
return 'normal' // 在线状态 - 绿色
|
||||||
|
case 2:
|
||||||
|
return 'error' // 离线状态 - 灰色
|
||||||
|
case 3:
|
||||||
|
return 'disabled' // 禁用状态 - 红色
|
||||||
|
default:
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理设备操作事件
|
||||||
|
* @param {string} action - 操作类型
|
||||||
|
*/
|
||||||
const handleAction = (action) => {
|
const handleAction = (action) => {
|
||||||
if (action === 'data') {
|
if (action === 'data') {
|
||||||
// 打开心电数据组件
|
// 打开心电数据组件
|
||||||
@ -111,13 +171,26 @@ const handleAction = (action) => {
|
|||||||
} else {
|
} else {
|
||||||
emit('action', {
|
emit('action', {
|
||||||
action,
|
action,
|
||||||
deviceId: props.deviceInfo.id
|
deviceId: props.deviceInfo.devicecode
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设备类型映射
|
||||||
|
const getDeviceTypeName = (type: string) => {
|
||||||
|
const typeMap: Record<string, string> = {
|
||||||
|
'ECG': '心电设备',
|
||||||
|
'BP': '血压设备',
|
||||||
|
'SPO2': '血氧设备',
|
||||||
|
'TEMP': '体温设备',
|
||||||
|
'WEIGHT': '体重设备'
|
||||||
|
}
|
||||||
|
return typeMap[type] || type
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
/* 设备卡片基础样式 */
|
||||||
.device-card {
|
.device-card {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
@ -128,70 +201,94 @@ const handleAction = (action) => {
|
|||||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 卡片悬停效果 */
|
||||||
.device-card:hover {
|
.device-card:hover {
|
||||||
transform: translateY(-5px);
|
transform: translateY(-5px);
|
||||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 卡片内容布局 */
|
||||||
.card-content {
|
.card-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 15px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 设备信息区域样式 */
|
||||||
.device-info {
|
.device-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 名称区域样式 */
|
||||||
.name-section {
|
.name-section {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0; /* 防止子元素溢出 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 设备名称样式 */
|
||||||
.device-name {
|
.device-name {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
transition: color 0.3s ease;
|
transition: color 0.3s ease;
|
||||||
|
white-space: nowrap; /* 防止文字换行 */
|
||||||
|
overflow: hidden; /* 超出部分隐藏 */
|
||||||
|
text-overflow: ellipsis; /* 显示省略号 */
|
||||||
|
max-width: 150px; /* 最大宽度 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 设备名称悬停效果 */
|
||||||
.device-card:hover .device-name {
|
.device-card:hover .device-name {
|
||||||
color: #409EFF;
|
color: #409EFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 设备状态基础样式 */
|
||||||
.device-status {
|
.device-status {
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
white-space: nowrap; /* 防止文字换行 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 在线状态样式 */
|
||||||
.device-status.normal {
|
.device-status.normal {
|
||||||
background-color: #67C23A;
|
background-color: #67C23A;
|
||||||
color: white;
|
color: white;
|
||||||
box-shadow: 0 2px 8px rgba(103, 194, 58, 0.3);
|
box-shadow: 0 2px 8px rgba(103, 194, 58, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 待激活状态样式 */
|
||||||
.device-status.warning {
|
.device-status.warning {
|
||||||
background-color: #F7BA2A;
|
background-color: #F7BA2A;
|
||||||
color: white;
|
color: white;
|
||||||
box-shadow: 0 2px 8px rgba(247, 186, 42, 0.3);
|
box-shadow: 0 2px 8px rgba(247, 186, 42, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 离线状态样式 */
|
||||||
.device-status.error {
|
.device-status.error {
|
||||||
background-color: #909399;
|
background-color: #909399;
|
||||||
color: white;
|
color: white;
|
||||||
box-shadow: 0 2px 8px rgba(144, 147, 153, 0.3);
|
box-shadow: 0 2px 8px rgba(144, 147, 153, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 禁用状态样式 */
|
||||||
|
.device-status.disabled {
|
||||||
|
background-color: #F56C6C;
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 2px 8px rgba(245, 108, 108, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 设备详情区域样式 */
|
||||||
.device-details {
|
.device-details {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -199,6 +296,7 @@ const handleAction = (action) => {
|
|||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 详情项样式 */
|
||||||
.detail-item {
|
.detail-item {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@ -206,128 +304,91 @@ const handleAction = (action) => {
|
|||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 详情项悬停效果 */
|
||||||
.device-card:hover .detail-item {
|
.device-card:hover .detail-item {
|
||||||
transform: translateX(5px);
|
transform: translateX(5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 标签样式 */
|
||||||
.label {
|
.label {
|
||||||
color: #909399;
|
color: #909399;
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 值样式 */
|
||||||
.value {
|
.value {
|
||||||
color: #303133;
|
color: #303133;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 分隔线样式 */
|
||||||
.divider {
|
.divider {
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background: linear-gradient(to right, transparent, #b7b7bb, transparent);
|
background: linear-gradient(to right, transparent, #DCDFE6, transparent);
|
||||||
margin: 5px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 操作按钮区域样式 */
|
||||||
.action-buttons {
|
.action-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 5px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-buttons .el-button {
|
/* 按钮图标样式 */
|
||||||
flex: 1;
|
.el-icon {
|
||||||
transition: all 0.3s ease;
|
margin-right: 4px;
|
||||||
}
|
|
||||||
|
|
||||||
.action-buttons .el-button:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-btn {
|
|
||||||
width: 24px !important;
|
|
||||||
height: 24px !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
background-color: #f38787 !important;
|
|
||||||
border: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-btn:hover {
|
|
||||||
background-color: #f38787 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-btn .el-icon {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-btn {
|
|
||||||
padding: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
height: auto;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
color: #409EFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-btn:hover {
|
|
||||||
color: #79bbff;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.data-btn {
|
|
||||||
padding: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
height: auto;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
color: #67C23A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.data-btn:hover {
|
|
||||||
color: #71d440;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 在线状态卡片样式 */
|
/* 在线状态卡片样式 */
|
||||||
.device-card[data-status="normal"] {
|
.device-card[data-status="1"] {
|
||||||
background: linear-gradient(145deg, #e6f3ff, #fafafa);
|
background: linear-gradient(145deg, #e6f3ff, #fafafa);
|
||||||
border: 1px solid rgba(64, 158, 255, 0.2);
|
border: 1px solid rgba(64, 158, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 在线状态卡片悬停效果 */
|
/* 在线状态卡片悬停效果 */
|
||||||
.device-card[data-status="normal"]:hover {
|
.device-card[data-status="1"]:hover {
|
||||||
background: linear-gradient(145deg, #d9edff, #fafafa);
|
background: linear-gradient(145deg, #d9edff, #fafafa);
|
||||||
box-shadow: 0 8px 30px rgba(64, 158, 255, 0.15);
|
box-shadow: 0 8px 30px rgba(64, 158, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 待激活状态卡片样式 */
|
/* 待激活状态卡片样式 */
|
||||||
.device-card[data-status="warning"] {
|
.device-card[data-status="0"] {
|
||||||
/* 淡粉色渐变背景,从淡粉色过渡到纯白色 */
|
|
||||||
background: linear-gradient(145deg, #f7ecec, #fafafa);
|
background: linear-gradient(145deg, #f7ecec, #fafafa);
|
||||||
/* 淡粉色边框 */
|
|
||||||
border: 1px solid rgba(247, 186, 42, 0.2);
|
border: 1px solid rgba(247, 186, 42, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 待激活状态卡片悬停效果 */
|
/* 待激活状态卡片悬停效果 */
|
||||||
.device-card[data-status="warning"]:hover {
|
.device-card[data-status="0"]:hover {
|
||||||
/* 悬停时加深粉色渐变效果 */
|
|
||||||
background: linear-gradient(145deg, #f7ecec, #fafafa);
|
background: linear-gradient(145deg, #f7ecec, #fafafa);
|
||||||
/* 添加淡粉色阴影效果 */
|
|
||||||
box-shadow: 0 8px 30px rgba(247, 186, 42, 0.15);
|
box-shadow: 0 8px 30px rgba(247, 186, 42, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 离线状态卡片样式 */
|
/* 离线状态卡片样式 */
|
||||||
.device-card[data-status="error"] {
|
.device-card[data-status="2"] {
|
||||||
background: linear-gradient(145deg, #e4e4e4, #fafafa);
|
background: linear-gradient(145deg, #e4e4e4, #fafafa);
|
||||||
border: 1px solid rgba(247, 186, 42, 0.2);
|
border: 1px solid rgba(247, 186, 42, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 离线状态卡片悬停效果 */
|
/* 离线状态卡片悬停效果 */
|
||||||
.device-card[data-status="error"]:hover {
|
.device-card[data-status="2"]:hover {
|
||||||
background: linear-gradient(145deg, #e4e4e4, #fafafa);
|
background: linear-gradient(145deg, #e4e4e4, #fafafa);
|
||||||
box-shadow: 0 8px 30px rgba(247, 186, 42, 0.15);
|
box-shadow: 0 8px 30px rgba(247, 186, 42, 0.15);
|
||||||
}
|
}
|
||||||
|
/* 禁用状态卡片样式 */
|
||||||
|
.device-card[data-status="3"] {
|
||||||
|
background: linear-gradient(145deg, #f09393, #fafafa);
|
||||||
|
border: 1px solid rgba(245, 108, 108, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 禁用状态卡片悬停效果 */
|
||||||
|
.device-card[data-status="3"]:hover {
|
||||||
|
background: linear-gradient(145deg, #f09393, #fafafa);
|
||||||
|
box-shadow: 0 8px 30px rgba(245, 108, 108, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
>
|
>
|
||||||
<el-form-item label="设备名称" prop="name">
|
<el-form-item label="设备名称" prop="name">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.name"
|
v-model="queryParams.devicename"
|
||||||
placeholder="请输入设备名称"
|
placeholder="请输入设备名称"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
@ -19,13 +19,13 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备状态" prop="status">
|
<el-form-item label="设备状态" prop="status">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="queryParams.status"
|
v-model="queryParams.devicestatus"
|
||||||
placeholder="请选择设备状态"
|
placeholder="请选择设备状态"
|
||||||
clearable
|
clearable
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.IOT_DEVICE_STATUS)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
@ -35,13 +35,13 @@
|
|||||||
<!-- 设备类型 -->
|
<!-- 设备类型 -->
|
||||||
<el-form-item label="设备类型" prop="type">
|
<el-form-item label="设备类型" prop="type">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="queryParams.type"
|
v-model="queryParams.devicetype"
|
||||||
placeholder="请选择设备类型"
|
placeholder="请选择设备类型"
|
||||||
clearable
|
clearable
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
v-for="dict in getStrDictOptions(DICT_TYPE.IOT_DEVICE_TYPE)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
@ -72,6 +72,13 @@
|
|||||||
@action="handleDeviceAction"
|
@action="handleDeviceAction"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="handleQuery"
|
||||||
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 设备表单 -->
|
<!-- 设备表单 -->
|
||||||
@ -84,61 +91,40 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElButton } from 'element-plus'
|
import { ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElButton } from 'element-plus'
|
||||||
import { getIntDictOptions } from '@/utils/dict'
|
import { getIntDictOptions,getStrDictOptions } from '@/utils/dict'
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
import DeviceCard from '../devices/devices_cards.vue'
|
import DeviceCard from '../devices/devices_cards.vue'
|
||||||
import DeviceForm from './DevFrom.vue'
|
import DeviceForm from './DevFrom.vue'
|
||||||
import DetailsForm from './DetailsForm.vue'
|
import DetailsForm from './DetailsForm.vue'
|
||||||
|
import { DeviceApi } from '@/api/device'
|
||||||
|
import { getUserProfile } from '@/api/system/user/profile'
|
||||||
import ECG_datas from './Device_Data_Components/ECG_datas.vue'
|
import ECG_datas from './Device_Data_Components/ECG_datas.vue'
|
||||||
|
|
||||||
// 查询参数
|
// 查询参数
|
||||||
interface QueryParams {
|
interface QueryParams {
|
||||||
name: string
|
devicename: string
|
||||||
status: number | undefined
|
devicestatus: number | undefined
|
||||||
type: number | undefined
|
devicetype: string | undefined
|
||||||
|
pageNo: number
|
||||||
|
pageSize: number
|
||||||
|
orgid: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryParams = reactive<QueryParams>({
|
const queryParams = reactive<QueryParams>({
|
||||||
name: '',
|
devicename: '',
|
||||||
status: undefined,
|
devicestatus: undefined,
|
||||||
type: undefined
|
devicetype: '',
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
orgid: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 总数据量
|
||||||
|
const total = ref(0)
|
||||||
|
// 用户信息
|
||||||
|
const userProfile = ref()
|
||||||
// 设备列表数据
|
// 设备列表数据
|
||||||
const deviceList = ref([
|
const deviceList = ref([])
|
||||||
{
|
|
||||||
id: 'ECG001',
|
|
||||||
name: '心电设备',
|
|
||||||
type: '心电设备',
|
|
||||||
address: '北京市/市辖区/西城区',
|
|
||||||
status: 'normal',
|
|
||||||
statusText: '在线'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Blood001',
|
|
||||||
name: '血压仪',
|
|
||||||
type: '血压仪',
|
|
||||||
address: '天津市/市辖区/西青区/精武镇',
|
|
||||||
status: 'normal',
|
|
||||||
statusText: '在线'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Glucose001',
|
|
||||||
name: '血糖仪',
|
|
||||||
type: '血糖仪',
|
|
||||||
address: '河北省/廊坊市/安次区',
|
|
||||||
status: 'warning',
|
|
||||||
statusText: '待激活'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Oxygen001',
|
|
||||||
name: '血氧仪',
|
|
||||||
type: '血氧仪',
|
|
||||||
address: '四川省/绵阳市/涪城区',
|
|
||||||
status: 'error',
|
|
||||||
statusText: '离线'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
// 查询表单引用
|
// 查询表单引用
|
||||||
const queryFormRef = ref()
|
const queryFormRef = ref()
|
||||||
@ -150,14 +136,25 @@ const detailsFormRef = ref()
|
|||||||
const ecgDataRef = ref()
|
const ecgDataRef = ref()
|
||||||
|
|
||||||
// 查询方法
|
// 查询方法
|
||||||
const handleQuery = () => {
|
const handleQuery = async () => {
|
||||||
// TODO: 实现查询逻辑
|
try {
|
||||||
console.log('查询参数:', queryParams)
|
//指定查询当前登录用户的机构ID
|
||||||
|
queryParams.orgid = userProfile.value.dept.id
|
||||||
|
const res = await DeviceApi.getDevicePage(queryParams)
|
||||||
|
deviceList.value = res.list
|
||||||
|
total.value = res.total
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取设备列表失败:', error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置查询
|
// 重置查询
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryFormRef.value?.resetFields()
|
queryFormRef.value?.resetFields()
|
||||||
|
queryParams.devicename = ''
|
||||||
|
queryParams.devicestatus = undefined
|
||||||
|
queryParams.devicetype = ''
|
||||||
|
queryParams.pageNo = 1
|
||||||
handleQuery()
|
handleQuery()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +165,7 @@ const openForm = (type: string) => {
|
|||||||
|
|
||||||
// 处理设备操作
|
// 处理设备操作
|
||||||
const handleDeviceAction = (action: any) => {
|
const handleDeviceAction = (action: any) => {
|
||||||
|
console.log('设备操作:', action)
|
||||||
if (action.action === 'details') {
|
if (action.action === 'details') {
|
||||||
// 打开表单并加载设备数据
|
// 打开表单并加载设备数据
|
||||||
detailsFormRef.value?.open(action.deviceId)
|
detailsFormRef.value?.open(action.deviceId)
|
||||||
@ -180,9 +178,10 @@ const handleDeviceAction = (action: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 页面加载时获取数据
|
// 页面加载时获取数据
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
// TODO: 实现获取设备列表数据
|
// 首先获取用户信息
|
||||||
// 这里可以添加实际的API调用
|
userProfile.value = await getUserProfile()
|
||||||
|
handleQuery()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -193,4 +192,10 @@ onMounted(() => {
|
|||||||
gap: 20px;
|
gap: 20px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagination-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user