pqdif
This commit is contained in:
@@ -19,6 +19,7 @@ export namespace DevType {
|
||||
id: string; //设备类型ID
|
||||
name: string;//设备类型名称
|
||||
icd: string| null;//设备关联的ICD
|
||||
pqdif: string| null;//设备关联的PQDIF
|
||||
power: string| null;//工作电源
|
||||
devVolt: number; //额定电压(V)
|
||||
devCurr: number; //额定电流(A)
|
||||
@@ -38,4 +39,4 @@ export namespace DevType {
|
||||
export interface ResPqDevTypePage extends ResPage<ResPqDevType> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
frontend/src/api/device/interface/pqdif.ts
Normal file
26
frontend/src/api/device/interface/pqdif.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { ReqPage, ResPage } from '@/api/interface'
|
||||
|
||||
export namespace PQDIF {
|
||||
export interface ReqPQDIFParams extends ReqPage {
|
||||
name?: string
|
||||
result?: number
|
||||
}
|
||||
|
||||
export interface ResPQDIF {
|
||||
id: string
|
||||
name: string
|
||||
filePath?: string | null
|
||||
recordCount?: number | null
|
||||
observationCount?: number | null
|
||||
sampleValueCount?: number | null
|
||||
result?: number | null
|
||||
msg?: string | null
|
||||
state: number
|
||||
createBy?: string | null
|
||||
createTime?: string | null
|
||||
updateBy?: string | null
|
||||
updateTime?: string | null
|
||||
}
|
||||
|
||||
export interface ResPQDIFPage extends ResPage<ResPQDIF> {}
|
||||
}
|
||||
14
frontend/src/api/device/pqdif/index.ts
Normal file
14
frontend/src/api/device/pqdif/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { PQDIF } from '@/api/device/interface/pqdif'
|
||||
import http from '@/api'
|
||||
|
||||
export const getPQDIFList = (params: PQDIF.ReqPQDIFParams) => {
|
||||
return http.post<PQDIF.ResPQDIFPage>('/pqdif/list', params)
|
||||
}
|
||||
|
||||
export const getPQDIFAllList = () => {
|
||||
return http.get<PQDIF.ResPQDIF[]>('/pqdif/listAll')
|
||||
}
|
||||
|
||||
export const importPQDIFJson = (params: FormData) => {
|
||||
return http.upload('/pqdif/import/json', params, { loading: false })
|
||||
}
|
||||
171
frontend/src/components/JsonImportDialog/index.vue
Normal file
171
frontend/src/components/JsonImportDialog/index.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="title"
|
||||
width="460px"
|
||||
destroy-on-close
|
||||
:close-on-click-modal="!loading"
|
||||
:show-close="!loading"
|
||||
>
|
||||
<div v-loading="loading" :element-loading-text="loadingText" class="json-import-content">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
action="#"
|
||||
class="upload"
|
||||
:auto-upload="false"
|
||||
:limit="1"
|
||||
accept=".json,application/json"
|
||||
:on-exceed="handleExceed"
|
||||
:on-change="handleChange"
|
||||
:on-remove="handleRemove"
|
||||
:disabled="loading"
|
||||
>
|
||||
<el-button type="primary" :icon="Upload" :disabled="loading">选择文件</el-button>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">{{ tip }}</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<div v-if="loading" class="json-import-loading-text">{{ loadingText }}</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :disabled="loading" @click="close">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="submit">开始导入</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Upload } from '@element-plus/icons-vue'
|
||||
import {
|
||||
ElMessage,
|
||||
ElNotification,
|
||||
genFileId,
|
||||
type UploadFile,
|
||||
type UploadInstance,
|
||||
type UploadProps,
|
||||
type UploadRawFile
|
||||
} from 'element-plus'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
title: string
|
||||
requestApi: (params: FormData) => Promise<unknown>
|
||||
tip?: string
|
||||
loadingText?: string
|
||||
successMessage?: string
|
||||
}>(),
|
||||
{
|
||||
tip: '请上传 .json 文件',
|
||||
loadingText: '导入中,请稍候...',
|
||||
successMessage: '导入成功'
|
||||
}
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'success'): void
|
||||
}>()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const loading = ref(false)
|
||||
const uploadRef = ref<UploadInstance | null>(null)
|
||||
const selectedFile = ref<File | null>(null)
|
||||
|
||||
const open = () => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
if (loading.value) {
|
||||
return
|
||||
}
|
||||
dialogVisible.value = false
|
||||
selectedFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
}
|
||||
|
||||
const isJsonFile = (file: UploadRawFile | File) => {
|
||||
return file.name.toLowerCase().endsWith('.json') || file.type === 'application/json'
|
||||
}
|
||||
|
||||
const notifyInvalidFile = () => {
|
||||
ElNotification({
|
||||
title: '温馨提示',
|
||||
message: '上传文件只能是 json 格式!',
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
|
||||
const setSelectedFile = (file: UploadRawFile | File | undefined) => {
|
||||
if (!file) {
|
||||
selectedFile.value = null
|
||||
return
|
||||
}
|
||||
if (!isJsonFile(file)) {
|
||||
notifyInvalidFile()
|
||||
selectedFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
return
|
||||
}
|
||||
selectedFile.value = file
|
||||
}
|
||||
|
||||
const handleExceed: UploadProps['onExceed'] = files => {
|
||||
uploadRef.value?.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
uploadRef.value?.handleStart(file)
|
||||
setSelectedFile(file)
|
||||
}
|
||||
|
||||
const handleChange = (uploadFile: UploadFile) => {
|
||||
setSelectedFile(uploadFile.raw as File | undefined)
|
||||
}
|
||||
|
||||
const handleRemove = () => {
|
||||
selectedFile.value = null
|
||||
}
|
||||
|
||||
const submit = async () => {
|
||||
if (loading.value) {
|
||||
return
|
||||
}
|
||||
if (!selectedFile.value) {
|
||||
ElMessage.warning('请选择文件!')
|
||||
return
|
||||
}
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append('file', selectedFile.value)
|
||||
loading.value = true
|
||||
try {
|
||||
await props.requestApi(formData)
|
||||
ElMessage.success(props.successMessage)
|
||||
dialogVisible.value = false
|
||||
selectedFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
emit('success')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.json-import-content {
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.json-import-loading-text {
|
||||
margin-top: 12px;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
@@ -192,7 +192,7 @@ export default class SocketService {
|
||||
* WebSocket连接配置
|
||||
*/
|
||||
private config: SocketConfig = {
|
||||
url: `ws://127.0.0.1:7778/hello`,
|
||||
url: `ws://127.0.0.1:7777/hello`,
|
||||
heartbeatInterval: 9000, // 9秒心跳间隔
|
||||
reconnectDelay: 5000, // 5秒重连延迟
|
||||
maxReconnectAttempts: 5, // 最多重连5次
|
||||
|
||||
@@ -65,6 +65,16 @@
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备关联PQDIF" prop="pqdif" >
|
||||
<el-select v-model="formContent.pqdif" clearable placeholder="请选择PQDIF">
|
||||
<el-option
|
||||
v-for="item in pqdifOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="录波指令" prop="waveCmd" v-if="modeStore.currentMode == '比对式'">
|
||||
<el-input v-model='formContent.waveCmd' placeholder="请输入录波指令" maxlength="32" show-word-limit/>
|
||||
@@ -89,6 +99,7 @@
|
||||
import { ref,computed, Ref } from 'vue'
|
||||
import { type DevType } from '@/api/device/interface/devType'
|
||||
import { type ICD } from '@/api/device/interface/icd'
|
||||
import { type PQDIF } from '@/api/device/interface/pqdif'
|
||||
import {dialogMiddle} from '@/utils/elementBind'
|
||||
import { useDictStore } from '@/stores/modules/dict'
|
||||
import {addDevType,updateDevType} from '@/api/device/devType'
|
||||
@@ -100,6 +111,7 @@
|
||||
const dialogFormRef = ref()
|
||||
const scene = ref('')
|
||||
const icdOptions = ref<ICD.StandardOption[]>([])
|
||||
const pqdifOptions = ref<PQDIF.ResPQDIF[]>([])
|
||||
function useMetaInfo() {
|
||||
const dialogVisible = ref(false)
|
||||
const titleType = ref('add')
|
||||
@@ -107,6 +119,7 @@
|
||||
id: '', //设备类型ID
|
||||
name: '',//设备类型名称
|
||||
icd: '',//设备关联的ICD
|
||||
pqdif: '',//设备关联的PQDIF
|
||||
power: 'AC/DC 110V-220V',//工作电源
|
||||
devVolt: 57.74, //额定电压(V)
|
||||
devCurr: 5, //额定电流(A)
|
||||
@@ -127,6 +140,7 @@ const resetFormContent = () => {
|
||||
id: '', //设备类型ID
|
||||
name: '',//设备类型名称
|
||||
icd: '',//设备关联的ICD
|
||||
pqdif: '',//设备关联的PQDIF
|
||||
power: 'AC/DC 110V-220V',//工作电源
|
||||
devVolt: 57.74, //额定电压(V)
|
||||
devCurr: 5, //额定电流(A)
|
||||
@@ -174,6 +188,9 @@ const resetFormContent = () => {
|
||||
],
|
||||
icd: [
|
||||
{ required: true, message: '设备关联ICD必选!', trigger: 'change' }
|
||||
],
|
||||
pqdif: [
|
||||
{ required: true, message: '设备关联PQDIF必选!', trigger: 'change' }
|
||||
]
|
||||
};
|
||||
|
||||
@@ -209,13 +226,14 @@ const close = () => {
|
||||
}
|
||||
|
||||
// 打开弹窗,可能是新增,也可能是编辑
|
||||
const open = async (sign: string, data: DevType.ResPqDevType,icd: ICD.StandardOption[],currentScene: string) => {
|
||||
const open = async (sign: string, data: DevType.ResPqDevType,icd: ICD.StandardOption[],pqdif: PQDIF.ResPQDIF[],currentScene: string) => {
|
||||
// 重置表单
|
||||
dialogFormRef.value?.resetFields()
|
||||
titleType.value = sign
|
||||
dialogVisible.value = true
|
||||
scene.value = currentScene
|
||||
icdOptions.value = icd
|
||||
pqdifOptions.value = pqdif
|
||||
|
||||
if (data.id) {
|
||||
formContent.value = { ...data }
|
||||
|
||||
@@ -45,6 +45,8 @@ import { onBeforeMount, reactive, ref } from 'vue'
|
||||
import { useModeStore, useAppSceneStore } from '@/stores/modules/mode'
|
||||
import { getICDAllList } from '@/api/device/icd'
|
||||
import type { ICD } from '@/api/device/interface/icd'
|
||||
import { getPQDIFAllList } from '@/api/device/pqdif'
|
||||
import type { PQDIF } from '@/api/device/interface/pqdif'
|
||||
|
||||
// defineOptions({
|
||||
// name: 'devType',
|
||||
@@ -56,6 +58,7 @@ import type { ICD } from '@/api/device/interface/icd'
|
||||
const proTable = ref<ProTableInstance>()
|
||||
const devTypePopup = ref()
|
||||
const icdOptions = ref<ICD.StandardOption[]>([])
|
||||
const pqdifOptions = ref<PQDIF.ResPQDIF[]>([])
|
||||
|
||||
const getTableList = async (params: any) => {
|
||||
let newParams = JSON.parse(JSON.stringify(params))
|
||||
@@ -111,6 +114,15 @@ import type { ICD } from '@/api/device/interface/icd'
|
||||
return <span>{name?.name}</span>
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: 'pqdif',
|
||||
label: '设备关联PQDIF',
|
||||
minWidth: 200,
|
||||
render: (scope) => {
|
||||
const name = pqdifOptions.value.find(option => option.id === scope.row.pqdif)
|
||||
return <span>{name?.name || '--'}</span>
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建时间',
|
||||
@@ -136,7 +148,7 @@ import type { ICD } from '@/api/device/interface/icd'
|
||||
|
||||
// 打开 drawer(新增、编辑)
|
||||
const openDialog = (titleType: string, row: Partial<DevType.ResPqDevType> = {}) => {
|
||||
devTypePopup.value?.open(titleType, row,icdOptions.value,appSceneStore.currentScene)
|
||||
devTypePopup.value?.open(titleType, row,icdOptions.value,pqdifOptions.value,appSceneStore.currentScene)
|
||||
}
|
||||
|
||||
|
||||
@@ -156,11 +168,12 @@ import type { ICD } from '@/api/device/interface/icd'
|
||||
|
||||
|
||||
onBeforeMount(async () => {
|
||||
const response = await getICDAllList()
|
||||
const [response, pqdifResponse] = await Promise.all([getICDAllList(), getPQDIFAllList()])
|
||||
icdOptions.value = (response.data as ICD.ResICD[]).map(item => ({
|
||||
id: item.id,
|
||||
name: item.name
|
||||
}))
|
||||
pqdifOptions.value = pqdifResponse.data as PQDIF.ResPQDIF[]
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
@@ -33,50 +33,20 @@
|
||||
</ProTable>
|
||||
</div>
|
||||
<IcdPopup ref="icdPopup" :refresh-table="proTable?.getTableList" />
|
||||
<el-dialog
|
||||
v-model="importDialogVisible"
|
||||
<JsonImportDialog
|
||||
ref="jsonImportDialog"
|
||||
title="导入ICD"
|
||||
width="460px"
|
||||
destroy-on-close
|
||||
:close-on-click-modal="!importLoading"
|
||||
:show-close="!importLoading"
|
||||
>
|
||||
<div v-loading="importLoading" element-loading-text="导入中,请稍候..." class="icd-import-content">
|
||||
<el-upload
|
||||
ref="importUploadRef"
|
||||
action="#"
|
||||
class="upload"
|
||||
:auto-upload="false"
|
||||
:limit="1"
|
||||
accept=".json,application/json"
|
||||
:on-exceed="handleImportExceed"
|
||||
:before-upload="beforeImportUpload"
|
||||
:on-change="handleImportChange"
|
||||
:on-remove="handleImportRemove"
|
||||
:disabled="importLoading"
|
||||
>
|
||||
<el-button type="primary" :icon="Upload" :disabled="importLoading">选择文件</el-button>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">请上传 .json 文件</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<div v-if="importLoading" class="icd-import-loading-text">导入中,请稍候...</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :disabled="importLoading" @click="closeImportDialog">取消</el-button>
|
||||
<el-button type="primary" :loading="importLoading" @click="submitImport">开始导入</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
:request-api="importICDJson"
|
||||
@success="handleImportSuccess"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx" name="useIcd">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { CirclePlus, Delete, Download, EditPen, Upload } from '@element-plus/icons-vue'
|
||||
import { ElMessage, ElNotification, genFileId, type UploadFile, type UploadInstance, type UploadProps, type UploadRawFile } from 'element-plus'
|
||||
import type { ICD } from '@/api/device/interface/icd'
|
||||
import ProTable from '@/components/ProTable/index.vue'
|
||||
import JsonImportDialog from '@/components/JsonImportDialog/index.vue'
|
||||
import type { ColumnProps, ProTableInstance } from '@/components/ProTable/interface'
|
||||
import { useHandleData } from '@/hooks/useHandleData'
|
||||
import { useDownloadWithServerFileName } from '@/hooks/useDownload'
|
||||
@@ -90,10 +60,7 @@ defineOptions({
|
||||
|
||||
const proTable = ref<ProTableInstance>()
|
||||
const icdPopup = ref<InstanceType<typeof IcdPopup>>()
|
||||
const importDialogVisible = ref(false)
|
||||
const importLoading = ref(false)
|
||||
const importUploadRef = ref<UploadInstance | null>(null)
|
||||
const selectedImportFile = ref<File | null>(null)
|
||||
const jsonImportDialog = ref<InstanceType<typeof JsonImportDialog>>()
|
||||
|
||||
const getTableList = async (params: ICD.ReqICDParams) => {
|
||||
return getICDList({ ...params })
|
||||
@@ -128,7 +95,7 @@ const columns = reactive<ColumnProps<ICD.ResICD>[]>([
|
||||
prop: 'type',
|
||||
label: '类型',
|
||||
minWidth: 180,
|
||||
enum: ICD_TYPE_OPTIONS,
|
||||
enum: [...ICD_TYPE_OPTIONS],
|
||||
fieldNames: { label: 'label', value: 'value' },
|
||||
search: {
|
||||
el: 'select',
|
||||
@@ -180,79 +147,10 @@ const handleExport = async (row: ICD.ResICD) => {
|
||||
}
|
||||
|
||||
const openImportDialog = () => {
|
||||
importDialogVisible.value = true
|
||||
jsonImportDialog.value?.open()
|
||||
}
|
||||
|
||||
const closeImportDialog = () => {
|
||||
if (importLoading.value) {
|
||||
return
|
||||
}
|
||||
importDialogVisible.value = false
|
||||
selectedImportFile.value = null
|
||||
importUploadRef.value?.clearFiles()
|
||||
}
|
||||
|
||||
const beforeImportUpload = (file: UploadRawFile) => {
|
||||
const isJsonFile = file.name.toLowerCase().endsWith('.json') || file.type === 'application/json'
|
||||
if (!isJsonFile) {
|
||||
ElNotification({
|
||||
title: '温馨提示',
|
||||
message: '上传文件只能是 json 格式!',
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
return isJsonFile
|
||||
}
|
||||
|
||||
const handleImportExceed: UploadProps['onExceed'] = files => {
|
||||
importUploadRef.value?.clearFiles()
|
||||
const file = files[0] as UploadRawFile
|
||||
file.uid = genFileId()
|
||||
importUploadRef.value?.handleStart(file)
|
||||
selectedImportFile.value = file
|
||||
}
|
||||
|
||||
const handleImportChange: UploadProps['onChange'] = uploadFile => {
|
||||
selectedImportFile.value = (uploadFile.raw as File | undefined) ?? null
|
||||
}
|
||||
|
||||
const handleImportRemove = () => {
|
||||
selectedImportFile.value = null
|
||||
}
|
||||
|
||||
const submitImport = async () => {
|
||||
if (importLoading.value) {
|
||||
return
|
||||
}
|
||||
if (!selectedImportFile.value) {
|
||||
ElMessage.warning('请选择文件!')
|
||||
return
|
||||
}
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append('file', selectedImportFile.value)
|
||||
importLoading.value = true
|
||||
try {
|
||||
await importICDJson(formData)
|
||||
ElMessage.success('导入成功')
|
||||
importDialogVisible.value = false
|
||||
selectedImportFile.value = null
|
||||
importUploadRef.value?.clearFiles()
|
||||
await proTable.value?.getTableList()
|
||||
} finally {
|
||||
importLoading.value = false
|
||||
}
|
||||
const handleImportSuccess = () => {
|
||||
proTable.value?.getTableList()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.icd-import-content {
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.icd-import-loading-text {
|
||||
margin-top: 12px;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
|
||||
142
frontend/src/views/machine/pqdif/index.vue
Normal file
142
frontend/src/views/machine/pqdif/index.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<ProTable ref="proTable" :columns="columns" :request-api="getTableList">
|
||||
<template #tableHeader>
|
||||
<el-button v-auth.pqdif="'import'" type="primary" plain :icon="Upload" @click="openImportDialog">
|
||||
导入
|
||||
</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
</div>
|
||||
<JsonImportDialog
|
||||
ref="jsonImportDialog"
|
||||
title="导入PQDIF"
|
||||
:request-api="importPQDIFJson"
|
||||
@success="handleImportSuccess"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx" name="usePqdif">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { Upload } from '@element-plus/icons-vue'
|
||||
import type { PQDIF } from '@/api/device/interface/pqdif'
|
||||
import { getPQDIFList, importPQDIFJson } from '@/api/device/pqdif'
|
||||
import ProTable from '@/components/ProTable/index.vue'
|
||||
import JsonImportDialog from '@/components/JsonImportDialog/index.vue'
|
||||
import type { ColumnProps, ProTableInstance } from '@/components/ProTable/interface'
|
||||
|
||||
defineOptions({
|
||||
name: 'pqdif'
|
||||
})
|
||||
|
||||
const proTable = ref<ProTableInstance>()
|
||||
const jsonImportDialog = ref<InstanceType<typeof JsonImportDialog>>()
|
||||
|
||||
const getTableList = async (params: PQDIF.ReqPQDIFParams) => {
|
||||
return getPQDIFList({ ...params })
|
||||
}
|
||||
|
||||
const formatDateTime = (value?: string | null) => {
|
||||
if (!value) {
|
||||
return '--'
|
||||
}
|
||||
const date = new Date(value)
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return value
|
||||
}
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
const hours = String(date.getHours()).padStart(2, '0')
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0')
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||||
}
|
||||
|
||||
const RESULT_OPTIONS = [
|
||||
{ label: '成功', value: 1 },
|
||||
{ label: '失败', value: 0 }
|
||||
]
|
||||
|
||||
const columns = reactive<ColumnProps<PQDIF.ResPQDIF>[]>([
|
||||
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
|
||||
{
|
||||
prop: 'name',
|
||||
label: 'PQDIF文件名称',
|
||||
minWidth: 180,
|
||||
search: { el: 'input' }
|
||||
},
|
||||
{
|
||||
prop: 'filePath',
|
||||
label: '原始文件路径',
|
||||
minWidth: 260,
|
||||
render: scope => scope.row.filePath || '--'
|
||||
},
|
||||
{
|
||||
prop: 'recordCount',
|
||||
label: 'Record总数',
|
||||
width: 130,
|
||||
render: scope => String(scope.row.recordCount ?? '--')
|
||||
},
|
||||
{
|
||||
prop: 'observationCount',
|
||||
label: 'Observation总数',
|
||||
width: 150,
|
||||
render: scope => String(scope.row.observationCount ?? '--')
|
||||
},
|
||||
{
|
||||
prop: 'sampleValueCount',
|
||||
label: '样例采样值数量',
|
||||
width: 160,
|
||||
render: scope => String(scope.row.sampleValueCount ?? '--')
|
||||
},
|
||||
{
|
||||
prop: 'result',
|
||||
label: '解析结果',
|
||||
width: 120,
|
||||
enum: RESULT_OPTIONS,
|
||||
fieldNames: { label: 'label', value: 'value' },
|
||||
search: {
|
||||
el: 'select',
|
||||
props: {
|
||||
clearable: true
|
||||
}
|
||||
},
|
||||
render: scope => {
|
||||
if (scope.row.result === 1) {
|
||||
return <el-tag type="success">成功</el-tag>
|
||||
}
|
||||
if (scope.row.result === 0) {
|
||||
return <el-tag type="danger">失败</el-tag>
|
||||
}
|
||||
return '--'
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'msg',
|
||||
label: '解析提示',
|
||||
minWidth: 220,
|
||||
render: scope => scope.row.msg || '--'
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建时间',
|
||||
width: 180,
|
||||
render: scope => formatDateTime(scope.row.createTime)
|
||||
},
|
||||
{
|
||||
prop: 'updateTime',
|
||||
label: '更新时间',
|
||||
width: 180,
|
||||
render: scope => formatDateTime(scope.row.updateTime)
|
||||
}
|
||||
])
|
||||
|
||||
const openImportDialog = () => {
|
||||
jsonImportDialog.value?.open()
|
||||
}
|
||||
|
||||
const handleImportSuccess = () => {
|
||||
proTable.value?.getTableList()
|
||||
}
|
||||
</script>
|
||||
14
frontend/vitest.config.ts
Normal file
14
frontend/vitest.config.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import path from "path";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
environment: "jsdom",
|
||||
include: ["frontend/src/**/*.spec.ts"]
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "src")
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user