16 changed files with 731 additions and 221 deletions
@ -0,0 +1,181 @@ |
|||||||
|
<template> |
||||||
|
<div class="info-card"> |
||||||
|
<div class="hd"> |
||||||
|
<span class="title">{{ title }}</span> |
||||||
|
<span class="detail-btn">查看详情</span> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 键值对信息块 --> |
||||||
|
<div v-if="kvColumns.length" class="kv"> |
||||||
|
<div class="kv-row" v-for="(col, idx) in kvColumns" :key="idx"> |
||||||
|
<div class="kv-label">{{ col.label }}:</div> |
||||||
|
<div class="kv-value">{{ safeGet(kvData, col.key) }}</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 状态行(可选) --> |
||||||
|
<!-- <div v-if="status" class="status-row"> |
||||||
|
<span class="status-label">设备状态:</span> |
||||||
|
<span class="status-value" :style="{ color }">{{ status }}</span> |
||||||
|
</div> --> |
||||||
|
|
||||||
|
<!-- 原生表格(报警信息记录等) --> |
||||||
|
<div v-if="tableColumns.length && tableData.length" class="table-wrap"> |
||||||
|
<div class="table-title">{{ tableTitle }}</div> |
||||||
|
<table class="native-table"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th v-for="(c, i) in tableColumns" :key="i" :style="{ width: c.width ? c.width + 'px' : 'auto' }">{{ c.label }}</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr v-for="(row, r) in tableData" :key="r"> |
||||||
|
<td v-for="(c, i) in tableColumns" :key="i">{{ safeGet(row, c.key) }}</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
name: 'InfoCard', |
||||||
|
props: { |
||||||
|
title: { type: String, default: '设备信息' }, |
||||||
|
color: { type: String, default: '#29a9fd' }, |
||||||
|
status: { type: String, default: '' }, |
||||||
|
// 键值对:columns + data |
||||||
|
kvColumns: { type: Array, default: () => [] }, // [{ label, key }] |
||||||
|
kvData: { type: Object, default: () => ({}) }, |
||||||
|
// 表格:columns + data |
||||||
|
tableTitle: { type: String, default: '报警信息记录' }, |
||||||
|
tableColumns: { type: Array, default: () => [] }, // [{ label, key, width? }] |
||||||
|
tableData: { type: Array, default: () => [] } |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
safeGet(obj, path) { |
||||||
|
if (!obj || !path) return '-'; |
||||||
|
const segs = path.split('.'); |
||||||
|
let cur = obj; |
||||||
|
for (let i = 0; i < segs.length; i++) { |
||||||
|
if (cur == null) return '-'; |
||||||
|
cur = cur[segs[i]]; |
||||||
|
} |
||||||
|
if (cur === undefined || cur === null || cur === '') return '-'; |
||||||
|
return cur; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.info-card { |
||||||
|
display: inline-block; |
||||||
|
min-width: 320px; |
||||||
|
max-width: 480px; |
||||||
|
border-radius: 8px; |
||||||
|
background: rgba(245, 248, 253, 0.98); |
||||||
|
border: 1px solid rgba(255, 255, 255, 1); |
||||||
|
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25); |
||||||
|
padding: 16px; |
||||||
|
} |
||||||
|
.hd { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
margin-bottom: 8px; |
||||||
|
} |
||||||
|
.title { |
||||||
|
height: 20px; |
||||||
|
font-family: PingFang SC, PingFang SC; |
||||||
|
font-weight: 500; |
||||||
|
font-size: 14px; |
||||||
|
color: #000000; |
||||||
|
text-align: left; |
||||||
|
font-style: normal; |
||||||
|
text-transform: none; |
||||||
|
} |
||||||
|
.detail-btn { |
||||||
|
font-family: PingFang SC, PingFang SC; |
||||||
|
font-weight: 400; |
||||||
|
font-size: 14px; |
||||||
|
color: #0d79e8; |
||||||
|
text-align: left; |
||||||
|
font-style: normal; |
||||||
|
text-transform: none; |
||||||
|
} |
||||||
|
.kv { |
||||||
|
margin-top: 6px; |
||||||
|
} |
||||||
|
.kv-row { |
||||||
|
display: flex; |
||||||
|
align-items: baseline; |
||||||
|
padding: 6px 0; |
||||||
|
justify-content: space-between; |
||||||
|
} |
||||||
|
.kv-label { |
||||||
|
font-family: PingFang SC, PingFang SC; |
||||||
|
font-weight: 400; |
||||||
|
font-size: 14px; |
||||||
|
color: #999999; |
||||||
|
text-align: left; |
||||||
|
font-style: normal; |
||||||
|
text-transform: none; |
||||||
|
} |
||||||
|
.kv-value { |
||||||
|
font-family: PingFang SC, PingFang SC; |
||||||
|
font-weight: 400; |
||||||
|
font-size: 14px; |
||||||
|
color: #333333; |
||||||
|
text-align: left; |
||||||
|
font-style: normal; |
||||||
|
text-transform: none; |
||||||
|
} |
||||||
|
|
||||||
|
.status-row { |
||||||
|
margin: 8px 0 4px; |
||||||
|
font-size: 18px; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.status-label { |
||||||
|
color: #7a869a; |
||||||
|
font-size: 14px; |
||||||
|
font-weight: 400; |
||||||
|
margin-right: 8px; |
||||||
|
} |
||||||
|
.status-value { |
||||||
|
font-size: 18px; |
||||||
|
} |
||||||
|
|
||||||
|
.table-wrap { |
||||||
|
margin-top: 10px; |
||||||
|
} |
||||||
|
.table-title { |
||||||
|
font-size: 14px; |
||||||
|
color: #2b2f36; |
||||||
|
font-weight: 600; |
||||||
|
margin-bottom: 6px; |
||||||
|
} |
||||||
|
.native-table { |
||||||
|
width: 100%; |
||||||
|
border-collapse: collapse; |
||||||
|
background: #fff; |
||||||
|
} |
||||||
|
.native-table th { |
||||||
|
text-align: left; |
||||||
|
background: #f4f6f8; |
||||||
|
color: #6b778c; |
||||||
|
font-weight: 600; |
||||||
|
font-size: 13px; |
||||||
|
padding: 8px 10px; |
||||||
|
} |
||||||
|
.native-table td { |
||||||
|
color: #2b2f36; |
||||||
|
font-size: 13px; |
||||||
|
padding: 10px; |
||||||
|
} |
||||||
|
.native-table tr + tr td { |
||||||
|
border-top: 1px solid #edf0f3; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,45 @@ |
|||||||
|
// 设备列表表格列
|
||||||
|
export const deviceTableColumns = [ |
||||||
|
{ label: '设备ID', key: 'name', width: 60 }, |
||||||
|
{ label: '当前区域', key: 'area', width: 60 }, |
||||||
|
{ label: '工作人员', key: 'team', width: 60 }, |
||||||
|
{ label: '今日工作量', key: 'dayWork', width: 60 }, |
||||||
|
{ label: '今日运行时长(h)', key: 'runtime' } |
||||||
|
]; |
||||||
|
// 设备弹窗表格列
|
||||||
|
export const devicePopupColumns = [ |
||||||
|
{ label: '设备编号', key: 'name' }, |
||||||
|
{ label: '设备类型', key: 'type' }, |
||||||
|
{ label: '设备位置', key: 'position' }, |
||||||
|
{ label: '操作人员', key: 'team' }, |
||||||
|
{ label: '今日安装量', key: 'dayWork' }, |
||||||
|
{ label: '设备状态', key: 'status' }, |
||||||
|
{ label: '运行时长(h)', key: 'runtime' } |
||||||
|
]; |
||||||
|
export const areaPopupColumns = [ |
||||||
|
{ label: '工区编号', key: 'name' }, |
||||||
|
{ label: '工区状态', key: 'name' }, |
||||||
|
{ label: '桩条安装数量', key: 'pileCount' }, |
||||||
|
{ label: '组件安装数量', key: 'moduleCount' } |
||||||
|
]; |
||||||
|
|
||||||
|
export const alarmTableColumns = [ |
||||||
|
{ label: '预警类别', key: 'code' }, |
||||||
|
{ label: '设备编码', key: 'device' }, |
||||||
|
{ label: '报警内容', key: 'desc' }, |
||||||
|
{ label: '报警时间', key: 'time' } |
||||||
|
]; |
||||||
|
export const STATUS_STYLE = { |
||||||
|
施工中: { stroke: 'rgba(19, 126, 233, 1)', fill: 'rgba(19, 126, 233, 0.4)' }, |
||||||
|
已施工: { stroke: 'rgba(26, 213, 154, 1)', fill: 'rgba(26, 213, 154, 0.4)' }, |
||||||
|
未施工: { stroke: 'rgba(255, 188, 72, 1)', fill: 'rgba(255, 188, 72, 0.4)' }, |
||||||
|
故障: { stroke: 'rgba(219,77,77,1)', fill: 'rgba(219,77,77,0.4)' }, |
||||||
|
运行中: { stroke: 'rgba(19,194,194,1)', fill: 'rgba(19,194,194,0.4)' }, |
||||||
|
停机: { stroke: 'rgba(243,180,71,1)', fill: 'rgba(243,180,71,0.4)' } |
||||||
|
}; |
||||||
|
export const isDevice = (item) => { |
||||||
|
return ['故障', '运行中', '停机'].includes(item.status); |
||||||
|
}; |
||||||
|
export const isArea = (item) => { |
||||||
|
return ['施工中', '已施工', '未施工'].includes(item.status); |
||||||
|
}; |
||||||
Loading…
Reference in new issue