Browse Source

feat: 固件升级

master
wangqi 2 months ago
parent
commit
b204694713
  1. 2
      .env.development
  2. 33
      components.d.ts
  3. 4
      src/api/module/eam/device/firmware.ts
  4. 13
      src/api/module/eam/device/index.ts
  5. 6
      src/api/module/eam/device/task.ts
  6. 119
      src/pages/deviceInfo/components/BasicInfo.vue
  7. 17
      src/pages/deviceInfo/components/data-filter.vue
  8. 4
      src/pages/deviceInfo/index.vue
  9. 4
      src/pages/deviceInfo/utils.ts
  10. 2
      src/pages/deviceStorage/utils.ts
  11. 7
      src/pages/deviceTest/testPlan/components/InfoDlg.vue
  12. 7
      src/pages/layout.vue
  13. 11
      src/pages/ota/firmware/components/create-firmware-dlg.vue
  14. 252
      src/pages/ota/upgradeTask/components/create-task-dlg.vue
  15. 9
      src/pages/ota/upgradeTask/index.vue
  16. 2
      src/pages/socket_server/index.ts
  17. 3
      src/pages/system/deviceField/components/CategoryDlg.vue

2
.env.development

@ -1,2 +1,2 @@ @@ -1,2 +1,2 @@
VITE_BASE_URL = 'http://192.168.1.3:48080'
VITE_SOCKET_SERVER = 'http://192.168.1.3:7080'
VITE_SOCKET_SERVER = 'http://192.168.1.3:48080'

33
components.d.ts vendored

@ -21,10 +21,20 @@ declare module 'vue' { @@ -21,10 +21,20 @@ 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']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElButton: typeof import('element-plus/es')['ElButton']
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
ElCard: typeof import('element-plus/es')['ElCard']
ElCascader: typeof import('element-plus/es')['ElCascader']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
@ -32,20 +42,40 @@ declare module 'vue' { @@ -32,20 +42,40 @@ declare module 'vue' {
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSpace: typeof import('element-plus/es')['ElSpace']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload']
Form: typeof import('./src/components/dashboard/Form/src/Form.vue')['default']
FormItemInput: typeof import('./src/components/dashboard/FormItemInput.vue')['default']
FormItemSelect: typeof import('./src/components/dashboard/FormItemSelect.vue')['default']
Icon: typeof import('./src/components/dashboard/Icon/src/Icon.vue')['default']
IconSelect: typeof import('./src/components/dashboard/Icon/src/IconSelect.vue')['default']
IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default']
ImageViewer: typeof import('./src/components/dashboard/ImageViewer/src/ImageViewer.vue')['default']
InputPassword: typeof import('./src/components/dashboard/InputPassword/src/InputPassword.vue')['default']
LegendItem: typeof import('./src/components/map_tool/legend/LegendItem.vue')['default']
@ -63,4 +93,7 @@ declare module 'vue' { @@ -63,4 +93,7 @@ declare module 'vue' {
XButton: typeof import('./src/components/dashboard/XButton/src/XButton.vue')['default']
XTextButton: typeof import('./src/components/dashboard/XButton/src/XTextButton.vue')['default']
}
export interface ComponentCustomProperties {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}

4
src/api/module/eam/device/firmware.ts

@ -26,10 +26,10 @@ export function createFirmware(data: any) { @@ -26,10 +26,10 @@ export function createFirmware(data: any) {
})
}
export function getSimpleFirmwareList(params: { type: number }) {
export function getSimpleFirmwareList(params: { type: string }) {
return eamServer({
url: '/firmware/simple-list',
method: 'get',
params,
})
}
}

13
src/api/module/eam/device/index.ts

@ -16,17 +16,21 @@ export interface IDevice { @@ -16,17 +16,21 @@ export interface IDevice {
testSheetId: number
testSheetStatus: string
testSheetDetail: string
currentFirmwareId: string
targetFirmwareId: string
}
export interface IDeviceOV {
id?: number
name: string
name?: string
categoryId: string
templateId: string
serialNo?: string
sn: string
description: string
cost: string
currentFirmwareId: string
targetFirmwareId: string
}
export const operantDevice = (type: OperantAction, data: IDeviceOV) => {
@ -82,6 +86,13 @@ export const getDeviceSummaryByStatus = () => { @@ -82,6 +86,13 @@ export const getDeviceSummaryByStatus = () => {
})
}
export const getSimpleDeviceList = (params: { categoryId: string }) =>
eamServer({
url: `/device/simple-list`,
method: 'get',
params,
})
// ============== 测试工单相关 ==============
export const operantDeviceTestSheet = (type: OperantAction, params: any) => {

6
src/api/module/eam/device/task.ts

@ -2,7 +2,7 @@ import { eamServer } from '../../index' @@ -2,7 +2,7 @@ import { eamServer } from '../../index'
export function getTaskList(params: PageParam) {
return eamServer({
url: '/device/task/page',
url: '/task/page',
method: 'get',
params,
})
@ -10,7 +10,7 @@ export function getTaskList(params: PageParam) { @@ -10,7 +10,7 @@ export function getTaskList(params: PageParam) {
export function getTaskDetails(id: string) {
return eamServer({
url: '/device/task/details',
url: '/task/details',
method: 'get',
params: { id },
})
@ -18,7 +18,7 @@ export function getTaskDetails(id: string) { @@ -18,7 +18,7 @@ export function getTaskDetails(id: string) {
export function createTask(data: any) {
return eamServer({
url: '/device/firmware/remote-update',
url: '/firmware/remote-update',
method: 'post',
data,
})

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

@ -13,16 +13,6 @@ @@ -13,16 +13,6 @@
>
</el-input>
</div>
<div class="from-row">
<div class="label">设备名称:</div>
<el-input
class="input"
v-model="params.name"
:disabled="disabled"
placeholder="请输入设备名称"
clearable
/>
</div>
<div class="from-row">
<div class="label">设备SN:</div>
@ -34,8 +24,6 @@ @@ -34,8 +24,6 @@
clearable
/>
</div>
</div>
<div class="group-box">
<div class="from-row">
<div class="label">设备类别:</div>
<el-cascader
@ -47,9 +35,30 @@ @@ -47,9 +35,30 @@
checkStrictly: true,
value: 'id',
label: 'name',
emitPath: false,
}"
/>
</div>
</div>
<div class="group-box">
<div class="from-row">
<div class="label">设备固件:</div>
<el-select
v-model="params.targetFirmwareId"
placeholder="请选择固件"
style="flex: 1"
:disabled="disabled ? true : isEmpty(params.categoryId)"
class="input"
@visible-change="loadFirmwareList"
>
<el-option
v-for="item in firmwareList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</div>
<div class="from-row">
<div class="label">测试模板:</div>
<FormItemSelect
@ -75,6 +84,15 @@ @@ -75,6 +84,15 @@
</div>
</div>
<div class="group-box">
<div class="from-row">
<div class="label">当前固件:</div>
<number-input
class="input"
:disabled="true"
v-model="params.currentFirmwareId"
placeholder="设备暂无固件"
/>
</div>
<div class="from-row">
<div class="label">备注:</div>
<el-input
@ -83,7 +101,7 @@ @@ -83,7 +101,7 @@
type="textarea"
v-model="params.description"
placeholder="请输入备注"
:autosize="{ minRows: 5, maxRows: 4 }"
:autosize="{ minRows: 3, maxRows: 4 }"
resize="none"
/>
</div>
@ -95,6 +113,13 @@ @@ -95,6 +113,13 @@
v-if="isShowSaveButton"
@click="onSave"
/>
<EdfsButton
inner-text="固件升级"
type="primary"
class="save-button"
v-if="isShowFirmwareUpgradeButton"
@click="onFirmwareUpgrade"
/>
</div>
</div>
</template>
@ -103,15 +128,17 @@ @@ -103,15 +128,17 @@
import { isEmpty } from '@/utils/is'
import numberInput from '@/components/dashboard/Edfs-number-item-input.vue'
import EdfsButton from '@/components/dashboard/Edfs-button/index.vue'
import { getSimpleFirmwareList } from '@/api/module/eam/device/firmware'
import FormItemSelect from '@/components/dashboard/FormItemSelect.vue'
import { operantDevice, type IDevice, type IDeviceOV } from '@/api/module/eam/device'
import { cloneDeep } from 'lodash'
import { isResError, useMessage } from '@/hooks/useMessage'
import { getDeviceTempSimpleList } from '@/api/module/eam/device/template'
import { getCategoryTree, type ICategoryTree } from '@/api/module/eam/device/category'
import { useRoute } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import type { OptAction } from '../utils'
const route = useRoute()
const router = useRouter()
const action = route.query.action as OptAction
const message = useMessage()
const props = defineProps<{
@ -122,20 +149,29 @@ const props = defineProps<{ @@ -122,20 +149,29 @@ const props = defineProps<{
const emit = defineEmits(['on-save'])
const paramsData: IDeviceOV = {
name: '',
currentFirmwareId: '',
categoryId: '',
templateId: '',
sn: '',
serialNo: '',
description: '',
cost: '',
targetFirmwareId: '',
}
const isShowSaveButton = computed(() => {
if(action === 'view') return false
if (action === 'view') return false
return props.info?.status === undefined ? true : props.info.status < 2
})
const isShowFirmwareUpgradeButton = computed(() => {
if (action === 'view') return false
return props.info?.status === undefined
? false
: props.info.status >= 1 && props.info.targetFirmwareId
})
const params = ref(cloneDeep(paramsData))
async function onSave() {
@ -144,9 +180,6 @@ async function onSave() { @@ -144,9 +180,6 @@ async function onSave() {
const type = !!params.value.serialNo ? 'update' : 'create'
const options = cloneDeep(params.value)
if (type === 'update') options.id = props.info?.id
options.categoryId = Array.isArray(options.categoryId)
? options.categoryId[options.categoryId.length - 1]
: options.categoryId
const res = await operantDevice(type, options)
if (isResError(res)) return
message.success('基础信息提交成功')
@ -162,34 +195,40 @@ watch( @@ -162,34 +195,40 @@ watch(
params.value[key] = info[key] ?? ''
}
}
console.log(params.value)
},
{ immediate: true }
)
watch(
() => params.value.categoryId,
val => {
params.value.targetFirmwareId = ''
}
)
function validate() {
if (isEmpty(params.value.name)) {
message.error('设备名称不能为空')
if (isEmpty(params.value.targetFirmwareId)) {
message.error('请选择固件')
return false
}
if (isEmpty(params.value.sn)) {
message.error('设备SN不能为空')
message.error('请输入设备SN')
return false
}
if (isEmpty(params.value.categoryId)) {
message.error('设备类别不能为空')
message.error('请选择设备类别')
return false
}
if (isEmpty(params.value.templateId)) {
message.error('测试模板不能为空')
message.error('请选择测试模板')
return false
}
if (isEmpty(params.value.cost)) {
message.error('设备成本不能为空')
message.error('请输入设备成本')
return false
}
@ -212,6 +251,34 @@ async function loadDeviceTypeTree() { @@ -212,6 +251,34 @@ async function loadDeviceTypeTree() {
categoryTreeData.value = res.data
}
}
const firmwareList = ref<any[]>([])
async function loadFirmwareList(value: boolean) {
if (!value) return
if (isEmpty(params.value.categoryId)) {
message.error('请选择设备类别')
return
}
const res = await getSimpleFirmwareList({ type: params.value.categoryId as any })
if (!isResError(res)) {
firmwareList.value = res.data
}
}
function onFirmwareUpgrade() {
if (!props.info) return
router.push({
path: '/ota/upgradeTask',
query: {
type: 'create',
categoryId: props.info.categoryId,
deviceSn: props.info.sn,
firmwareId: props.info.targetFirmwareId,
},
})
}
onMounted(() => {
loadDeviceTypeTree()
loadTemplateList()

17
src/pages/deviceInfo/components/data-filter.vue

@ -37,8 +37,8 @@ @@ -37,8 +37,8 @@
<el-checkbox v-model="checkbox.serialNo" size="large" />
</div>
<div class="item">
<el-input placeholder="请输入设备名称" v-model="filterData.name" />
<el-checkbox v-model="checkbox.name" size="large" />
<el-input placeholder="请输入设备sn" v-model="filterData.sn" />
<el-checkbox v-model="checkbox.sn" size="large" />
</div>
<div class="item">
@ -67,6 +67,7 @@ @@ -67,6 +67,7 @@
checkStrictly: true,
value: 'id',
label: 'name',
emitPath: false,
}"
/>
<el-checkbox v-model="checkbox.categoryId" size="large" />
@ -109,16 +110,16 @@ type FilterKeys = keyof typeof filterData.value @@ -109,16 +110,16 @@ type FilterKeys = keyof typeof filterData.value
const filterData = ref({
startDay: '',
endDay: '',
name: '',
sn: '',
status: '',
serialNo: '',
categoryId: [],
categoryId: '',
})
const checkbox = ref<Record<FilterKeys, boolean>>({
startDay: false,
endDay: false,
name: false,
sn: false,
serialNo: false,
status: false,
categoryId: false,
@ -147,14 +148,16 @@ function onReset() { @@ -147,14 +148,16 @@ function onReset() {
filterData.value = {
startDay: '',
endDay: '',
name: '',
sn: '',
status: '',
serialNo: '',
categoryId: [],
}
checkbox.value = {
startDay: false,
endDay: false,
name: false,
sn: false,
status: false,
serialNo: false,
categoryId: false,
}

4
src/pages/deviceInfo/index.vue

@ -130,9 +130,7 @@ const getList = async () => { @@ -130,9 +130,7 @@ const getList = async () => {
}
loading.value = true
const options = Object.assign({}, queryParams, filter.value, {
categoryId: filter.value.categoryId?.[filter.value.categoryId.length - 1],
})
const options = Object.assign({}, queryParams, filter.value)
const res = await getDevicePage(options)

4
src/pages/deviceInfo/utils.ts

@ -5,11 +5,11 @@ export enum DeviceStatus { @@ -5,11 +5,11 @@ export enum DeviceStatus {
,
}
export const deviceTableCol = [
{ label: '设备sn', prop: 'sn', minWidth: '10%' },
{ label: '设备编号', prop: 'serialNo', minWidth: '16%' },
{ label: '设备名称', prop: 'name', minWidth: '10%' },
// { label: '设备名称', prop: 'name', minWidth: '10%' },
{ label: '设备类型', prop: 'categoryName', minWidth: '10%' },
{ label: '设备状态', prop: 'status', minWidth: '10%' },
{ label: '设备sn', prop: 'sn', minWidth: '10%' },
{ label: '创建时间', prop: 'createTime', minWidth: '10%' },
]

2
src/pages/deviceStorage/utils.ts

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
export const tableCol = [
{ label: '设备名称', prop: 'deviceName', minWidth: '10%' },
// { label: '设备名称', prop: 'deviceName', minWidth: '10%' },
{ label: '设备sn', prop: 'sn', minWidth: '10%' },
{ label: '库存状态', prop: 'status', minWidth: '10%' },
{ label: '客户', prop: 'customerName', minWidth: '14%' },

7
src/pages/deviceTest/testPlan/components/InfoDlg.vue

@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
checkStrictly: true,
value: 'id',
label: 'name',
emitPath: false,
}"
clearable
/>
@ -86,9 +87,7 @@ async function onSave() { @@ -86,9 +87,7 @@ async function onSave() {
if (!validate()) return
loading.value = true
const params = cloneDeep(formData.value)
params.categoryId = Array.isArray(params.categoryId)
? params.categoryId[params.categoryId.length - 1]
: params.categoryId
let res
if (props.action === 'create') {
res = await createdDeviceTemp(params)
@ -109,7 +108,7 @@ function validate() { @@ -109,7 +108,7 @@ function validate() {
return false
}
if (formData.value.categoryId.length === 0) {
if (isEmpty(formData.value.categoryId)) {
message.error('请选择设备类型')
return false
}

7
src/pages/layout.vue

@ -111,6 +111,7 @@ import Avatar from './avatar.png' @@ -111,6 +111,7 @@ import Avatar from './avatar.png'
import { useI18n } from 'vue-i18n'
import { useTheme } from '@/utils/useTheme'
import { THEME_KEY, INIT_OPTIONS_KEY } from 'vue-echarts'
import { openSocket, closeSocket } from '@/pages/socket_server/index'
import { registerTheme } from 'echarts/core'
const { theme, toggle } = useTheme()
import { customDark, customLight } from '@/utils/dark'
@ -121,6 +122,8 @@ provide(INIT_OPTIONS_KEY, { @@ -121,6 +122,8 @@ provide(INIT_OPTIONS_KEY, {
devicePixelRatio: 2,
})
openSocket()
const route = useRoute()
const breadcrumbItems = computed(() => {
@ -236,7 +239,9 @@ async function loginOut() { @@ -236,7 +239,9 @@ async function loginOut() {
} catch {}
}
onUnmounted(() => {
closeSocket()
})
</script>
<style scoped lang="scss">

11
src/pages/ota/firmware/components/create-firmware-dlg.vue

@ -23,11 +23,12 @@ @@ -23,11 +23,12 @@
class="input"
v-model="formData.type"
:options="categoryTreeData"
style="flex: 1;"
style="flex: 1"
:props="{
checkStrictly: true,
value: 'id',
label: 'name',
emitPath: false,
}"
/>
</el-row>
@ -69,7 +70,7 @@ import EdfsDialog from '@/components/dashboard/Edfs-dialog.vue' @@ -69,7 +70,7 @@ import EdfsDialog from '@/components/dashboard/Edfs-dialog.vue'
import FormItemInput from '@/components/dashboard/FormItemInput.vue'
import { isResError, useMessage } from '@/hooks/useMessage'
import FormItemSelect from '@/components/dashboard/FormItemSelect.vue'
import { getTenantId } from '@/utils/auth'
// import { getTenantId } from '@/utils/auth'
import { getIntDictOptions } from '@/utils/dict'
const message = useMessage()
@ -122,7 +123,7 @@ function validate() { @@ -122,7 +123,7 @@ function validate() {
return true
}
if (formData.value.type.length < 1) {
if (!formData.value.type) {
message.error('请选择固件类型')
return true
}
@ -139,11 +140,11 @@ async function onSave() { @@ -139,11 +140,11 @@ async function onSave() {
if (validate()) return
loading.value = true
const data = new FormData()
data.append('path', getTenantId())
// data.append('path', getTenantId())
data.append('file', fileList.value[0].raw as File)
data.append('name', formData.value.name)
data.append('version', formData.value.version)
data.append('type', formData.value.type[formData.value.type.length - 1])
data.append('type', formData.value.type)
data.append('description', formData.value.description)
const res = await createFirmware(data)
loading.value = false

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

@ -11,39 +11,63 @@ @@ -11,39 +11,63 @@
<el-row>
<FormItemInput label="任务名称" v-model="formData.name" require />
</el-row>
<el-row>
<span class="label">固件选择</span>
<span class="label"> <span class="require">*</span>设备类别: </span>
<el-cascader
:props="cascaderFirmware"
v-model="firmwareSelect"
ref="firmwareCascaderRef"
:show-all-levels="false"
placeholder="请选择"
v-model="formData.type"
:options="categoryTreeData"
style="flex: 1"
:props="{
checkStrictly: true,
value: 'id',
label: 'name',
emitPath: false,
}"
/>
</el-row>
<el-row v-if="isShowDeviceSelect">
<!-- <span class="label">设备选择</span>
<el-cascader
style="flex: 1"
v-model="deviceSelect"
:props="cascaderDevice"
@change="devChange"
ref="deviceCascaderRef"
:show-all-levels="false"
popper-class="task-device-select-cascader"
placeholder="请选择"
<el-row v-if="typeof formData.type !== 'undefined'">
<span class="label"> <span class="require">*</span>设备: </span>
<el-select
v-model="formData.deviceSns"
multiple
collapse-tags
style="flex: 1"
:max-collapse-tags="4"
collapse-tags-tooltip
@expand-change="changeSourceType"
/> -->
placeholder="请选择设备"
@visible-change="loadDeviceList"
>
<el-option
v-for="item in deviceList"
:key="item.sn"
:label="item.sn"
:value="item.sn"
/>
</el-select>
</el-row>
<el-row v-if="typeof formData.type !== 'undefined'">
<span class="label"> <span class="require">*</span>固件选择: </span>
<el-select
v-model="formData.firmwareId"
placeholder="请选择固件"
style="flex: 1"
:disabled="false"
class="input"
@visible-change="loadFirmwareList"
>
<el-option
v-for="item in firmwareList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-row>
<el-row>
<span class="label">是否立即执行</span>
<el-switch
v-model="formData.executeNow"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
/>
<el-switch v-model="formData.executeNow" />
</el-row>
<el-row v-if="!formData.executeNow">
<span class="label">任务执行时间</span>
@ -74,135 +98,32 @@ import EdfsDialog from '@/components/dashboard/Edfs-dialog.vue' @@ -74,135 +98,32 @@ import EdfsDialog from '@/components/dashboard/Edfs-dialog.vue'
import FormItemInput from '@/components/dashboard/FormItemInput.vue'
import { isResError, useMessage } from '@/hooks/useMessage'
import EdfsNumberInput from '@/components/dashboard/Edfs-number-item-input.vue'
import FormItemSelect from '@/components/dashboard/FormItemSelect.vue'
import type { CascaderProps, CascaderValue, ElCascader } from 'element-plus'
// import { getSimpleStationList } from '@/api/module/app/station'
// import { getSimpleDeviceList } from '@/api/module/app/device'
import { getIntDictOptions } from '@/utils/dict'
import { getSimpleDeviceList } from '@/api/module/eam/device/index'
import { getSimpleFirmwareList } from '@/api/module/eam/device/firmware'
import { isEmpty } from '@/utils/is'
import { clone, cloneDeep } from 'lodash'
import { cloneDeep } from 'lodash'
import { createTask } from '@/api/module/eam/device/task'
import { getCategoryTree, type ICategoryTree } from '@/api/module/eam/device/category'
import { useRoute } from 'vue-router'
const route = useRoute()
const message = useMessage()
interface Props {
isShow: boolean
}
const emits = defineEmits(['on-save', 'on-close'])
const props = withDefaults(defineProps<Props>(), {
withDefaults(defineProps<Props>(), {
isShow: false,
})
const firmwareSelect = ref<CascaderValue>([])
const firmwareCascaderRef = ref<InstanceType<typeof ElCascader>>()
const cascaderFirmware: CascaderProps = {
lazy: true,
async lazyLoad(node, resolve) {
const { level } = node
if (level === 0) {
const deviceTypes = getIntDictOptions('device_entity_type').map(item => ({
value: item.value,
label: item.label,
isLeaf: false,
}))
resolve(deviceTypes)
}
if (level === 1) {
const res = await getSimpleFirmwareList({
type: node.data?.value as number,
})
const data = Array.isArray(res?.data) ? res.data : []
const firmware = data.map((item: any) => ({
value: item.id,
label: item.name,
isLeaf: true,
leaf: true,
}))
resolve(firmware)
}
},
}
const selectFirmwareType = ref()
watch(firmwareSelect, (value: any) => {
selectFirmwareType.value = value[0] ?? ''
formData.value.firmwareId = String(value[1]) ?? ''
})
const isShowDeviceSelect = ref(false)
watch(
() => selectFirmwareType.value,
() => {
isShowDeviceSelect.value = false
nextTick(() => {
isShowDeviceSelect.value =
!isEmpty(selectFirmwareType.value) &&
typeof selectFirmwareType.value !== 'undefined'
})
}
)
// const deviceCascaderRef = ref<InstanceType<typeof ElCascader>>()
// const cascaderDevice: CascaderProps = {
// lazy: true,
// multiple: true,
// async lazyLoad(node, resolve) {
// const { level } = node
// if (level === 0) {
// const res = await getSimpleStationList()
// if (isResError(res)) return
// const data = Array.isArray(res?.data) ? res.data : []
// const nodes = data.map((item: any) => ({
// value: item.id,
// label: item.name,
// isLeaf: false,
// }))
// resolve(nodes)
// }
// if (level === 1) {
// const res = await getSimpleDeviceList({
// siteId: node.data?.value as number,
// type: selectFirmwareType.value,
// })
// const data = Array.isArray(res?.data) ? res.data : []
// const devices = data.map((item: any) => ({
// value: item.sn,
// label: item.name,
// isLeaf: true,
// leaf: true,
// }))
// resolve(devices)
// }
// },
// }
const deviceSelect = ref<CascaderValue>([])
watch(deviceSelect, (value: any) => {
formData.value.deviceSns = value.map((item: any) => item[1])
})
function devChange() {}
const cascaderTag = ref<any[]>([])
function changeSourceType(selectItem: any) {
if (!cascaderTag.value.includes(selectItem[0])) {
deviceSelect.value = []
}
cascaderTag.value = selectItem
}
const form = {
name: '',
name: undefined,
executeNow: false, //
executeTime: '', //
executeTime: undefined, //
retryCount: 3, //
retryInterval: 1000, //
monitorTimeout: 1000, //
firmwareId: '', // ID
deviceSns: [], // SN
firmwareId: undefined, // ID
type: undefined, //
deviceSns: [], //
}
const formData = ref(cloneDeep(form))
@ -211,14 +132,15 @@ function validate() { @@ -211,14 +132,15 @@ function validate() {
message.error('请输入任务名称')
return true
}
if (!formData.value.firmwareId) {
message.error('请选择固件')
if (!formData.value.type) {
message.error('请选择设备类别')
return true
}
if (!formData.value.deviceSns.length) {
message.error('请选择设备')
if (!formData.value.firmwareId) {
message.error('请选择固件')
return true
}
if (!formData.value.executeNow && !formData.value.executeTime) {
message.error('请选择执行时间')
return true
@ -255,10 +177,49 @@ function onClone() { @@ -255,10 +177,49 @@ function onClone() {
function clearData() {
formData.value = cloneDeep(form)
firmwareSelect.value = []
cascaderTag.value = []
deviceSelect.value = []
}
const categoryTreeData = ref<ICategoryTree[]>([])
async function loadDeviceTypeTree() {
const res = await getCategoryTree()
if (!isResError(res)) {
categoryTreeData.value = res.data
}
}
const firmwareList = ref<any[]>([])
async function loadFirmwareList(value: boolean) {
if (!value) return
const res = await getSimpleFirmwareList({ type: formData.value.type as any })
if (!isResError(res)) {
firmwareList.value = res.data
}
}
const deviceList = ref<any[]>([])
async function loadDeviceList(value: boolean) {
if (!value) return
const res = await getSimpleDeviceList({ categoryId: formData.value.type as any })
if (!isResError(res)) {
deviceList.value = res.data
}
}
onMounted(async () => {
await loadDeviceTypeTree()
if (route.query.categoryId) {
formData.value.type = Number(route.query.categoryId)
await loadFirmwareList(true)
await loadDeviceList(true)
}
if (route.query.deviceSn) {
formData.value.deviceSns = [route.query.deviceSn]
}
if (route.query.firmwareId) {
formData.value.firmwareId = Number(route.query.firmwareId)
}
})
</script>
<style lang="scss">
@ -277,9 +238,6 @@ function clearData() { @@ -277,9 +238,6 @@ function clearData() {
<style scoped lang="scss">
.create-task-dlg {
.dlg-body {
max-height: 400px;
}
.el-row {
height: 32px;
width: 74%;

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

@ -113,8 +113,9 @@ import createTaskDlg from './components/create-task-dlg.vue' @@ -113,8 +113,9 @@ 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'
const route = useRoute()
const message = useMessage()
const createIcon = useIcon({ icon: 'gravity-ui:plus' })
@ -174,10 +175,14 @@ async function onDetails(row: any) { @@ -174,10 +175,14 @@ async function onDetails(row: any) {
rowData.value = row
isShowDetails.value = true
}
const queryType = route.query.type
onMounted(async () => {
await loadData()
addListener(socketMsgListener)
if(queryType === 'create') {
addTask()
}
})
onBeforeUnmount(() => {
@ -351,6 +356,8 @@ function updateTaskData() { @@ -351,6 +356,8 @@ function updateTaskData() {
// test(item.type, item.stationId, item.data, item.time)
// }
// }, 1000)
</script>
<style scoped lang="scss">

2
src/pages/socket_server/index.ts

@ -21,4 +21,4 @@ export function openSocket() { @@ -21,4 +21,4 @@ export function openSocket() {
export function closeSocket() {
worker.postMessage({ cmd: WorkerCMD.STOP })
// worker.terminate()
}
}

3
src/pages/system/deviceField/components/CategoryDlg.vue

@ -20,6 +20,7 @@ @@ -20,6 +20,7 @@
checkStrictly: true,
value: 'id',
label: 'name',
emitPath: false,
}"
clearable
/>
@ -115,7 +116,7 @@ function formatterParams(params: CategoryOV): CategoryOV { @@ -115,7 +116,7 @@ function formatterParams(params: CategoryOV): CategoryOV {
let obj = {} as CategoryOV
for (const key of [...Object.keys(createFrom), 'id'] as (keyof CategoryOV)[]) {
if (params[key] !== undefined) {
obj[key] = key === 'pid' ? params[key][params.pid.length - 1] : params[key]
obj[key] = params[key]
}
}
return obj

Loading…
Cancel
Save