UPDATE:优化完善新增编辑检测计划绑定被检设备

This commit is contained in:
贾同学
2025-08-12 20:42:48 +08:00
parent 919e81da8b
commit ce8607af36
3 changed files with 881 additions and 660 deletions

View File

@@ -77,7 +77,7 @@
"vite-plugin-compression": "^0.5.1",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-html": "^3.2.0",
"vite-plugin-node-polyfills": "^0.23.0",
"vite-plugin-node-polyfills": "^0.24.0",
"vite-plugin-pwa": "^0.16.5",
"vite-plugin-svg-icons": "^2.0.1",
"vue-tsc": "^2.0.21"

View File

@@ -1,15 +1,40 @@
<template>
<!-- 基础信息弹出框 -->
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="planType == 0 ? dialogBig : dialogMiddle" align-center>
<div>
<el-dialog
:title="dialogTitle"
v-if="dialogVisible"
v-model="dialogVisible"
@close="close"
v-bind="dialogBig"
align-center
>
<el-row :gutter="24">
<el-col :span="planType == 0 ? 12 : 24">
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' >
<el-col :span="planType == 0 ? 10 : 24">
<el-form :model="formContent" ref="dialogFormRef" :rules="rules">
<el-form-item label="名称" prop="name" :label-width="110">
<el-input v-model="formContent.name" placeholder="请输入名称" autocomplete="off" maxlength="32" show-word-limit/>
<el-input
v-model="formContent.name"
placeholder="请输入名称"
autocomplete="off"
maxlength="32"
show-word-limit
/>
</el-form-item>
<el-form-item label='标准设备' prop='standardDevIds' :label-width='110' v-if="selectByMode && planType == 0" >
<el-select v-model="formContent.standardDevIds" multiple collapse-tags :max-collapse-tags="2" :disabled="planType != 0" placeholder="请选择标准设备" clearable>
<el-form-item
label="标准设备"
prop="standardDevIds"
:label-width="110"
v-if="selectByMode && planType == 0"
>
<el-select
v-model="formContent.standardDevIds"
multiple
collapse-tags
:max-collapse-tags="2"
:disabled="planType != 0"
placeholder="请选择标准设备"
clearable
>
<el-option
v-for="option in pqStandardDevArray"
:key="option.value"
@@ -19,8 +44,16 @@
/>
</el-select>
</el-form-item>
<el-form-item label='测试项' prop='testItems' :label-width='110' v-if="selectByMode" >
<el-select v-model="formContent.testItems" multiple collapse-tags :max-collapse-tags="3" :disabled="planType != 0" placeholder="请选择测试项" clearable>
<el-form-item label="测试项" prop="testItems" :label-width="110" v-if="selectByMode">
<el-select
v-model="formContent.testItems"
multiple
collapse-tags
:max-collapse-tags="3"
:disabled="planType != 0"
placeholder="请选择测试项"
clearable
>
<el-option
v-for="(option, index) in secondLevelOptions"
:key="index"
@@ -29,8 +62,14 @@
/>
</el-select>
</el-form-item>
<el-form-item label='检测源' prop='sourceIds' :label-width='110' v-if="!selectByMode">
<el-select v-model="formContent.sourceIds" :multiple="selectByMode" collapse-tags placeholder="请选择检测源" clearable>
<el-form-item label="检测源" prop="sourceIds" :label-width="110" v-if="!selectByMode">
<el-select
v-model="formContent.sourceIds"
:multiple="selectByMode"
collapse-tags
placeholder="请选择检测源"
clearable
>
<el-option
v-for="(option, index) in pqSourceArray"
:key="index"
@@ -40,7 +79,17 @@
</el-select>
</el-form-item>
<el-form-item label="数据源" prop="datasourceIds" :label-width="110">
<el-select v-model="formContent.datasourceIds" :multiple="selectByMode" :max-collapse-tags="2" :disabled="planType != 0" collapse-tags placeholder="请选择数据源" autocomplete="off" clearable @change="handleDataSourceChange">
<el-select
v-model="formContent.datasourceIds"
:multiple="selectByMode"
:max-collapse-tags="2"
:disabled="planType != 0"
collapse-tags
placeholder="请选择数据源"
autocomplete="off"
clearable
@change="handleDataSourceChange"
>
<el-option
v-for="item in dictStore.getDictData(dataSourceType)"
:key="item.id"
@@ -50,7 +99,13 @@
</el-select>
</el-form-item>
<el-form-item label="检测脚本" prop="scriptId" :label-width="110" v-if="!selectByMode">
<el-select v-model="formContent.scriptId" placeholder="请选择检测脚本" autocomplete="off" :disabled="isSelectDisabled" clearable>
<el-select
v-model="formContent.scriptId"
placeholder="请选择检测脚本"
autocomplete="off"
:disabled="isSelectDisabled"
clearable
>
<el-option
v-for="(option, index) in pqScriptArray"
:key="index"
@@ -60,7 +115,13 @@
</el-select>
</el-form-item>
<el-form-item label="误差体系" prop="errorSysId" :label-width="110">
<el-select v-model="formContent.errorSysId" placeholder="请选择误差体系" autocomplete="off" :disabled="isSelectDisabled" clearable>
<el-select
v-model="formContent.errorSysId"
placeholder="请选择误差体系"
autocomplete="off"
:disabled="isSelectDisabled"
clearable
>
<el-option
v-for="(option, index) in pqErrorArray"
:key="index"
@@ -70,7 +131,13 @@
</el-select>
</el-form-item>
<el-form-item label="数据处理原则" prop="dataRule" :label-width="110">
<el-select v-model="formContent.dataRule" placeholder="请选择数据处理原则" autocomplete="off" :disabled="isSelectDisabled" clearable>
<el-select
v-model="formContent.dataRule"
placeholder="请选择数据处理原则"
autocomplete="off"
:disabled="isSelectDisabled"
clearable
>
<el-option
v-for="item in dictStore.getDictData('Data_Rule')"
:key="item.id"
@@ -79,7 +146,7 @@
/>
</el-select>
</el-form-item>
<el-form-item label="守时检测" :label-width="110" prop='timeCheck' >
<el-form-item label="守时检测" :label-width="110" prop="timeCheck">
<el-radio-group v-model="formContent.timeCheck" :disabled="planType != 0">
<el-radio :value="1"></el-radio>
<el-radio :value="0"></el-radio>
@@ -91,8 +158,18 @@
<el-radio :value="0"></el-radio>
</el-radio-group>
</el-form-item> -->
<el-form-item label="模版名称" prop="reportTemplateName" :label-width="110" v-if="formContent.associateReport === 1">
<el-select v-model="formContent.reportTemplateName" placeholder="请选择报告模版" autocomplete="off" :disabled="planType != 0" >
<el-form-item
label="模版名称"
prop="reportTemplateName"
:label-width="110"
v-if="formContent.associateReport === 1"
>
<el-select
v-model="formContent.reportTemplateName"
placeholder="请选择报告模版"
autocomplete="off"
:disabled="planType != 0"
>
<el-option
v-for="(option, index) in pqReportName"
:key="index"
@@ -103,55 +180,123 @@
</el-form-item>
</el-form>
</el-col>
<el-col :span="12" v-if="planType == 0">
<div style="text-align: center; margin-bottom: -30px;">
<el-button type='primary' v-auth.plan="'import'" :icon='Download'>导入</el-button>
</div>
<el-col :span="14" v-if="planType == 0">
<el-transfer
v-model="value"
filterable
:filter-method="filterMethod"
filter-placeholder="请输入内容搜索"
:data="allData"
:titles="['未绑定被检设备', '已绑定被检设备']">
:titles="['未绑定被检设备', '已绑定被检设备']"
>
<template #default="{ option }">
<span>{{ option.label }}</span>
<div style="display: flex; align-items: center; justify-content: space-between">
<span>
{{ JSON.parse(option.label).manufacturer }} - {{ JSON.parse(option.label).name }}
</span>
<el-tooltip placement="top" effect="light">
<template #content>
<el-descriptions size="small" title="被检设备详情" border>
<el-descriptions-item label="设备名称">
{{ JSON.parse(option.label).name }}
</el-descriptions-item>
<el-descriptions-item label="设备厂家">
{{ JSON.parse(option.label).manufacturer }}
</el-descriptions-item>
<el-descriptions-item label="所属地市">
{{ JSON.parse(option.label).cityName }}
</el-descriptions-item>
<el-descriptions-item label="所属供电公司">
{{ JSON.parse(option.label).gdName }}
</el-descriptions-item>
<el-descriptions-item label="所属电站">
{{ JSON.parse(option.label).subName }}
</el-descriptions-item>
</el-descriptions>
</template>
<el-icon><Warning /></el-icon>
</el-tooltip>
</div>
</template>
<template #left-footer>
<el-button
class="transfer-footer"
v-if="modeStore.currentMode !== '比对式'"
size="small"
type="primary"
v-auth.plan="'import'"
:icon="Download"
@click="importFile('')"
>
导入被检设备
</el-button>
<el-button
class="transfer-footer"
v-if="modeStore.currentMode === '比对式'"
size="small"
type="primary"
v-auth.plan="'import'"
:icon="Download"
@click="importFile('比对式')"
>
导入被检设备
</el-button>
</template>
<template #right-footer>
<el-text></el-text>
</template>
<template #left-empty>
<el-empty :image-size="60" description="暂无被检设备" />
</template>
<template #right-empty>
<el-empty :image-size="60" description="暂无被检设备" />
</template>
</el-transfer>
</el-col>
</el-row>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'> </el-button>
<el-button @click="close()"> </el-button>
<el-button type="primary" @click="save()"> </el-button>
</div>
</template>
<ImportExcel ref="deviceImportExcel" />
</el-dialog>
</template>
<script setup lang="ts">
import { CascaderOption, ElMessage, type FormItemRule } from 'element-plus'
import { defineProps, reactive,ref, computed } from 'vue';
import { dialogBig,dialogMiddle} from '@/utils/elementBind'
import { type Plan } from '@/api/plan/interface';
import { addPlan, updatePlan,getUnboundPqDevList,getBoundPqDevList,getPqErrSysList,getPqScriptList,getTestSourceList,updateSubPlanName } from '@/api/plan/plan.ts'
import { computed, defineProps, reactive, ref } from 'vue'
import { dialogBig } from '@/utils/elementBind'
import { type Plan } from '@/api/plan/interface'
import {
addPlan,
getBoundPqDevList,
getPqErrSysList,
getPqScriptList,
getTestSourceList,
getUnboundPqDevList,
updatePlan,
updateSubPlanName
} from '@/api/plan/plan.ts'
import { useDictStore } from '@/stores/modules/dict'
import { type TestSource } from '@/api/device/interface/testSource';
import { type TestScript } from '@/api/device/interface/testScript';
import { type ErrorSystem } from '@/api/device/interface/error';
import { type Device } from '@/api/device/interface/device';
import { type TestSource } from '@/api/device/interface/testSource'
import { type TestScript } from '@/api/device/interface/testScript'
import { type ErrorSystem } from '@/api/device/interface/error'
import { type Device } from '@/api/device/interface/device'
import { getPqReportAllName } from '@/api/device/report/index.ts'
import {useAppSceneStore} from "@/stores/modules/mode";
import { useAppSceneStore, useModeStore } from '@/stores/modules/mode'
import { Download } from '@element-plus/icons-vue'
import { getAllPqStandardDev } from '@/api/device/standardDevice/index.ts'
import { StandardDevice } from '@/api/device/interface/standardDevice';
import { Dict } from '@/api/system/dictionary/interface';
import { getDictTreeByCode } from '@/api/system/dictionary/dictTree';
import { StandardDevice } from '@/api/device/interface/standardDevice'
import { Dict } from '@/api/system/dictionary/interface'
import { getDictTreeByCode } from '@/api/system/dictionary/dictTree'
import { getAllUser } from '@/api/user/user'
import ImportExcel from '@/components/ImportExcel/index.vue'
import { downloadTemplate, importPqDev } from '@/api/device/device/index'
const modeStore = useModeStore()
const AppSceneStore = useAppSceneStore()
const dictStore = useDictStore()
// 定义弹出组件元信息
@@ -166,13 +311,13 @@
const pqReportName = ref<{ name: string }[]>([])
const pqSourceArray = ref<{ label: string; value: string; }[]>()
const pqScriptArray = ref<{ label: string; value: string; }[]>()
const pqErrorArray = ref<{ label: string; value: string; }[]>()
const pqDevArray = ref<{ label: string; value: string; }[]>()
const pqStandardDevArray = ref<{ label: string; value: string; }[]>()
const secondLevelOptions: any[] = [];
const userArray = ref<{ label: string; value: string; }[]>([])
const pqSourceArray = ref<{ label: string; value: string }[]>()
const pqScriptArray = ref<{ label: string; value: string }[]>()
const pqErrorArray = ref<{ label: string; value: string }[]>()
const pqDevArray = ref<{ label: string; value: string }[]>()
const pqStandardDevArray = ref<{ label: string; value: string }[]>()
const secondLevelOptions: any[] = []
const userArray = ref<{ label: string; value: string }[]>([])
const unboundPqDevList = ref<Device.ResPqDev[]>([]) //指定模式下所有未绑定的设备
const boundPqDevList = ref<Device.ResPqDev[]>([]) //根据检测计划id查询出所有已绑定的设备
@@ -183,22 +328,50 @@
const subPlanBindStandardDev = ref<any>([]) //哪些标准设备已经被子计划绑定
const generateData = () => {
const manufacturerDict = dictStore.getDictData('Dev_Manufacturers')
unboundPqDevList.value.forEach(i => {
// 确保字段不为空且字典存在再进行查找
if (i.manufacturer && manufacturerDict) {
const manufacturer = manufacturerDict.find(item => item.id === i.manufacturer)
if (manufacturer) {
i.manufacturer = manufacturer.name
}
}
})
const unboundData = unboundPqDevList.value.map((i: Device.ResPqDev) => ({
key: i.id,
label: i.name,
label: JSON.stringify(i)
//tips: i.description
}))
boundPqDevList.value.forEach(i => {
// 确保字段不为空且字典存在再进行查找
if (i.manufacturer && manufacturerDict) {
const manufacturer = manufacturerDict.find(item => item.id === i.manufacturer)
if (manufacturer) {
i.manufacturer = manufacturer.name
}
}
})
const boundData = boundPqDevList.value.map((i: Device.ResPqDev) => ({
key: i.id,
label: i.name,
label: JSON.stringify(i),
//tips: i.description
disabled:i.checkState != 0 || i.assign == 1,
disabled: i.checkState != 0 || i.assign == 1
}))
return [...unboundData, ...boundData]
}
const filterMethod = (query: string, item: { label?: string }) => {
return item.label?.toLowerCase().includes(query.toLowerCase()) ?? false
const dataJSON = item.label ? JSON.parse(item.label) : {}
return (
(dataJSON.name?.toLowerCase().includes(query.toLowerCase()) ||
dataJSON.manufacturer?.toLowerCase().includes(query.toLowerCase()) ||
dataJSON.subName?.toLowerCase().includes(query.toLowerCase()) ||
dataJSON.gdName?.toLowerCase().includes(query.toLowerCase()) ||
dataJSON.cityName?.toLowerCase().includes(query.toLowerCase())) ??
false
)
}
function useMetaInfo() {
@@ -234,7 +407,7 @@ const filterMethod = (query: string, item: { label?: string }) => {
standardDevIds: [],
standardDevMap: new Map<string, number>(),
testItems: [],
Check_By:'',
Check_By: ''
})
return { dialogVisible, titleType, formContent }
}
@@ -243,8 +416,7 @@ const filterMethod = (query: string, item: { label?: string }) => {
// 清空formContent
const resetFormContent = () => {
Object.assign(
formContent,{
Object.assign(formContent, {
id: '',
planId: '',
name: '',
@@ -274,10 +446,8 @@ const filterMethod = (query: string, item: { label?: string }) => {
standardDevMap: new Map<string, number>(),
testItemNameStr: '',
testItems: [],
Check_By:'',
}
)
Check_By: ''
})
}
let dialogTitle = computed(() => {
@@ -299,20 +469,21 @@ const baseRules: Record<string, Array<FormItemRule>> = {
errorSysId: [{ required: true, message: '误差体系必选!', trigger: 'change' }],
dataRule: [{ required: true, message: '数据处理原则必选!', trigger: 'change' }],
standardDevIds: [{ required: true, message: '标准设备必选!', trigger: 'change' }],
testItems: [{ required: true, message: '测试项必选!', trigger: 'change' }],
};
testItems: [{ required: true, message: '测试项必选!', trigger: 'change' }]
}
// 使用计算属性根据 scene 动态生成规则
const rules = computed(() => {
const dynamicRules = { ...baseRules };
const dynamicRules = { ...baseRules }
if (formContent.associateReport === 1){//只有关联报告模版时需要展示
dynamicRules.reportTemplateName= [{ required: true, message: '报告模版名称必选!', trigger: 'change' }];
if (formContent.associateReport === 1) {
//只有关联报告模版时需要展示
dynamicRules.reportTemplateName = [{ required: true, message: '报告模版名称必选!', trigger: 'change' }]
//dynamicRules.reportTemplateVersion= [{ required: true, message: '报告模版版本号必选!', trigger: 'change' }];
}
return dynamicRules;
});
return dynamicRules
})
// 关闭弹窗
const close = () => {
@@ -322,10 +493,9 @@ const rules = computed(() => {
resetFormContent()
// 重置表单
dialogFormRef.value?.resetFields()
dialogFormRef.value?.clearValidate()
}
const emit = defineEmits(['update:tab'])
// 保存数据
const save = () => {
@@ -336,51 +506,59 @@ const rules = computed(() => {
if (formContent.id) {
// 把数据处理原则转成字典ID
const patternItem = dictStore.getDictData('Data_Rule').find(item => item.name === formContent.dataRule);
const patternItem = dictStore
.getDictData('Data_Rule')
.find(item => item.name === formContent.dataRule)
if (patternItem) {
formContent.dataRule = patternItem.id;
formContent.dataRule = patternItem.id
}
if (mode.value === '比对式') {
if (planType.value == 1) {
formContent.fatherPlanId = formContent.id;
formContent.id = '';
formContent.fatherPlanId = formContent.id
formContent.id = ''
formContent.devIds = []
formContent.standardDevIds = []
formContent.standardDevMap = new Map<string, number>();
formContent.standardDevMap = new Map<string, number>()
await addPlan(formContent)
emit('update:tab')
}
else if(planType.value == 2){
} else if (planType.value == 2) {
await updateSubPlanName(formContent)
emit('update:tab')
console.log('更新子计划', formContent)
}
else{
} else {
formContent.sourceIds = null
await updatePlan(formContent)
}
} else {
await updatePlan({...formContent,'sourceIds':[formContent.sourceIds],'datasourceIds':[formContent.datasourceIds]});
await updatePlan({
...formContent,
sourceIds: [formContent.sourceIds],
datasourceIds: [formContent.datasourceIds]
})
}
ElMessage.success({ message: `${dialogTitle.value}成功!` })
} else {
// 新增需要把设备模式转成字典ID
const patternItem = dictStore.getDictData('Pattern').find(item => item.name === formContent.pattern);
const patternItem = dictStore.getDictData('Pattern').find(item => item.name === formContent.pattern)
if (patternItem) {
formContent.pattern = patternItem.id;
formContent.pattern = patternItem.id
}
// 把数据处理原则转成字典ID
const patternItem2 = dictStore.getDictData('Data_Rule').find(item => item.name === formContent.dataRule);
const patternItem2 = dictStore
.getDictData('Data_Rule')
.find(item => item.name === formContent.dataRule)
if (patternItem2) {
formContent.dataRule = patternItem2.id;
formContent.dataRule = patternItem2.id
}
if (mode.value === '比对式') {
formContent.sourceIds = null
await addPlan(formContent);
await addPlan(formContent)
} else {
await addPlan({...formContent,'sourceIds':[formContent.sourceIds],'datasourceIds':[formContent.datasourceIds]});
await addPlan({
...formContent,
sourceIds: [formContent.sourceIds],
datasourceIds: [formContent.datasourceIds]
})
}
ElMessage.success({ message: `${dialogTitle.value}成功!` })
}
@@ -389,7 +567,6 @@ const rules = computed(() => {
if (planType.value == 0) {
await props.refreshTable!()
}
}
})
} catch (err) {
@@ -397,7 +574,6 @@ const rules = computed(() => {
}
}
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string, data: Plan.ReqPlan, currentMode: string, plan: number) => {
unboundPqDevList.value = []
@@ -412,7 +588,7 @@ const open = async (sign: string, data: Plan.ReqPlan,currentMode: string,plan:nu
console.log('planType.value', planType.value)
//比对式测试项下拉框
if (mode.value == '比对式') {
const dictCode = 'Script_Error';
const dictCode = 'Script_Error'
const resDictTree: Dict.ResDictTree = {
name: '',
id: '',
@@ -420,22 +596,26 @@ const open = async (sign: string, data: Plan.ReqPlan,currentMode: string,plan:nu
pids: '',
code: dictCode,
sort: 0
};
}
const result = await getDictTreeByCode(resDictTree)
const allOptions = convertToOptions(result.data as Dict.ResDictTree[]);
const allOptions = convertToOptions(result.data as Dict.ResDictTree[])
// 提取第二层节点
allOptions.forEach(option => {
if (option.children && option.children.length > 0) {
secondLevelOptions.push(...option.children);
secondLevelOptions.push(...option.children)
}
});
})
}
if(sign == 'add')
{
if (sign == 'add') {
resetFormContent()
let pqSource_Result, PqScript_Result, PqErrSys_Result, pqDevList_Result, pqReportName_Result, pqStandardDev_Result;
let pqSource_Result,
PqScript_Result,
PqErrSys_Result,
pqDevList_Result,
pqReportName_Result,
pqStandardDev_Result
if (mode.value === '比对式') {
const commonResults = await Promise.all([
@@ -443,49 +623,49 @@ const open = async (sign: string, data: Plan.ReqPlan,currentMode: string,plan:nu
getUnboundPqDevList(data),
getPqReportAllName(),
getAllPqStandardDev()
]);
[PqErrSys_Result, pqDevList_Result, pqReportName_Result, pqStandardDev_Result] = commonResults;
])
;[PqErrSys_Result, pqDevList_Result, pqReportName_Result, pqStandardDev_Result] = commonResults
// 比对式下这两个接口不需要
pqSource_Result = { data: [] };
PqScript_Result = { data: [] };
pqSource_Result = { data: [] }
PqScript_Result = { data: [] }
} else {
const commonResults = await Promise.all([
getTestSourceList(data),
getPqScriptList(data),
getPqErrSysList(),
getUnboundPqDevList(data),
getPqReportAllName(),
]);
[pqSource_Result, PqScript_Result, PqErrSys_Result, pqDevList_Result, pqReportName_Result] = commonResults;
getPqReportAllName()
])
;[pqSource_Result, PqScript_Result, PqErrSys_Result, pqDevList_Result, pqReportName_Result] = commonResults
}
if (Array.isArray(pqReportName_Result.data)) {
pqReportName.value = pqReportName_Result.data.map(item => ({ name: item }));
pqReportName.value = pqReportName_Result.data.map(item => ({ name: item }))
} else {
pqReportName.value = [];
pqReportName.value = []
}
pqSourceList.value = pqSource_Result.data as TestSource.ResTestSource[];
pqScriptList.value = PqScript_Result.data as TestScript.ResTestScript[];
pqErrSysList.value = PqErrSys_Result.data as unknown as ErrorSystem.ErrorSystemList[];
pqDevList.value = pqDevList_Result.data as Device.ResPqDev[];
pqSourceList.value = pqSource_Result.data as TestSource.ResTestSource[]
pqScriptList.value = PqScript_Result.data as TestScript.ResTestScript[]
pqErrSysList.value = PqErrSys_Result.data as unknown as ErrorSystem.ErrorSystemList[]
pqDevList.value = pqDevList_Result.data as Device.ResPqDev[]
if (pqStandardDev_Result && Array.isArray(pqStandardDev_Result.data)) {
pqStandardDevList.value = pqStandardDev_Result.data as StandardDevice.ResPqStandardDevice[];
pqStandardDevList.value = pqStandardDev_Result.data as StandardDevice.ResPqStandardDevice[]
} else {
pqStandardDevList.value = [];
pqStandardDevList.value = []
}
// 初始化 boundPqDevList 为空数组
unboundPqDevList.value = pqDevList.value
boundPqDevList.value = [];
boundPqDevList.value = []
//楼下场景新增下拉框需要默认
formContent.scriptId = pqScriptList.value[0]?.id ?? '';
formContent.errorSysId = pqErrSysList.value[0]?.id ?? '';
formContent.sourceIds = pqSourceList.value[0]?.id ?? '';
formContent.datasourceIds = dictStore.getDictData('Datasource')[0]?.code ?? '';
formContent.dataRule = dictStore.getDictData('Data_Rule')[0]?.id ?? '';
}else{//编辑时先给表单赋值(这会没接收被检设备),需要手动再给被检设备复制后整体表单赋值
formContent.scriptId = pqScriptList.value[0]?.id ?? ''
formContent.errorSysId = pqErrSysList.value[0]?.id ?? ''
formContent.sourceIds = pqSourceList.value[0]?.id ?? ''
formContent.datasourceIds = dictStore.getDictData('Datasource')[0]?.code ?? ''
formContent.dataRule = dictStore.getDictData('Data_Rule')[0]?.id ?? ''
} else {
//编辑时先给表单赋值(这会没接收被检设备),需要手动再给被检设备复制后整体表单赋值
if (plan == 1 || plan == 2) {
isSelectDisabled.value = true
@@ -499,21 +679,33 @@ const open = async (sign: string, data: Plan.ReqPlan,currentMode: string,plan:nu
Object.assign(formContent, { ...data })
let pqSource_Result, PqScript_Result, PqErrSys_Result, boundPqDevList_Result, unboundPqDevList_Result, pqReportName_Result, pqStandardDev_Result;
let pqSource_Result,
PqScript_Result,
PqErrSys_Result,
boundPqDevList_Result,
unboundPqDevList_Result,
pqReportName_Result,
pqStandardDev_Result
if (mode.value === '比对式') {
const commonResults = await Promise.all([
getPqErrSysList(),
getBoundPqDevList({ 'planIdList': [data.id] }),
getBoundPqDevList({ planIdList: [data.id] }),
getUnboundPqDevList(data),
getPqReportAllName(),
getAllPqStandardDev()
]);
[PqErrSys_Result, boundPqDevList_Result, unboundPqDevList_Result, pqReportName_Result, pqStandardDev_Result] = commonResults;
])
;[
PqErrSys_Result,
boundPqDevList_Result,
unboundPqDevList_Result,
pqReportName_Result,
pqStandardDev_Result
] = commonResults
// 比对式下这两个接口不需要
pqSource_Result = { data: [] };
PqScript_Result = { data: [] };
pqSource_Result = { data: [] }
PqScript_Result = { data: [] }
//编辑时把标准设备map赋值给数组
formContent.standardDevIds = Object.keys(formContent.standardDevMap)
@@ -523,71 +715,77 @@ const open = async (sign: string, data: Plan.ReqPlan,currentMode: string,plan:nu
.map(([key]) => {
const matched = pqStandardDev_Result.data?.find(
(item: StandardDevice.ResPqStandardDevice) => item.id === key
);
return matched ? matched.name : key;
});
)
return matched ? matched.name : key
})
} else {
const commonResults = await Promise.all([
getTestSourceList(data),
getPqScriptList(data),
getPqErrSysList(),
getBoundPqDevList({ 'planIdList': [data.id] }),
getBoundPqDevList({ planIdList: [data.id] }),
getUnboundPqDevList(data),
getPqReportAllName(),
]);
[pqSource_Result, PqScript_Result, PqErrSys_Result, boundPqDevList_Result, unboundPqDevList_Result, pqReportName_Result] = commonResults;
getPqReportAllName()
])
;[
pqSource_Result,
PqScript_Result,
PqErrSys_Result,
boundPqDevList_Result,
unboundPqDevList_Result,
pqReportName_Result
] = commonResults
}
if (Array.isArray(pqReportName_Result.data)) {
pqReportName.value = pqReportName_Result.data.map(item => ({ name: item }));
pqReportName.value = pqReportName_Result.data.map(item => ({ name: item }))
} else {
pqReportName.value = [];
pqReportName.value = []
}
pqSourceList.value = pqSource_Result.data as TestSource.ResTestSource[];
pqScriptList.value = PqScript_Result.data as TestScript.ResTestScript[];
pqErrSysList.value = PqErrSys_Result.data as unknown as ErrorSystem.ErrorSystemList[];
pqSourceList.value = pqSource_Result.data as TestSource.ResTestSource[]
pqScriptList.value = PqScript_Result.data as TestScript.ResTestScript[]
pqErrSysList.value = PqErrSys_Result.data as unknown as ErrorSystem.ErrorSystemList[]
if (pqStandardDev_Result && Array.isArray(pqStandardDev_Result.data)) {
pqStandardDevList.value = pqStandardDev_Result.data as StandardDevice.ResPqStandardDevice[];
pqStandardDevList.value = pqStandardDev_Result.data as StandardDevice.ResPqStandardDevice[]
} else {
pqStandardDevList.value = [];
pqStandardDevList.value = []
}
const boundData = Array.isArray(boundPqDevList_Result.data) ? boundPqDevList_Result.data : [];
const unboundData = Array.isArray(unboundPqDevList_Result.data) ? unboundPqDevList_Result.data : [];
pqDevList.value = [...boundData,...unboundData] as Device.ResPqDev[];
formContent.devIds = boundData.map(i => i.id );// 已绑定设备id集合
const boundData = Array.isArray(boundPqDevList_Result.data) ? boundPqDevList_Result.data : []
const unboundData = Array.isArray(unboundPqDevList_Result.data) ? unboundPqDevList_Result.data : []
pqDevList.value = [...boundData, ...unboundData] as Device.ResPqDev[]
formContent.devIds = boundData.map(i => i.id) // 已绑定设备id集合
Object.assign(formContent, { ...data })
//设备绑定显示
unboundPqDevList.value = unboundPqDevList_Result.data as Device.ResPqDev[];
boundPqDevList.value = boundPqDevList_Result.data as Device.ResPqDev[];
unboundPqDevList.value = unboundData as Device.ResPqDev[]
boundPqDevList.value = boundData as Device.ResPqDev[]
}
pqToArray();//将对象转为数组
pqToArray() //将对象转为数组
if (mode.value != '比对式') {
selectByMode.value = false
// 将 formContent.sourceIds 从数组转换为字符串
if (Array.isArray(formContent.sourceIds)) {
formContent.sourceIds = formContent.sourceIds.join(',');
formContent.sourceIds = formContent.sourceIds.join(',')
}
// 将 formContent.sourceIds 从数组转换为字符串
if (Array.isArray(formContent.datasourceIds)) {
formContent.datasourceIds = formContent.datasourceIds.join(',');
formContent.datasourceIds = formContent.datasourceIds.join(',')
}
}
value.value = boundPqDevList.value.map((i: { id: { toString: () => any } }) => i.id.toString());
value.value = boundPqDevList.value.map((i: { id: { toString: () => any } }) => i.id.toString())
if(AppSceneStore.currentScene == "1"){//楼下场景不用报告模版
if (AppSceneStore.currentScene == '1') {
//楼下场景不用报告模版
formContent.associateReport = 0
} else {
formContent.associateReport = 1
}
if(plan == 1)//新增子计划名称清空
{
if (plan == 1) {
//新增子计划名称清空
formContent.name = ''
const userList = await getAllUser()
const sourceArray1 = Array.isArray(userList.data) ? userList.data : []
@@ -595,10 +793,10 @@ const open = async (sign: string, data: Plan.ReqPlan,currentMode: string,plan:nu
userArray.value = sourceArray1.map(item => ({
label: item.loginName || '',
value: item.id
}));
}))
}
// 所有数据加载完成后显示对话框
dialogVisible.value = true;
dialogVisible.value = true
}
// 转换函数
@@ -609,27 +807,27 @@ const convertToOptions = (dictTree: Dict.ResDictTree[]): CascaderOption[] => {
code: item.code,
children: item.children ? convertToOptions(item.children) : undefined,
remark: item.remark
}));
};
}))
}
function pqToArray() {
const sourceArray1 = Array.isArray(pqSourceList.value) ? pqSourceList.value : []
// 将 pqSource_Result 转换成 { label, value } 数组
pqSourceArray.value = sourceArray1.map(item => ({
label: item.name || '',
value: item.id
}));
}))
const sourceArray2 = Array.isArray(pqScriptList.value) ? pqScriptList.value : []
pqScriptArray.value = sourceArray2.map(item => ({
label: item.name || '',
value: item.id || ''
}));
}))
const sourceArray3 = Array.isArray(pqErrSysList.value) ? pqErrSysList.value : []
pqErrorArray.value = sourceArray3.map(item => ({
label: item.name,
value: item.id
}));
}))
const sourceArray4 = Array.isArray(pqDevList.value) ? pqDevList.value : []
pqDevArray.value = sourceArray4.map(item => ({
@@ -642,12 +840,8 @@ function pqToArray() {
label: item.name,
value: item.id
}))
}
const dataSourceType = computed(() => {
// switch (mode.value) {
// case '模拟式':
@@ -661,46 +855,72 @@ const dataSourceType = computed(() => {
})
const handleDataSourceChange = () => {
if(mode.value != '比对式')
return
if (mode.value != '比对式') return
// 获取当前选中的 datasourceIds并确保为数组
const values = Array.isArray(formContent.datasourceIds)
? formContent.datasourceIds
: [formContent.datasourceIds].filter(Boolean); // 转为数组并过滤空值
: [formContent.datasourceIds].filter(Boolean) // 转为数组并过滤空值
const selectedLabels = values.map(value => {
const matched = dictStore.getDictData(dataSourceType.value).find(item => item.code === value);
return matched ? matched.name : '';
const matched = dictStore.getDictData(dataSourceType.value).find(item => item.code === value)
return matched ? matched.name : ''
})
// 判断是否同时包含 '3s' 和 '分钟'
const hasThreeSeconds = selectedLabels.some(label => label.includes('3s'));
const hasMinuteStats = selectedLabels.some(label => label.includes('分钟'));
const hasThreeSeconds = selectedLabels.some(label => label.includes('3s'))
const hasMinuteStats = selectedLabels.some(label => label.includes('分钟'))
if (hasThreeSeconds && hasMinuteStats) {
ElMessage.warning('3s实时数据与分钟统计数据不能同时选择');
formContent.datasourceIds = '';
ElMessage.warning('3s实时数据与分钟统计数据不能同时选择')
formContent.datasourceIds = ''
}
// 判断是否选择了多个“分钟统计数据”项
const minuteStatLabels = selectedLabels.filter(label => label.includes('分钟'));
const minuteStatLabels = selectedLabels.filter(label => label.includes('分钟'))
if (minuteStatLabels.length > 1) {
ElMessage.warning('分钟统计数据不能多选');
formContent.datasourceIds = '';
ElMessage.warning('分钟统计数据不能多选')
formContent.datasourceIds = ''
}
}
};
//导入设备
const deviceImportExcel = ref<InstanceType<typeof ImportExcel> | null>(null)
const importFile = async (pattern: string) => {
const params = {
title: '被检设备',
showCover: false,
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id,
planId: null,
tempApi: downloadTemplate,
importApi: importPqDev
// importApi: modeStore.currentMode === "比对式"? importContrastPqDev: importCNDev,
// getTableList: proTable.value?.getTableList
}
deviceImportExcel.value?.acceptParams(params)
}
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
refreshTable: (() => Promise<void>) | undefined
}>()
</script>
<style scoped lang="scss">
// :deep(.dialog-small .el-dialog__body){
// max-height: 330px !important;
// }
:deep(.el-transfer) {
--el-transfer-panel-width: 250px;
--el-transfer-panel-body-height: 315px;
}
.transfer-footer {
margin-left: 15px;
padding: 6px 5px;
}
:deep(.el-transfer-panel__footer) {
display: flex;
justify-content: center;
align-items: center;
}
</style>

View File

@@ -1,110 +1,111 @@
import { defineConfig, loadEnv, ConfigEnv, UserConfig } from "vite";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import vue from "@vitejs/plugin-vue";
import path from "path";
import { ConfigEnv, defineConfig, loadEnv, UserConfig } from 'vite'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// 处理env环境参数读取
import { wrapperEnv } from "./build/getEnv";
import { createProxy } from "./build/proxy";
import { wrapperEnv } from './build/getEnv'
import { createProxy } from './build/proxy'
// 导入
import vueJsx from "@vitejs/plugin-vue-jsx";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import { nodePolyfills } from 'vite-plugin-node-polyfills';
import vueJsx from '@vitejs/plugin-vue-jsx'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { nodePolyfills } from 'vite-plugin-node-polyfills'
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
const root = process.cwd();
const env = loadEnv(mode, root);
const viteEnv = wrapperEnv(env);
const root = process.cwd()
const env = loadEnv(mode, root)
const viteEnv = wrapperEnv(env)
return {
plugins: [
vue(),
vueJsx(),
// svg图标配置可以使用svg图标
createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), "src/assets/icons")],
symbolId: "icon-[dir]-[name]",
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
symbolId: 'icon-[dir]-[name]'
}),
AutoImport({
// 自动导入 Vue 相关函数ref, reactive, toRef 等
imports: ["vue", "@vueuse/core", "pinia", "vue-router", "vue-i18n"],
imports: ['vue', '@vueuse/core', 'pinia', 'vue-router', 'vue-i18n'],
resolvers: [
// 自动导入 Element Plus 相关函数ElMessage, ElMessageBox... (带样式)
ElementPlusResolver({
importStyle: "sass",
}),
importStyle: 'sass'
})
],
eslintrc: {
// 是否自动生成 eslint 规则,建议生成之后设置 false
enabled: false,
// 指定自动导入函数 eslint 规则的文件
filepath: "./.eslintrc-auto-import.json",
globalsPropValue: true,
filepath: './.eslintrc-auto-import.json',
globalsPropValue: true
},
// 是否在 vue 模板中自动导入
vueTemplate: true,
// 指定自动导入函数TS类型声明文件路径 (false:关闭自动生成)
dts: false,
dts: false
// dts: "src/types/auto-imports.d.ts",
}),
Components({
resolvers: [
// 自动导入 Element Plus 组件
ElementPlusResolver({
importStyle: "sass",
}),
importStyle: 'sass'
})
],
// 指定自定义组件位置(默认:src/components)
dirs: ["src/components", "src/**/components"],
dirs: ['src/components', 'src/**/components'],
// 指定自动导入组件TS类型声明文件路径 (false:关闭自动生成)
dts: false,
dts: false
// dts: "src/types/components.d.ts",
}),
nodePolyfills({
include: ['crypto'],
globals: {
crypto: true,
},
}),
crypto: true
}
})
],
// 基础配置
base: viteEnv.VITE_PUBLIC_PATH,
root,
publicDir: "public",
publicDir: 'public',
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
"vue-i18n": "vue-i18n/dist/vue-i18n.cjs.js",
},
'@': path.resolve(__dirname, 'src'),
'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js'
}
},
css: {
preprocessorOptions: {
scss: {
prependData: `@import "@/styles/var.scss";`,
},
},
api: 'modern-compiler'
}
}
},
build: {
outDir: "dist",
assetsDir: "assets",
outDir: 'dist',
assetsDir: 'assets',
assetsInlineLimit: 4096,
cssCodeSplit: true,
sourcemap: false,
minify: "terser",
minify: 'terser',
terserOptions: {
compress: {
// 生产环境去除console及debug
drop_console: false,
drop_debugger: true,
},
},
drop_debugger: true
}
}
},
server: {
host: "0.0.0.0",
host: '0.0.0.0',
port: viteEnv.VITE_PORT,
open: viteEnv.VITE_OPEN,
cors: true,
proxy: createProxy(viteEnv.VITE_PROXY),
},
};
});
proxy: createProxy(viteEnv.VITE_PROXY)
}
}
})