Browse Source

fix: 功能细节优化

main
betaqi 2 months ago
parent
commit
768025aabf
  1. 17
      src/stores/transferData.ts
  2. 10
      src/views/firmwareUpload/index.vue
  3. 3
      src/views/stationData/components/PointGroupTree.vue
  4. 28
      src/views/stationData/components/deviceDrawer.vue
  5. 2
      src/views/stationData/components/newDataChart.vue
  6. 13
      src/views/stationData/index.vue
  7. 64
      src/views/stationData/transferData.vue

17
src/stores/transferData.ts

@ -32,6 +32,20 @@ export const useTransferDataStore = defineStore('transfer', () => {
}, 1000); }, 1000);
} }
function formatSizeFromKB(num: number): string {
const sizeKB = Number(num)
const units = ['KB', 'MB', 'GB', 'TB', 'PB']
let size = sizeKB
let unitIndex = 0
while (size >= 1024 && unitIndex < units.length - 1) {
size = size / 1024
unitIndex++
}
return `${size.toFixed(2)} ${units[unitIndex]}`
}
function getSubDevicesCb(msg: SubMsgData) { function getSubDevicesCb(msg: SubMsgData) {
const { feedback } = msg const { feedback } = msg
const sn = feedback[1] const sn = feedback[1]
@ -40,12 +54,13 @@ export const useTransferDataStore = defineStore('transfer', () => {
hasDevice.lastUpdated = Date.now() hasDevice.lastUpdated = Date.now()
hasDevice.status = '在线' hasDevice.status = '在线'
} else { } else {
const num = feedback[4] || 0
const device: IOnlineDevice = { const device: IOnlineDevice = {
clientIp: feedback[0], clientIp: feedback[0],
sn: sn, sn: sn,
site_id: feedback[2], site_id: feedback[2],
versions: feedback[3] ?? '--', versions: feedback[3] ?? '--',
footprint: feedback[4] ?? '--', footprint: formatSizeFromKB(Number(num)),
lastUpdated: Date.now(), lastUpdated: Date.now(),
status: '在线', // 初始状态为在线 status: '在线', // 初始状态为在线
isChecked: false, isChecked: false,

10
src/views/firmwareUpload/index.vue

@ -111,6 +111,8 @@ async function onSave() {
// } catch (error) { // } catch (error) {
// message.error('') // message.error('')
// } // }
await getPath()
abortController.value = undefined abortController.value = undefined
loading.value = false loading.value = false
@ -164,12 +166,16 @@ const firmwarePath = ref<string>()
const title = computed(() => { const title = computed(() => {
return `固件上传(${firmwarePath.value ? `当前固件:${firmwarePath.value}` : '当前固件: 未上传'}` return `固件上传(${firmwarePath.value ? `当前固件:${firmwarePath.value}` : '当前固件: 未上传'}`
}) })
onMounted(async () => {
const getPath = async () => {
const res = await getFirmwarePath() const res = await getFirmwarePath()
if (res.code === 200 || res.code === 0) { if (res.code === 200 || res.code === 0) {
firmwarePath.value = res.data.path.split('/').at(-1) firmwarePath.value = res.data?.path?.split('/').at(-1)
} }
}
onMounted(() => {
getPath()
}) })
</script> </script>

3
src/views/stationData/components/PointGroupTree.vue

@ -13,7 +13,7 @@
</el-scrollbar> </el-scrollbar>
</div> </div>
<el-divider direction="vertical" class="h-full" /> <el-divider direction="vertical" class="h-full" />
<div class="w-340"> <div class="w-340" v-loading="loadingPoints" element-loading-text="数据加载中...">
<el-scrollbar class="scroll"> <el-scrollbar class="scroll">
<el-checkbox-group v-model="checkPointList" class="point-checks" @change="changePoints"> <el-checkbox-group v-model="checkPointList" class="point-checks" @change="changePoints">
<template v-for="(item, index) in devicePoints" :key="index"> <template v-for="(item, index) in devicePoints" :key="index">
@ -35,6 +35,7 @@ interface Props {
label: string label: string
addr: string addr: string
}> }>
loadingPoints: boolean
groupChangeLoading: boolean groupChangeLoading: boolean
} }

28
src/views/stationData/components/deviceDrawer.vue

@ -6,12 +6,13 @@
<main class="wh-full flex"> <main class="wh-full flex">
<EdfsWrap title="点位组" class="p-r-4 h-full border-r-1 border-solid border-r-#e4e7ed"> <EdfsWrap title="点位组" class="p-r-4 h-full border-r-1 border-solid border-r-#e4e7ed">
<PointGroupTree v-if="isShowDrawer" :data="pointGroup" @device-select="onGroupChange" <PointGroupTree v-if="isShowDrawer" :data="pointGroup" @device-select="onGroupChange"
:groupChangeLoading="groupChangeLoading" @onchangePoints="onchangePoints" :device-points="pointList" :groupChangeLoading="groupChangeLoading" @onchangePoints="onchangePoints" :devicePoints="pointList"
:isTransfer="props.isTransfer" :siteInfo="props.siteInfo" ref="pointGroupTreeRef" /> :loadingPoints="loadingPoints" :isTransfer="props.isTransfer" :siteInfo="props.siteInfo"
ref="pointGroupTreeRef" />
</EdfsWrap> </EdfsWrap>
<div class="flex-1 p-4 h-full overflow-hidden"> <div class="flex-1 p-4 h-full overflow-hidden" v-loading="loadingChart" element-loading-text="点位数据加载中...">
<el-button class="mb-4" type="primary" @click="loadChardData">查询数据</el-button> <el-button class="mb-4" type="primary" @click="loadChardData">查询数据</el-button>
<NewDataChart v-if="isShowChart && !loading" :chart-datas="chartDatas" :legends="legends" <NewDataChart v-if="isShowChart" :chart-datas="chartDatas" :legends="legends"
:axis-data="Array.from(axisData)" ref="chartRef" /> :axis-data="Array.from(axisData)" ref="chartRef" />
</div> </div>
</main> </main>
@ -82,6 +83,8 @@ async function open(device: IOfflineDevice | IOnlineDevice) {
}) })
} }
const loadingPoints = ref(false)
const columsParams = computed(() => ['ts', ...checkPointList.value.map(i => i.addr)]) const columsParams = computed(() => ['ts', ...checkPointList.value.map(i => i.addr)])
async function loadPoints() { async function loadPoints() {
if (!curGroup.value) { if (!curGroup.value) {
@ -101,7 +104,7 @@ async function loadPoints() {
params.site = props.siteInfo!.name params.site = props.siteInfo!.name
params.isLocal = true params.isLocal = true
} }
loadingPoints.value = true
const res = await getPoints(params) const res = await getPoints(params)
if (res.code === 0) { if (res.code === 0) {
const data = Array.isArray(res?.data) ? res.data : [] const data = Array.isArray(res?.data) ? res.data : []
@ -110,11 +113,8 @@ async function loadPoints() {
addr: i.addr, addr: i.addr,
unit: i.unit || '', unit: i.unit || '',
})) }))
pointList.value.push({
label: '时间',
addr: 'ts',
})
} }
loadingPoints.value = false
return res return res
} }
@ -145,7 +145,7 @@ const chartDatas = reactive(new Map<string, any[]>())
const axisData = new Set<string>() const axisData = new Set<string>()
const legends = ref<{ addr: string; label: string, unit: string }[]>([]) const legends = ref<{ addr: string; label: string, unit: string }[]>([])
const loading = ref(false) const loadingChart = ref(false)
async function loadChardData() { async function loadChardData() {
if (!columsParams.value.filter(i => i !== 'ts').length) { if (!columsParams.value.filter(i => i !== 'ts').length) {
@ -164,7 +164,8 @@ async function loadChardData() {
params.site_id = props.siteInfo!.name || '' params.site_id = props.siteInfo!.name || ''
params.device_id = curDevice.value?.sn || '' params.device_id = curDevice.value?.sn || ''
} }
loading.value = true loadingChart.value = true
isShowChart.value = false
const res = await getDeviceDetails(params) const res = await getDeviceDetails(params)
if (res.code === 0) { if (res.code === 0) {
@ -200,7 +201,10 @@ async function loadChardData() {
} else { } else {
message.error('获取设备数据失败') message.error('获取设备数据失败')
} }
loading.value = false loadingChart.value = false
nextTick(() => {
isShowChart.value = true
})
} }
// function zmqImport(device: IOfflineDevice) { // function zmqImport(device: IOfflineDevice) {

2
src/views/stationData/components/newDataChart.vue

@ -59,7 +59,7 @@ const props = defineProps({
const loading = ref(true) const loading = ref(true)
const loadingOpt = { const loadingOpt = {
type: 'default', type: 'default',
text: '请选择点位', text: '暂无数据',
color: '#c23531', color: '#c23531',
textColor: '#666', textColor: '#666',
maskColor: 'rgba(0, 0, 0, 0)', maskColor: 'rgba(0, 0, 0, 0)',

13
src/views/stationData/index.vue

@ -49,6 +49,7 @@
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
<template v-if="env.VITE_APP_ENV == 'local'">
<div class="body"> <div class="body">
<div class="info"> <div class="info">
<div class="info-item"> <div class="info-item">
@ -65,6 +66,18 @@
</div> </div>
</div> </div>
</div> </div>
</template>
<template v-else>
<div class="body">
<div class="info">
<div class="info-item">
<div class="info-item-label">迁移时间</div>
<div class="info-item-value">{{ item.create_time }}</div>
</div>
</div>
</div>
</template>
</div> </div>
</div> </div>
</EdfsWrap> </EdfsWrap>

64
src/views/stationData/transferData.vue

@ -164,7 +164,7 @@
</div> </div>
<div class="transfer-log-wrap h-490 flex-col"> <div class="transfer-log-wrap h-490 flex-col">
<div class="text-16px font-500">迁移日志</div> <div class="text-16px font-500">迁移日志</div>
<el-scrollbar class="flex-1"> <el-scrollbar class="flex-1" ref="transferLogScrollbar">
<div v-for="i in curTransferLog" :class="i.status === 'failed' ? 'text-red-500' : ''" <div v-for="i in curTransferLog" :class="i.status === 'failed' ? 'text-red-500' : ''"
class="text-gray-600"> class="text-gray-600">
{{ i.msg }} {{ i.msg }}
@ -195,7 +195,7 @@
</div> </div>
<div class="h-490 border-radius-8px bg-[#F9FAFB] p-10 flex-col"> <div class="h-490 border-radius-8px bg-[#F9FAFB] p-10 flex-col">
<div class="text-16px font-500">迁移日志</div> <div class="text-16px font-500">迁移日志</div>
<el-scrollbar class="flex-1"> <el-scrollbar class="flex-1" ref="transferLogScrollbar">
<div v-for="i in siteTransferLogList" <div v-for="i in siteTransferLogList"
:class="['error', 'timeout'].includes(i.status) ? 'text-red-500' : ''" class="text-gray-600"> :class="['error', 'timeout'].includes(i.status) ? 'text-red-500' : ''" class="text-gray-600">
{{ i.device.sn }}{{ i.msg }} {{ i.device.sn }}{{ i.msg }}
@ -274,6 +274,7 @@ const transferStatusMap = {
success: '迁移成功', success: '迁移成功',
failed: '迁移失败', failed: '迁移失败',
timeout: '迁移超时', timeout: '迁移超时',
stop: '迁移已终止',
} }
const exportPubDeviceMap = new Map<string, { device: IOnlineDevice; action: 'export' }>() const exportPubDeviceMap = new Map<string, { device: IOnlineDevice; action: 'export' }>()
@ -282,7 +283,7 @@ const curTransferLog = ref<
{ msg: string; host: string; status: 'success' | 'padding' | 'failed' }[] { msg: string; host: string; status: 'success' | 'padding' | 'failed' }[]
>([]) >([])
const transferStatus = ref<'progress' | 'success' | 'failed' | 'timeout' | undefined>() const transferStatus = ref<'progress' | 'success' | 'failed' | 'timeout' | 'stop' | undefined>()
const devices = computed(() => { const devices = computed(() => {
return isonLineTransfer.value ? Array.from(devicesMap.value.values()) : offLineDeviceList.value return isonLineTransfer.value ? Array.from(devicesMap.value.values()) : offLineDeviceList.value
@ -327,6 +328,7 @@ const statusMap = {
} }
const zmqExportMSG = ref('')
function zmqExportCb(msg: PubMsgData) { function zmqExportCb(msg: PubMsgData) {
if (!isonLineTransfer.value) return if (!isonLineTransfer.value) return
const { feedback, result, id } = msg const { feedback, result, id } = msg
@ -338,12 +340,35 @@ function zmqExportCb(msg: PubMsgData) {
| 'padding' | 'padding'
| 'failed') | 'failed')
: 'failed' : 'failed'
const isLineFeed = feedback[2] && feedback[2].includes('\n')
if (isLineFeed) {
if (zmqExportMSG.value) {
curTransferLog.value.at(-1)!.msg += feedback[2]
} else {
curTransferLog.value.push({ curTransferLog.value.push({
msg: `主机【${feedback[0]}】: ${feedback[2]}`, msg: `主机【${feedback[0]}】: ${feedback[2]}`,
host: feedback[0], host: feedback[0],
status, status,
}) })
} }
zmqExportMSG.value = ''
} else {
if (!zmqExportMSG.value) {
curTransferLog.value.push({
msg: `主机【${feedback[0]}】: ${zmqExportMSG.value + feedback[2]}`,
host: feedback[0],
status,
})
}
zmqExportMSG.value += typeof feedback[2] === 'string' ? feedback : ''
curTransferLog.value.at(-1)!.msg = zmqExportMSG.value
}
}
transferStatus.value = 'progress' transferStatus.value = 'progress'
if (result !== 'progress') { if (result !== 'progress') {
@ -388,6 +413,7 @@ function onStopTransfer() {
worker.publish(postTransferTopic, msg) worker.publish(postTransferTopic, msg)
message.success('迁移已取消') message.success('迁移已取消')
exportPubDeviceMap.clear() exportPubDeviceMap.clear()
transferStatus.value = 'stop'
}) })
} }
@ -684,6 +710,7 @@ const offLineTransferRes = () => {
} }
} }
const importMsg = ref('')
const onOffDeviceTransferStatus = ref<'progress' | 'success' | undefined>() const onOffDeviceTransferStatus = ref<'progress' | 'success' | undefined>()
function zmqImportCb(msg: PubMsgData) { function zmqImportCb(msg: PubMsgData) {
const { id, feedback, result, code } = msg const { id, feedback, result, code } = msg
@ -693,6 +720,12 @@ function zmqImportCb(msg: PubMsgData) {
if (code === ZmqMsgResultType.PROGRESS) { if (code === ZmqMsgResultType.PROGRESS) {
onOffDeviceTransferStatus.value = 'progress' onOffDeviceTransferStatus.value = 'progress'
const log: string = Array.isArray(feedback) ? feedback[0] || '' : '' const log: string = Array.isArray(feedback) ? feedback[0] || '' : ''
console.log(log)
const isLineFeed = log && log.includes('\n')
if (isLineFeed) {
if (importMsg.value) {
siteTransferLogList.value.at(-1)!.msg += log
} else {
siteTransferLogList.value.push({ siteTransferLogList.value.push({
msg: log, msg: log,
device: offDevice, device: offDevice,
@ -700,6 +733,20 @@ function zmqImportCb(msg: PubMsgData) {
}) })
} }
importMsg.value = ''
} else {
if (!importMsg.value) {
siteTransferLogList.value.push({
msg: log,
device: offDevice,
status: 'success'
})
}
importMsg.value += typeof log === 'string' ? log : ''
siteTransferLogList.value.at(-1)!.msg = importMsg.value
}
}
if (code !== ZmqMsgResultType.PROGRESS) { if (code !== ZmqMsgResultType.PROGRESS) {
importQueue.value.shift() importQueue.value.shift()
isImporting.value = false isImporting.value = false
@ -734,6 +781,17 @@ function zmqImportTimeoutCb(msg: TimeoutMsg) {
} }
// ================ 线 end ========= // ================ 线 end =========
// const transferLogScrollbar = ref()
// watch(siteTransferLogList, () => {
// nextTick(() => {
// if (transferLogScrollbar.value) {
// const scrollbar = transferLogScrollbar.value
// scrollbar.setScrollTop(scrollbar.wrap$.scrollHeight)
// }
// })
// }, { deep: true })
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

Loading…
Cancel
Save