Browse Source

fix: 设备的一些修改

master
wangqi 6 months ago
parent
commit
060c8e2e3c
  1. 1
      auto-imports.d.ts
  2. 2
      components.d.ts
  3. 9
      src/api/module/eam/device/index.ts
  4. 7
      src/api/module/eam/device/template.ts
  5. 32
      src/pages/deviceInfo/components/BasicInfo.vue
  6. 8
      src/pages/deviceInfo/components/DeliveryInfo.vue
  7. 84
      src/pages/deviceInfo/components/TestInfo.vue
  8. 46
      src/pages/deviceInfo/components/data-filter.vue
  9. 81
      src/pages/deviceInfo/components/testSheetInfoDlg.vue
  10. 1
      src/pages/deviceInfo/info.vue
  11. 15
      src/pages/deviceInfo/utils.ts
  12. 60
      src/pages/deviceStorage/components/data-filter.vue
  13. 8
      src/pages/ota/upgradeTask/index.vue
  14. 2
      src/pages/socket_server/AppSocketServer.ts
  15. 6
      src/pages/socket_server/index.ts
  16. 22
      src/pages/system/manufacturer/components/manufacturerDlg.vue
  17. 45
      src/tools/event/socketEvent.ts

1
auto-imports.d.ts vendored

@ -6,7 +6,6 @@ @@ -6,7 +6,6 @@
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const ElLoading: typeof import('element-plus/es')['ElLoading']
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
const ElNotification: typeof import('element-plus/es')['ElNotification']
const computed: typeof import('vue')['computed']

2
components.d.ts vendored

@ -32,6 +32,8 @@ declare module 'vue' { @@ -32,6 +32,8 @@ declare module 'vue' {
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElDrawer: typeof import('element-plus/es')['ElDrawer']

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

@ -24,7 +24,7 @@ export interface IDeviceOV { @@ -24,7 +24,7 @@ export interface IDeviceOV {
id?: number
name?: string
categoryId: string
templateId: string
// templateId: string
serialNo?: string
sn: string
description: string
@ -111,3 +111,10 @@ export const operantDeviceTestSheet = (type: OperantAction, params: any) => { @@ -111,3 +111,10 @@ export const operantDeviceTestSheet = (type: OperantAction, params: any) => {
})
}
}
export const getDeviceTestSheet = (params: { deviceId: number; isLast: boolean }) => {
return eamServer({
url: `/test-sheet/get-by-device-id`,
method: 'get',
params,
})
}

7
src/api/module/eam/device/template.ts

@ -57,6 +57,13 @@ export const updateSheetStatus = (id: string, status: number) => @@ -57,6 +57,13 @@ export const updateSheetStatus = (id: string, status: number) =>
data: { id, status },
})
export const getSheetDetail = (sheetId: number) =>
eamServer({
url: '/sheet-detail/get-by-sheet-id',
method: 'get',
params: { sheetId },
})
export const updateTestSheetStatus = (params: { id: number; deviceId: number }) =>
eamServer({
url: '/test-sheet/update-status',

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

@ -59,7 +59,7 @@ @@ -59,7 +59,7 @@
/>
</el-select>
</div>
<div class="from-row">
<!--<div class="from-row">
<div class="label">测试模板:</div>
<FormItemSelect
:disabled="disabled"
@ -71,6 +71,15 @@ @@ -71,6 +71,15 @@
valueTag="id"
class="input"
:isShowLabel="false"
/>
</div>-->
<div class="from-row">
<div class="label">当前固件:</div>
<number-input
class="input"
:disabled="true"
v-model="params.currentFirmwareId"
placeholder="设备暂无固件"
/>
</div>
<div class="from-row">
@ -84,15 +93,6 @@ @@ -84,15 +93,6 @@
</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
@ -101,7 +101,7 @@ @@ -101,7 +101,7 @@
type="textarea"
v-model="params.description"
placeholder="请输入备注"
:autosize="{ minRows: 3, maxRows: 4 }"
:autosize="{ minRows: 5, maxRows: 4 }"
resize="none"
/>
</div>
@ -151,7 +151,7 @@ const emit = defineEmits(['on-save']) @@ -151,7 +151,7 @@ const emit = defineEmits(['on-save'])
const paramsData: IDeviceOV = {
currentFirmwareId: '',
categoryId: '',
templateId: '',
// templateId: '',
sn: '',
serialNo: '',
description: '',
@ -222,10 +222,10 @@ function validate() { @@ -222,10 +222,10 @@ function validate() {
return false
}
if (isEmpty(params.value.templateId)) {
message.error('请选择测试模板')
return false
}
// if (isEmpty(params.value.templateId)) {
// message.error('')
// return false
// }
if (isEmpty(params.value.cost)) {
message.error('请输入设备成本')

8
src/pages/deviceInfo/components/DeliveryInfo.vue

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
:options="customerList"
placeholder="请选择出库流向"
keyTag="id"
:disabled="action === 'view'"
labelTag="name"
valueTag="id"
:isShowLabel="false"
@ -16,7 +17,11 @@ @@ -16,7 +17,11 @@
</div>
<div class="from-row">
<div class="label">设备价格:</div>
<number-input v-model="params.price" placeholder="请输入成本" />
<number-input
v-model="params.price"
:disabled="action === 'view'"
placeholder="请输入成本"
/>
</div>
</div>
<div class="group-box">
@ -26,6 +31,7 @@ @@ -26,6 +31,7 @@
type="textarea"
v-model="params.description"
placeholder="请输入备注"
:disabled="action === 'view'"
:autosize="{ minRows: 3, maxRows: 4 }"
/>
</div>

84
src/pages/deviceInfo/components/TestInfo.vue

@ -10,23 +10,22 @@ @@ -10,23 +10,22 @@
>
<template v-for="(col, idx) in testTableCol" :key="idx">
<el-table-column
v-if="col.prop === 'actualResult'"
v-if="col.prop.endsWith('Time')"
:label="col.label"
:min-width="col.minWidth"
>
<template #default="scope">
<el-radio-group
v-if="isShowSaveButton"
v-model="scope.row[col.prop]"
@change="onChangeRadio(scope.row)"
>
<template v-for="item in testSheetStatus">
<el-radio :value="item.value">{{ item.label }}</el-radio>
</template>
</el-radio-group>
<div v-else>
{{ testSheetStatus.find(r => r.value === scope.row.status)?.label ?? '' }}
</div>
{{ 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"
:min-width="col.minWidth"
>
<template #default="scope">
{{ testSheetStatus.find(item => item.value === scope.row.status)?.label }}
</template>
</el-table-column>
<el-table-column
@ -36,6 +35,16 @@ @@ -36,6 +35,16 @@
:min-width="col.minWidth"
/>
</template>
<el-table-column label="操作" width="190" align="center">
<template #default="scope">
<EdfsButton
link
type="primary"
inner-text="查看详情"
@click="loadSheetDetail(scope.row)"
/>
</template>
</el-table-column>
</EdfsTable>
<EdfsButton
inner-text="提交并入库"
@ -46,24 +55,34 @@ @@ -46,24 +55,34 @@
/>
</div>
</div>
<testSheetInfoDlg
:info="sheetDetail"
:title="curSheetDetailName"
:isShow="isShowDetail"
@on-close="isShowDetail = false"
/>
</template>
<script setup lang="ts">
import dayjs from 'dayjs'
import EdfsTable from '@/components/dashboard/Edfs-table/index.vue'
import EdfsButton from '@/components/dashboard/Edfs-button/index.vue'
import { testSheetStatus, testTableCol, type OptAction } from '../utils'
import {
getSheetDetail,
updateSheetStatus,
updateTestSheetStatus,
} from '@/api/module/eam/device/template'
import { isResError, useMessage } from '@/hooks/useMessage'
import type { IDevice } from '@/api/module/eam/device'
import { getDeviceTestSheet, type IDevice } from '@/api/module/eam/device'
import { useRoute } from 'vue-router'
import testSheetInfoDlg from './testSheetInfoDlg.vue'
const route = useRoute()
const action = route.query.action as OptAction
const massage = useMessage()
const props = defineProps<{
disabled: boolean
deviceId: number | undefined
info: IDevice | undefined
}>()
@ -73,15 +92,6 @@ const isShowSaveButton = computed(() => { @@ -73,15 +92,6 @@ const isShowSaveButton = computed(() => {
if (action === 'view') return false
return props.info?.status === undefined ? true : props.info.status < 2
})
watch(
() => props.info,
val => {
if (val) {
list.value = Array.isArray(val?.testSheetDetail) ? val.testSheetDetail : []
}
},
{ immediate: true }
)
async function onChangeRadio(row: any) {
const res = await updateSheetStatus(row.id, row.actualResult)
@ -98,6 +108,34 @@ async function onSave() { @@ -98,6 +108,34 @@ async function onSave() {
if (isResError(res)) return
emit('onSave')
}
async function loadDeviceTestSheet() {
const res = await getDeviceTestSheet({
deviceId: props.deviceId as number,
isLast: true,
})
if (isResError(res)) return
list.value = res.data
}
const isShowDetail = ref(false)
const sheetDetail = ref<any>([])
const curSheetDetailName = ref<any>()
async function loadSheetDetail(row: any) {
const res = await getSheetDetail(row.id)
if (isResError(res)) return
sheetDetail.value = res.data
isShowDetail.value = true
curSheetDetailName.value = row.name
}
watch(
() => props.deviceId,
newVal => {
if (newVal) {
loadDeviceTestSheet()
}
}
)
</script>
<style scoped lang="scss">

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

@ -32,10 +32,10 @@ @@ -32,10 +32,10 @@
</el-config-provider>
</div>
<div class="item">
<!-- <div class="item">
<el-input placeholder="请输入设备序列号" v-model="filterData.serialNo" />
<el-checkbox v-model="checkbox.serialNo" size="large" />
</div>
</div> -->
<div class="item">
<el-input placeholder="请输入设备sn" v-model="filterData.sn" />
<el-checkbox v-model="checkbox.sn" size="large" />
@ -89,9 +89,12 @@ import dayjs from 'dayjs' @@ -89,9 +89,12 @@ import dayjs from 'dayjs'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import EdfsButton from '@/components/dashboard/Edfs-button/index.vue'
import { DeviceStatus, enumToKeyValueArray } from '../utils'
import { useMessage } from '@/hooks/useMessage'
import type { CustomerVO } from '@/api/module/eam/customer'
const msg = useMessage()
const locale = zhCn
const prop = defineProps<{
@ -112,7 +115,7 @@ const filterData = ref({ @@ -112,7 +115,7 @@ const filterData = ref({
endDay: '',
sn: '',
status: '',
serialNo: '',
// serialNo: '',
categoryId: '',
})
@ -120,15 +123,50 @@ const checkbox = ref<Record<FilterKeys, boolean>>({ @@ -120,15 +123,50 @@ const checkbox = ref<Record<FilterKeys, boolean>>({
startDay: false,
endDay: false,
sn: false,
serialNo: false,
// serialNo: false,
status: false,
categoryId: false,
})
watch(
() => checkbox.value.startDay,
val => {
checkbox.value.endDay = val
}
)
watch(
() => checkbox.value.endDay,
val => {
checkbox.value.startDay = val
}
)
function onSearch() {
if (!validate()) return
emit('search', formatParams())
}
const placeholderMap = {
startDay: '请选择开始时间',
endDay: '请选择结束时间',
sn: '请输入设备sn',
status: '请选择设备状态',
categoryId: '请选择设备分类',
}
function validate() {
const keys = Object.entries(checkbox.value)
.filter(([, value]) => value)
.map(([key]) => key as FilterKeys)
for (const element of keys) {
if (!filterData.value[element]) {
msg.error('请输入' + placeholderMap[element])
return false
}
}
return true
}
function formatParams() {
const params: Partial<Record<FilterKeys, string>> = {}
const keys = Object.keys(checkbox.value) as FilterKeys[]

81
src/pages/deviceInfo/components/testSheetInfoDlg.vue

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
<template>
<EdfsDialog
class="test-sheet-info-dlg"
:title="title"
:isShow="isShow"
width="70%"
:isShowFooter="false"
@on-close="onClone"
@on-save="onClone"
>
<div class="dlg-body">
<EdfsTable
class="table"
:data="info"
:usePaging="false"
:highlight-current-row="true"
row-class-name="row"
>
<template v-for="(col, idx) in tableCol" :key="idx">
<!-- <el-table-column
v-if="col.prop.endsWith('Time')"
:label="col.label"
:min-width="col.minWidth"
>
<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"
:min-width="col.minWidth"
>
<template #default="scope">
{{ testSheetStatus.find(item => item.value === scope.row.status)?.label }}
</template>
</el-table-column> -->
<el-table-column
:prop="col.prop"
:label="col.label"
:min-width="col.minWidth"
/>
</template>
</EdfsTable>
</div>
</EdfsDialog>
</template>
<script setup lang="ts">
import EdfsDialog from '@/components/dashboard/Edfs-dialog.vue'
const props = defineProps<{
isShow: boolean
info: any
title: string
}>()
const emits = defineEmits(['on-close'])
const title = computed(() => `${props.title}测试详情`)
const tableCol = [
{ prop: 'content', label: '测试内容', minWidth: '12%' },
{ prop: 'actualResult', label: '实际结果', minWidth: '8%' },
{ prop: 'expectResult', label: '预期结果', minWidth: '8%' },
{ prop: 'remark', label: '备注', minWidth: '20%' },
]
function onClone() {
emits('on-close')
}
</script>
<style scoped lang="scss">
.test-sheet-info-dlg {
.dlg-body {
height: 700px;
.table {
height: 100%;
}
}
}
</style>

1
src/pages/deviceInfo/info.vue

@ -30,6 +30,7 @@ @@ -30,6 +30,7 @@
/>
<TestInfo
v-else-if="item.name === 'test'"
:deviceId="deviceInfoId"
:info="deviceInfo"
:disabled="isDisabledTest"
@onSave="loadDeviceInfo"

15
src/pages/deviceInfo/utils.ts

@ -3,6 +3,7 @@ export enum DeviceStatus { @@ -3,6 +3,7 @@ export enum DeviceStatus {
,
,
,
,
}
export const deviceTableCol = [
{ label: '设备sn', prop: 'sn', minWidth: '10%' },
@ -41,16 +42,18 @@ export const testSheetStatus = [ @@ -41,16 +42,18 @@ export const testSheetStatus = [
]
export const testTableCol = [
{ label: '测试内容', prop: 'content', minWidth: '10%' },
{ label: '预计结果', prop: 'expectResult', minWidth: '10%' },
{ label: '测试结果', prop: 'actualResult', minWidth: '20%' },
{ label: '工单名称', prop: 'name', minWidth: '20%' },
{ label: '最终测试结果', prop: 'status', minWidth: '10%' },
{ label: '创建时间', prop: 'createTime', minWidth: '18%' },
{ label: '备注', prop: 'description', minWidth: '16%' },
]
export function enumToKeyValueArray(enumObj: object): Array<{ label: string; value: number }> {
export function enumToKeyValueArray(
enumObj: object
): Array<{ label: string; value: number }> {
return Object.keys(enumObj)
.filter(key => isNaN(Number(key))) // 排除反向映射的数值键
.map(key => ({
label: key,
value: enumObj[key as keyof typeof enumObj] as number,
}));
}
}))
}

60
src/pages/deviceStorage/components/data-filter.vue

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
<template>
<el-scrollbar class="storage-data-filter">
<el-scrollbar class="storage-data-filter">
<div class="time-item">
<el-config-provider :locale="locale">
<span>开始时间:</span>
@ -56,7 +56,7 @@ @@ -56,7 +56,7 @@
:value="item.value"
/>
</el-select>
<el-checkbox v-model="checkbox.status" size="large" disabled/>
<el-checkbox v-model="checkbox.status" size="large" disabled />
</div>
<div class="item item-btn">
<EdfsButton
@ -65,6 +65,7 @@ @@ -65,6 +65,7 @@
style="width: 100%"
@click="onSearch"
/>
<EdfsButton inner-text="重置" style="width: 100%" @click="onReset" />
</div>
</el-scrollbar>
</template>
@ -77,8 +78,10 @@ import { getIntDictOptions } from '@/utils/dict' @@ -77,8 +78,10 @@ import { getIntDictOptions } from '@/utils/dict'
import { isResError } from '@/hooks/useMessage'
import type { CustomerVO } from '@/api/module/eam/customer'
import { statusList } from '../utils'
import { useMessage } from '@/hooks/useMessage'
const locale = zhCn
const msg = useMessage()
const prop = defineProps<{
customerList: Array<Pick<CustomerVO, 'id' | 'name'>>
@ -111,10 +114,46 @@ const checkbox = ref<Record<FilterKeys, boolean>>({ @@ -111,10 +114,46 @@ const checkbox = ref<Record<FilterKeys, boolean>>({
customerId: false,
})
watch(
() => checkbox.value.startDay,
val => {
checkbox.value.endDay = val
}
)
watch(
() => checkbox.value.endDay,
val => {
checkbox.value.startDay = val
}
)
function onSearch() {
if (!validate()) return
emit('search', formatParams())
}
const placeholderMap = {
startDay: '开始时间',
endDay: '终止时间',
sn: '设备SN',
customerId: '客户',
}
function validate() {
const keys = Object.entries(checkbox.value)
.filter(([, value]) => value)
.map(([key]) => key as FilterKeys)
for (const element of keys) {
if (!filterData.value[element]) {
msg.error('请输入' + placeholderMap[element])
return false
}
}
return true
}
function formatParams() {
const params: Partial<Record<FilterKeys, string>> = {}
const keys = Object.keys(checkbox.value) as FilterKeys[]
@ -130,6 +169,23 @@ function formatParams() { @@ -130,6 +169,23 @@ function formatParams() {
return params
}
function onReset() {
filterData.value = {
startDay: '',
endDay: '',
status: 3,
sn: '',
customerId: '',
}
checkbox.value = {
startDay: false,
endDay: false,
status: true,
sn: false,
customerId: false,
}
}
onMounted(() => {
onSearch()
})

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

@ -113,7 +113,7 @@ import createTaskDlg from './components/create-task-dlg.vue' @@ -113,7 +113,7 @@ 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 { useRoute } from 'vue-router'
import { getTaskList } from '@/api/module/eam/device/task'
const route = useRoute()
const message = useMessage()
@ -180,7 +180,7 @@ const queryType = route.query.type @@ -180,7 +180,7 @@ const queryType = route.query.type
onMounted(async () => {
await loadData()
addListener(socketMsgListener)
if(queryType === 'create') {
if (queryType === 'create') {
addTask()
}
})
@ -192,7 +192,7 @@ const detailsRef = ref<any>(null) @@ -192,7 +192,7 @@ const detailsRef = ref<any>(null)
const tasksStatusMap = new Map()
const socketMsgListener: SocketMsgListener = {
onCmdPost: function (type: string, stationId: number, data?: any, time?: string) {
onCmdPost: function (type: string, data?: any, time?: string) {
if (type === 'upgrade') {
const { deviceSn, taskId } = data
if (!taskId || !deviceSn) return
@ -356,8 +356,6 @@ function updateTaskData() { @@ -356,8 +356,6 @@ function updateTaskData() {
// test(item.type, item.stationId, item.data, item.time)
// }
// }, 1000)
</script>
<style scoped lang="scss">

2
src/pages/socket_server/AppSocketServer.ts

@ -14,7 +14,7 @@ if (import.meta.env.PROD) { @@ -14,7 +14,7 @@ if (import.meta.env.PROD) {
}
const onMessage = (data: any) => {
if (!data.type || !data.stationId) {
if (!data.type) {
return
}
postMessage(data)

6
src/pages/socket_server/index.ts

@ -5,8 +5,8 @@ import { getToken } from '@/utils/auth' @@ -5,8 +5,8 @@ import { getToken } from '@/utils/auth'
const worker = new SocketServer()
worker.onmessage = e => {
const { type, stationId, data, time } = e.data
publish({ type, stationId, data, time })
const { type, data, time } = e.data
publish({ type, data, time })
}
export function openSocket() {
@ -21,4 +21,4 @@ export function openSocket() { @@ -21,4 +21,4 @@ export function openSocket() {
export function closeSocket() {
worker.postMessage({ cmd: WorkerCMD.STOP })
// worker.terminate()
}
}

22
src/pages/system/manufacturer/components/manufacturerDlg.vue

@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
</el-row>
<el-row>
<FormItemInput v-model="formData.email" label="邮箱:" require />
<FormItemInput v-model="formData.email" label="邮箱:" />
</el-row>
<el-row>
@ -102,8 +102,24 @@ async function onSave() { @@ -102,8 +102,24 @@ async function onSave() {
}
function validate() {
// if (isEmpty(formData.value.type)) {
// message.error('')
if (isEmpty(formData.value.name)) {
message.error('请输入厂商名称')
return false
}
if (isEmpty(formData.value.address)) {
message.error('请输入地址')
return false
}
if (isEmpty(formData.value.phone)) {
message.error('请输入联系电话')
return false
}
if (isEmpty(formData.value.contact)) {
message.error('请输入联系人')
return false
}
// if (isEmpty(formData.value.email)) {
// message.notifyWarning('')
// return false
// }

45
src/tools/event/socketEvent.ts

@ -1,39 +1,38 @@ @@ -1,39 +1,38 @@
import Emitter from "./eventBus";
import Emitter from './eventBus'
export interface SocketEvent {
type: string;
stationId: number;
data?: any;
time?: any;
type: string
data?: any
time?: any
}
export interface SocketMsgListener {
onCmdPost(type: string, stationId: number, data?: any, time?:any): void;
onCmdPost(type: string, data?: any, time?: any): void
}
let listeners: SocketMsgListener[] = [];
let listeners: SocketMsgListener[] = []
export function addListener(listener: SocketMsgListener) {
if (listeners.length === 0) {
Emitter.on("socketMsg", (event: SocketEvent) => {
if (!event) {
return;
}
for (const listener of listeners) {
listener.onCmdPost(event.type, event.stationId, event.data, event.time);
}
});
}
listeners.push(listener);
if (listeners.length === 0) {
Emitter.on('socketMsg', (event: SocketEvent) => {
if (!event) {
return
}
for (const listener of listeners) {
listener.onCmdPost(event.type, event.data, event.time)
}
})
}
listeners.push(listener)
}
export function removeListener(listener: SocketMsgListener) {
listeners = listeners.filter((item) => item !== listener);
if (listeners.length === 0) {
Emitter.off("socketMsg");
}
listeners = listeners.filter(item => item !== listener)
if (listeners.length === 0) {
Emitter.off('socketMsg')
}
}
export function publish(event: SocketEvent) {
Emitter.emit("socketMsg", event);
Emitter.emit('socketMsg', event)
}

Loading…
Cancel
Save