Browse Source

fix: 固件升级

master
taqi be 1 month ago
parent
commit
c778b5e16b
  1. 2
      components.d.ts
  2. 34
      src/pages/deviceInfo/components/BasicInfo.vue
  3. 1
      src/pages/layout.vue
  4. 5
      src/pages/ota/firmware/utils.ts
  5. 4
      src/pages/ota/upgradeTask/components/create-task-dlg.vue
  6. 65
      src/pages/ota/upgradeTask/components/details-drawer.vue
  7. 301
      src/pages/ota/upgradeTask/index.vue
  8. 150
      src/pages/ota/upgradeTask/utils.ts
  9. 5
      src/pages/socket_server/SocketServer.ts

2
components.d.ts vendored

@ -21,6 +21,7 @@ declare module 'vue' { @@ -21,6 +21,7 @@ declare module 'vue' {
EdfsTable: typeof import('./src/components/dashboard/Edfs-table/index.vue')['default']
EdfsWrap: typeof import('./src/components/dashboard/Edfs-wrap.vue')['default']
Editor: typeof import('./src/components/dashboard/Editor/src/Editor.vue')['default']
ElAutoResizer: typeof import('element-plus/es')['ElAutoResizer']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElButton: typeof import('element-plus/es')['ElButton']
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
@ -63,6 +64,7 @@ declare module 'vue' { @@ -63,6 +64,7 @@ declare module 'vue' {
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTableV2: typeof import('element-plus/es')['ElTableV2']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']

34
src/pages/deviceInfo/components/BasicInfo.vue

@ -75,12 +75,13 @@ @@ -75,12 +75,13 @@
</div>-->
<div class="from-row">
<div class="label">当前固件:</div>
<number-input
class="input"
:disabled="true"
v-model="params.currentFirmwareId"
placeholder="设备暂无固件"
/>
<!-- {{ params.currentFirmwareId }}
{{ firmwareList }} -->
<div class="dis">
{{
firmwareList.find(item => item.id == params.currentFirmwareId)?.name ?? ''
}}
</div>
</div>
<div class="from-row">
<div class="label">设备成本:</div>
@ -266,6 +267,15 @@ async function loadFirmwareList(value: boolean) { @@ -266,6 +267,15 @@ async function loadFirmwareList(value: boolean) {
}
}
watch(
() => params.value.categoryId,
val => {
if (val) {
loadFirmwareList(true)
}
}
)
function onFirmwareUpgrade() {
if (!props.info) return
@ -309,6 +319,18 @@ onMounted(() => { @@ -309,6 +319,18 @@ onMounted(() => {
box-sizing: border-box;
min-height: 32px;
align-items: center;
.dis {
flex: 1;
box-shadow: 0 0 0 1px var(--el-disabled-border-color) inset;
background-color: var(--el-fill-color-light);
color: var(--el-text-color-placeholder);
line-height: 24px;
min-height: 32px;
cursor: not-allowed;
padding: 4px 12px;
box-sizing: border-box;
border-radius: var(--el-border-radius-base);
}
.label {
white-space: nowrap;
width: 70px;

1
src/pages/layout.vue

@ -106,7 +106,6 @@ import logoIcon from '@/assets/image/dashboard/common/icon_logo_pg.png' @@ -106,7 +106,6 @@ import logoIcon from '@/assets/image/dashboard/common/icon_logo_pg.png'
import { usePermissionStore } from '@/stores/permission'
import dayjs from 'dayjs'
import { useUserStore } from '@/stores/user'
import { isResError } from '@/hooks/useMessage'
import Avatar from './avatar.png'
import { useI18n } from 'vue-i18n'
import { useTheme } from '@/utils/useTheme'

5
src/pages/ota/firmware/utils.ts

@ -19,11 +19,6 @@ export const tableColumns = [ @@ -19,11 +19,6 @@ export const tableColumns = [
prop: 'createTime',
width: '20%',
},
{
label: '固件状态',
prop: 'status',
width: '10%',
},
{
label: '描述',
prop: 'description',

4
src/pages/ota/upgradeTask/components/create-task-dlg.vue

@ -74,8 +74,8 @@ @@ -74,8 +74,8 @@
<el-date-picker
v-model="formData.executeTime"
type="datetime"
value-format="YYYY-MM-DD HH:mm"
format="YYYY-MM-DD HH:mm"
value-format="x"
placeholder="Pick a day"
:disabled-date="disabledExecuteDate"
/>
@ -214,7 +214,7 @@ onMounted(async () => { @@ -214,7 +214,7 @@ onMounted(async () => {
}
if (route.query.deviceSn) {
formData.value.deviceSns = [route.query.deviceSn]
formData.value.deviceSns = typeof route.query.deviceSn === 'string' ? [route.query.deviceSn] : []
}
if (route.query.firmwareId) {
formData.value.firmwareId = Number(route.query.firmwareId)

65
src/pages/ota/upgradeTask/components/details-drawer.vue

@ -11,18 +11,21 @@ @@ -11,18 +11,21 @@
<div class="device-status">
<template v-for="(item, idx) in deviceDetails" :key="idx">
<div class="device-info">
<div class="title">站点名称{{ item.siteName }}</div>
<div class="title" :title="item.deviceSn">
设备SN: {{ item.deviceSn }}
</div>
<div class="body">
<div class="info">
<!-- <div class="item">
<span class="label">设备sn:</span><span class="val">{{}}</span>
</div> -->
<div class="item">
<span class="label">设备:</span><span>{{ item.deviceName }}</span>
</div>
<div class="item">
<span class="label">状态:</span
><span>{{ TaskStatus[item.node] ?? '未开始' }}</span>
<span class="label">状态:</span>
<span class="val">{{ TaskStatus[item.node] ?? '未开始' }}</span>
</div>
<div class="item" v-if="item.node === 1">
<span class="label">原因:</span><span>{{ item.reason }}</span>
<span class="label">原因:</span
><span class="val">{{ item.reason }}</span>
</div>
</div>
<div class="progress" v-if="!isEmpty(item.node)">
@ -115,10 +118,10 @@ async function loadData() { @@ -115,10 +118,10 @@ async function loadData() {
if (!isResError(res)) {
deviceDetails.value = Array.isArray(res.data) ? res.data : []
}
debugger
}
function updateData(data: any[]) {
console.log('object', data)
for (const d of data) {
const find = deviceDetails.value.find((item: any) => item.deviceSn == d.deviceSn)
if (find) {
@ -145,17 +148,11 @@ defineExpose({ @@ -145,17 +148,11 @@ defineExpose({
<style lang="scss" scoped>
.details-drawer {
font-size: 16px;
:deep(.el-overlay) {
// background-color: transparent !important;
}
// :deep(.el-drawer) {
// width: calc(100% - 280px) !important;
// width: 70%;
// }
:deep(.el-drawer__header) {
margin-bottom: 10px;
padding: 10px;
border-bottom: 1px solid #ccc;
color: var(--text-color);
border-bottom: 1px solid var(--pagination-border-color);
}
:deep(.el-drawer__body) {
padding: 20px;
@ -164,7 +161,6 @@ defineExpose({ @@ -164,7 +161,6 @@ defineExpose({
:deep(.el-drawer__title) {
font-family: Alibaba-PuHuiTi-M;
font-size: 16px;
color: #4d4d4d;
line-height: 24px;
font-weight: 500;
}
@ -179,12 +175,11 @@ defineExpose({ @@ -179,12 +175,11 @@ defineExpose({
column-gap: 20px;
row-gap: 24px;
.device-info {
width: 280px;
width: 350px;
height: 192px;
background: #ffffff;
border: 1px solid #e9e9e9;
box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.09);
border-radius: 4px;
border-radius: 8px;
overflow: hidden;
display: flex;
flex-direction: column;
box-sizing: border-box;
@ -193,25 +188,30 @@ defineExpose({ @@ -193,25 +188,30 @@ defineExpose({
align-items: center;
height: 48px;
width: 100%;
background-color: #f1f1f1;
background-color: var(--station-header-bg);
color: var(--station-header-text-color);
box-sizing: border-box;
font-family: Alibaba-PuHuiTi-M;
font-size: 16px;
color: #030303;
font-size: 18px;
font-weight: 500;
justify-content: space-between;
padding: 0 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.body {
padding: 10px;
display: flex;
column-gap: 14px;
column-gap: 16px;
background-color: var(--station-card-bg);
flex: 1;
.info {
width: 130px;
flex: 1;
}
.progress {
flex: 1;
width: 128px;
height: 128px;
.progress-content {
display: flex;
flex-direction: column;
@ -222,18 +222,17 @@ defineExpose({ @@ -222,18 +222,17 @@ defineExpose({
.item {
display: flex;
min-height: 32px;
column-gap: 8px;
align-items: center;
.label {
color: #6a6a6a;
font-size: 14px;
flex: 0.5;
color: var(--label-color);
}
span {
.val {
word-wrap: break-word;
word-break: break-all;
white-space: normal;
font-size: 14px;
flex: 1;
color: #3c3c3c;
color: var(--station-info-val-text);
}
}
}

301
src/pages/ota/upgradeTask/index.vue

@ -11,82 +11,22 @@ @@ -11,82 +11,22 @@
/>
</div>
</template>
<edfs-table
:data="dataList"
:highlight-current-row="true"
ref="tableRef"
row-class-name="row"
:page-size="pageSize"
:page-total="pageTotal"
class="table"
:current-page="pageIndex"
@pageCurrentChange="handleJump"
>
<template v-for="(col, idx) in tableColumns" :key="idx">
<el-table-column
v-if="col.prop === 'createTime'"
:label="col.label"
:prop="col.prop"
:min-width="col.width"
>
<template #default="scope">
{{ dayjs(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column
v-else-if="col.prop === 'status'"
:label="col.label"
:prop="col.prop"
:min-width="col.width"
>
<template #default="scope">
{{ taskStatusMap[scope.row.status] }}
</template>
</el-table-column>
<el-table-column
v-else-if="col.prop === 'executeTime'"
:label="col.label"
:prop="col.prop"
:min-width="col.width"
>
<template #default="scope">
{{ dayjs(scope.row.executeTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column
v-else-if="col.prop === 'deviceUpgradeDetail'"
:label="col.label"
:prop="col.prop"
:min-width="col.width"
>
<template #default="scope">
<div>
<div>升级中{{ scope.row.processingCount }}</div>
<div>失败数量: {{ scope.row.failCount }}</div>
<div>升级完成: {{ scope.row.successCount }}</div>
</div>
</template>
</el-table-column>
<el-table-column
v-else
:label="col.label"
:prop="col.prop"
:min-width="col.width"
<el-auto-resizer class="table">
<template #default="{ height, width }">
<el-table-v2
ref="mainTable"
scrollbar-always-on
:columns="tableCol"
:data="dataList"
v-if="visibilityTable"
:border="true"
:width="width"
:estimated-row-height="60"
:height="height"
row-key="id"
/>
</template>
<el-table-column label="操作" min-width="8%">
<template #default="scope">
<EdfsButton
type="primary"
link
v-if="scope.row.status === 1 || scope.row.status === 2"
inner-text="详情"
@click="onDetails(scope.row)"
/>
</template>
</el-table-column>
</edfs-table>
</el-auto-resizer>
</EdfsWrap>
<createTaskDlg :isShow="isShowDlg" @on-close="onClose" @on-save="onSave" />
<detailsDrawer
@ -104,7 +44,7 @@ import { @@ -104,7 +44,7 @@ import {
removeListener,
type SocketMsgListener,
} from '@/tools/event/socketEvent'
import { tableColumns, taskStatusMap } from './utils'
import { generateTableColumns, taskStatusMap } from './utils'
import EdfsButton from '@/components/dashboard/Edfs-button/index.vue'
import EdfsTable from '@/components/dashboard/Edfs-table/index.vue'
import EdfsWrap from '@/components/dashboard/Edfs-wrap.vue'
@ -112,12 +52,14 @@ import { useIcon } from '@/utils/useIcon' @@ -112,12 +52,14 @@ import { useIcon } from '@/utils/useIcon'
import createTaskDlg from './components/create-task-dlg.vue'
import detailsDrawer from './components/details-drawer.vue'
import { isResError, useMessage } from '@/hooks/useMessage.js'
import dayjs from 'dayjs'
import { useRoute } from 'vue-router'
import { getTaskList } from '@/api/module/eam/device/task'
import { useWindowResize } from '@/tools/common/hooks'
const route = useRoute()
const message = useMessage()
const tableCol = ref(generateTableColumns(onDetails))
const createIcon = useIcon({ icon: 'gravity-ui:plus' })
const tableRef = ref<any>(null)
const dataList = ref<any>([])
@ -131,12 +73,9 @@ type TaskMap = Map<number, DeviceMap> @@ -131,12 +73,9 @@ type TaskMap = Map<number, DeviceMap>
const taskMap: TaskMap = new Map<number, DeviceMap>()
async function loadData() {
if (!pageSize.value) {
pageSize.value = tableRef.value.getSize()
}
const res = await getTaskList({
pageNo: pageIndex.value,
pageSize: pageSize.value,
pageSize: pageSize.value ?? 124,
})
if (isResError(res)) return
const { list, total } = res.data
@ -183,8 +122,27 @@ onMounted(async () => { @@ -183,8 +122,27 @@ onMounted(async () => {
if (queryType === 'create') {
addTask()
}
resetColumnsWidth()
useWindowResize(resetColumnsWidth)
})
const visibilityTable = ref(false)
async function resetColumnsWidth() {
visibilityTable.value = false
await nextTick()
visibilityTable.value = true
const table = document.querySelector('.table')
if (!table) return
const tableWidth = table.clientWidth
const columns = tableCol.value
const totalWidth = columns.reduce((acc, cur) => acc + cur.width, 0)
const scale = tableWidth / totalWidth
for (const col of columns) {
col.width = col.width * scale
}
}
onBeforeUnmount(() => {
removeListener(socketMsgListener)
})
@ -210,7 +168,7 @@ const socketMsgListener: SocketMsgListener = { @@ -210,7 +168,7 @@ const socketMsgListener: SocketMsgListener = {
detailsRef.value.updateData(dataArray)
}
}
if (type === 'upgrade-task' && data.id) {
if (type === 'upgradeTask' && data.id) {
tasksStatusMap.set(data.id, data)
updateTaskData()
}
@ -227,136 +185,61 @@ function updateTaskData() { @@ -227,136 +185,61 @@ function updateTaskData() {
data.successCount = taskData.successCount
}
}
</script>
// let a = [
// {
// type: 'upgrade',
// stationId: 1,
// time: 1726129158000,
// data: {
// id: 1,
// taskId: 32,
// deviceId: 1,
// node: 0,
// subNode: 10,
// reason: null,
// deviceSn: '4',
// tenantId: 162,
// createTime: 1725533993000,
// updateTime: 1725533993000,
// creator: '145',
// updater: '145',
// deleted: false,
// },
// },
// {
// type: 'upgrade',
// stationId: 1,
// time: 1726129158000,
// data: {
// id: 1,
// taskId: 32,
// deviceId: 1,
// node: 1,
// subNode: 10,
// reason: 'null',
// deviceSn: '5',
// tenantId: 162,
// createTime: 1725533993000,
// updateTime: 1725533993000,
// creator: '145',
// updater: '145',
// deleted: false,
// },
// },
// {
// type: 'upgrade',
// stationId: 1,
// time: 1726129158000,
// data: {
// id: 1,
// taskId: 32,
// deviceId: 1,
// node: 2,
// subNode: 10,
// reason: 'null',
// deviceSn: '6',
// tenantId: 162,
// createTime: 1725533993000,
// updateTime: 1725533993000,
// creator: '145',
// updater: '145',
// deleted: false,
// },
// },
// {
// type: 'upgrade',
// stationId: 1,
// time: 1726129158000,
// data: {
// id: 1,
// taskId: 1,
// deviceId: 1,
// node: 3,
// subNode: 10,
// reason: null,
// deviceSn: '6',
// tenantId: 162,
// createTime: 1725533993000,
// updateTime: 1725533993000,
// creator: '145',
// updater: '145',
// deleted: false,
// },
// },
// {
// type: 'upgrade',
// stationId: 1,
// time: 1726129158000,
// data: {
// id: 1,
// taskId: 1,
// deviceId: 1,
// node: 1,
// subNode: 10,
// reason: null,
// deviceSn: '6',
// tenantId: 162,
// createTime: 1725533993000,
// updateTime: 1725533993000,
// creator: '145',
// updater: '145',
// deleted: false,
// },
// },
// ]
// function test(type: string, stationId: number, data?: any, time?: number) {
// if (type === 'upgrade') {
// const { deviceSn, taskId } = data
// if (!taskId || !deviceSn) return
// //
// let deviceMap = taskMap.get(taskId)
// if (!deviceMap) {
// deviceMap = new Map<number, any>()
// taskMap.set(taskId, deviceMap)
// }
// deviceMap.set(deviceSn, data)
<style lang="scss">
.task-management-wrap {
.el-table-v2__header,
.el-table-v2__header-wrapper {
height: 40px !important;
}
// if (detailsRef.value && rowData.value?.id) {
// const taskId = rowData.value?.id
// let taskData = taskMap.get(taskId)
// const dataArray = taskData ? Array.from(taskData.values()) : []
// detailsRef.value.updateData(dataArray)
// }
// }
// }
.el-table-v2__header {
.el-table-v2__header-row {
height: 40px !important;
background-color: var(--table-header-bg);
}
// setInterval(() => {
// for (const item of a) {
// test(item.type, item.stationId, item.data, item.time)
// }
// }, 1000)
</script>
.el-table-v2__header-cell {
font-size: 14px;
color: var(--table-header-text-color);
background-color: transparent;
}
}
.el-table-v2__body {
.el-table-v2__row {
min-height: 37px;
}
.el-table-v2__row:hover {
background-color: var(--el-fill-color-light);
}
.el-table-v2__row-cell {
font-size: 14px;
text-align: center;
color: var(--text-color);
background-color: transparent;
padding: 0px 0px;
padding-left: 14px;
word-wrap: break-word;
word-break: normal;
}
}
.right-table {
.el-table-v2__header-row {
> :not(:first-child) {
visibility: hidden;
}
}
.el-table-v2__row {
> :not(:first-child) {
visibility: hidden;
}
}
}
}
</style>
<style scoped lang="scss">
.task-management-wrap {
@ -365,8 +248,6 @@ function updateTaskData() { @@ -365,8 +248,6 @@ function updateTaskData() {
.task-table {
height: 100%;
box-sizing: border-box;
background: #fff;
padding-bottom: 0;
.table {
height: 100%;

150
src/pages/ota/upgradeTask/utils.ts

@ -1,41 +1,117 @@ @@ -1,41 +1,117 @@
export const tableColumns = [
{
label: '任务名称',
prop: 'taskName',
width: '10%',
},
{
label: '固件名称',
prop: 'name',
width: '8%',
},
{
label: '固件版本',
prop: 'version',
width: '8%',
},
import { ElDivider, TableV2FixedDir, type Column } from 'element-plus'
import EdfsButton from '@/components/dashboard/Edfs-button/index.vue'
import dayjs from 'dayjs'
import { h } from 'vue'
{
label: '创建时间',
prop: 'createTime',
width: '18%',
},
{
label: '任务执行时间',
prop: 'executeTime',
width: '18%',
},
{
label: '升级详情',
prop: 'deviceUpgradeDetail',
width: '10%',
},
{
label: '任务状态',
prop: 'status',
width: '8%',
},
]
export const generateTableColumns = (fn: Function): Column<any>[] => {
const col = [
{
dataKey: 'taskName',
key: 'taskName',
title: '任务名称',
width: 120,
},
{
dataKey: 'name',
key: 'name',
title: '固件名称',
width: 100,
},
{
dataKey: 'version',
key: 'version',
title: '固件版本',
width: 80,
},
{
dataKey: 'createTime',
key: 'createTime',
title: '创建时间',
width: 180,
},
{
dataKey: 'executeTime',
key: 'executeTime',
title: '任务执行时间',
width: 180,
cellRenderer: ({ rowData }: { rowData: any }) =>
h('span', dayjs(rowData.executeTime).format('YYYY-MM-DD HH:mm:ss')),
},
{
dataKey: 'status',
title: '任务状态',
key: 'status',
width: 80,
cellRenderer: ({ rowData }: { rowData: any }) => {
return h('span', taskStatusMap[rowData.status])
},
},
{
dataKey: 'deviceUpgradeDetail',
key: 'deviceUpgradeDetail',
title: '升级详情',
width: 300,
cellRenderer: ({ rowData }: { rowData: any }) => {
// <div>
// <div>升级中:{{ scope.row.processingCount }}</div>
// <div>失败数量: {{ scope.row.failCount }}</div>
// <div>升级完成: {{ scope.row.successCount }}</div>
// </div>
return h('div', [
h(
'span',
// {
// style: {
// color: '#3b82f6',
// paddingRight: '10px',
// },
// },
`升级中:${rowData.processingCount}`
),
h(ElDivider, { direction: 'vertical' }),
h(
'span',
// {
// style: {
// color: '#ef4444',
// paddingRight: '10px',
// },
// },
`失败数量: ${rowData.failCount}`
),
h(ElDivider, { direction: 'vertical' }),
h(
'span',
// {
// style: {
// color: '#16a34a',
// paddingRight: '10px',
// },
// },
`升级完成: ${rowData.successCount}`
),
])
},
},
{
key: 'operation',
title: '操作',
width: 80,
cellRenderer: ({ rowData }: { rowData: any }) => {
return h(EdfsButton, {
type: 'primary',
link: true,
onClick: () => {
fn(rowData)
},
innerText: '升级详情',
})
},
},
]
return col
}
export const tableColumns: Column<any>[] = []
export const taskStatusMap = {
0: '未开始',

5
src/pages/socket_server/SocketServer.ts

@ -109,7 +109,10 @@ export class SocketServer { @@ -109,7 +109,10 @@ export class SocketServer {
const msg = JSON.parse(e.data)
console.log(msg)
if (msg.type === 'notice-push' || msg.type === 'device') {
this.msgListener?.(msg.content)
const data =
typeof msg.content === 'string' ? JSON.parse(msg.content) : msg.content
console.log(data)
this.msgListener?.(data)
}
}
}

Loading…
Cancel
Save