|
86 | 86 | />
|
87 | 87 | </el-select>
|
88 | 88 | </el-form-item>
|
| 89 | + <el-form-item class="float-right !mr-0 !mb-0"> |
| 90 | + <el-button-group> |
| 91 | + <el-button :type="viewMode === 'card' ? 'primary' : 'default'" @click="viewMode = 'card'"> |
| 92 | + <Icon icon="ep:grid" /> |
| 93 | + </el-button> |
| 94 | + <el-button :type="viewMode === 'list' ? 'primary' : 'default'" @click="viewMode = 'list'"> |
| 95 | + <Icon icon="ep:list" /> |
| 96 | + </el-button> |
| 97 | + </el-button-group> |
| 98 | + </el-form-item> |
89 | 99 | <el-form-item>
|
90 | 100 | <el-button @click="handleQuery">
|
91 | 101 | <Icon icon="ep:search" class="mr-5px" />
|
|
137 | 147 |
|
138 | 148 | <!-- 列表 -->
|
139 | 149 | <ContentWrap>
|
| 150 | + <template v-if="viewMode === 'card'"> |
| 151 | + <el-row :gutter="16"> |
| 152 | + <el-col v-for="item in list" :key="item.id" :xs="24" :sm="12" :md="12" :lg="6" class="mb-4"> |
| 153 | + <el-card class="h-full transition-colors" :body-style="{ padding: '0' }"> |
| 154 | + <div class="p-4"> |
| 155 | + <!-- 标题区域 --> |
| 156 | + <div class="flex items-center mb-3"> |
| 157 | + <div class="mr-2.5 flex items-center"> |
| 158 | + <el-image :src="defaultIconUrl" class="w-[18px] h-[18px]" /> |
| 159 | + </div> |
| 160 | + <div class="text-[16px] font-600">{{ item.deviceName }}</div> |
| 161 | + </div> |
| 162 | + |
| 163 | + <!-- 信息区域 --> |
| 164 | + <div class="flex items-center text-[14px]"> |
| 165 | + <div class="flex-1"> |
| 166 | + <div class="mb-2.5 last:mb-0"> |
| 167 | + <span class="text-[#717c8e] mr-2.5">所属产品</span> |
| 168 | + <span class="text-[#0070ff]">{{ |
| 169 | + products.find((p) => p.id === item.productId)?.name |
| 170 | + }}</span> |
| 171 | + </div> |
| 172 | + <div class="mb-2.5 last:mb-0"> |
| 173 | + <span class="text-[#717c8e] mr-2.5">设备类型</span> |
| 174 | + <dict-tag :type="DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE" :value="item.deviceType" /> |
| 175 | + </div> |
| 176 | + <div class="mb-2.5 last:mb-0"> |
| 177 | + <span class="text-[#717c8e] mr-2.5">DeviceKey</span> |
| 178 | + <span class="text-[#0b1d30]">{{ item.deviceKey }}</span> |
| 179 | + </div> |
| 180 | + </div> |
| 181 | + <div class="w-[100px] h-[100px]"> |
| 182 | + <el-image :src="defaultPicUrl" class="w-full h-full" /> |
| 183 | + </div> |
| 184 | + </div> |
| 185 | + |
| 186 | + <!-- 分隔线 --> |
| 187 | + <el-divider class="!my-3" /> |
| 188 | + |
| 189 | + <!-- 按钮组 --> |
| 190 | + <div class="flex items-center px-0"> |
| 191 | + <el-button |
| 192 | + class="flex-1 !px-2 !h-[32px] text-[13px]" |
| 193 | + type="primary" |
| 194 | + plain |
| 195 | + @click="openForm('update', item.id)" |
| 196 | + v-hasPermi="['iot:device:update']" |
| 197 | + > |
| 198 | + <Icon icon="ep:edit-pen" class="mr-1" /> |
| 199 | + 编辑 |
| 200 | + </el-button> |
| 201 | + <el-button |
| 202 | + class="flex-1 !px-2 !h-[32px] !ml-[10px] text-[13px]" |
| 203 | + type="warning" |
| 204 | + plain |
| 205 | + @click="openDetail(item.id)" |
| 206 | + > |
| 207 | + <Icon icon="ep:view" class="mr-1" /> |
| 208 | + 详情 |
| 209 | + </el-button> |
| 210 | + <el-button |
| 211 | + class="flex-1 !px-2 !h-[32px] !ml-[10px] text-[13px]" |
| 212 | + type="info" |
| 213 | + plain |
| 214 | + @click="openLog(item.id)" |
| 215 | + > |
| 216 | + <Icon icon="ep:tickets" class="mr-1" /> |
| 217 | + 日志 |
| 218 | + </el-button> |
| 219 | + <div class="mx-[10px] h-[20px] w-[1px] bg-[#dcdfe6]"></div> |
| 220 | + <el-button |
| 221 | + class="!px-2 !h-[32px] text-[13px]" |
| 222 | + type="danger" |
| 223 | + plain |
| 224 | + @click="handleDelete(item.id)" |
| 225 | + v-hasPermi="['iot:device:delete']" |
| 226 | + > |
| 227 | + <Icon icon="ep:delete" /> |
| 228 | + </el-button> |
| 229 | + </div> |
| 230 | + </div> |
| 231 | + </el-card> |
| 232 | + </el-col> |
| 233 | + </el-row> |
| 234 | + </template> |
| 235 | + |
| 236 | + <!-- 列表视图 --> |
140 | 237 | <el-table
|
| 238 | + v-else |
141 | 239 | v-loading="loading"
|
142 | 240 | :data="list"
|
143 | 241 | :stripe="true"
|
|
192 | 290 | >
|
193 | 291 | 查看
|
194 | 292 | </el-button>
|
| 293 | + <el-button link type="primary" @click="openLog(scope.row.id)"> 日志 </el-button> |
195 | 294 | <el-button
|
196 | 295 | link
|
197 | 296 | type="primary"
|
|
211 | 310 | </template>
|
212 | 311 | </el-table-column>
|
213 | 312 | </el-table>
|
| 313 | + |
214 | 314 | <!-- 分页 -->
|
215 | 315 | <Pagination
|
216 | 316 | :total="total"
|
@@ -260,6 +360,9 @@ const exportLoading = ref(false) // 导出加载状态
|
260 | 360 | const products = ref<ProductVO[]>([]) // 产品列表
|
261 | 361 | const deviceGroups = ref<DeviceGroupVO[]>([]) // 设备分组列表
|
262 | 362 | const selectedIds = ref<number[]>([]) // 选中的设备编号数组
|
| 363 | +const viewMode = ref<'card' | 'list'>('card') // 视图模式状态 |
| 364 | +const defaultPicUrl = ref('/src/assets/imgs/iot/device.png') // 默认设备图片 |
| 365 | +const defaultIconUrl = ref('/src/assets/svgs/iot/card-fill.svg') // 默认设备图标 |
263 | 366 |
|
264 | 367 | /** 查询列表 */
|
265 | 368 | const getList = async () => {
|
@@ -349,6 +452,11 @@ const openGroupForm = () => {
|
349 | 452 | groupFormRef.value.open(selectedIds.value)
|
350 | 453 | }
|
351 | 454 |
|
| 455 | +/** 打开日志 */ |
| 456 | +const openLog = (id: number) => { |
| 457 | + push({ name: 'IoTDeviceDetail', params: { id }, query: { tab: 'log' } }) |
| 458 | +} |
| 459 | +
|
352 | 460 | /** 初始化 **/
|
353 | 461 | onMounted(async () => {
|
354 | 462 | getList()
|
|
0 commit comments