检测计划

This commit is contained in:
sjl
2024-12-11 19:39:09 +08:00
parent 393ad5fa0b
commit 5dbd6eb8be
15 changed files with 634 additions and 550 deletions

View File

@@ -25,7 +25,7 @@
</template>
<script setup lang='tsx' name='useRole'>
import { Device } from '@/api/device/interface/device.ts';
import { type Device } from '@/api/device/interface/device.ts';
import { useHandleData } from '@/hooks/useHandleData'
import { useDownload } from '@/hooks/useDownload'
import { useAuthButtons } from '@/hooks/useAuthButtons'

View File

@@ -1,12 +1,12 @@
<template>
<!-- 权限信息弹出框 -->
<el-dialog :model-value="dialogVisible" title="设备绑定" v-bind="dialogBig" @close="handleCancel" width="600" draggable>
<el-dialog title="设备绑定" v-model='dialogVisible' @close="close" v-bind="dialogBig" width="600" draggable>
<div>
<el-transfer v-model="value"
filterable
:filter-method="filterMethod"
filter-placeholder="请输入内容搜索"
:data="data"
:data="allData"
:titles="['未绑定设备', '已绑定设备']">
<template #default="{ option }">
<el-tooltip :content="option.tips" placement="top" :show-after=1000>
@@ -18,8 +18,8 @@
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleCancel">
<el-button @click="close()">取消</el-button>
<el-button type="primary" @click="save()">
保存
</el-button>
</div>
@@ -28,94 +28,68 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { computed, ref } from 'vue'
import type { Device } from '@/api/device/interface'
import deviceDataList from '@/api/device/deviceData'
import { dialogBig } from '@/utils/elementBind'
const {dialogVisible} = defineProps<{
dialogVisible: boolean;
}>()
interface Option {
key: number
label: string
initial: string
tips: string
}
const generateData = () => {
const data: Option[] = []
const states = [
'240001',
'240002',
'240003',
'240004',
'240005',
'240006',
'240007',
'240008',
'240009',
'240010',
'240011',
'240012',
'240013',
'240014',
]
const initials = ['CA', 'IL', 'MD', 'TX', 'FL', 'CO', 'CT', 'GT', 'IL', 'MD', 'TX', 'FL', 'CO', 'CT', 'GT']
states.forEach((city, index) => {
data.push({
label: city,
key: index,
initial: initials[index],
tips:"PQS882A 192.16.1.136",
})
})
return data
}
const generateValue = () => {
const data: number[] = []
const states = [
'240001',
'240002',
]
const initials = ['AB', 'CD']
states.forEach((city, index) => {
const key = states.indexOf(city)
if (key !== -1) {
data.push(key)
}
})
return data
import { getUnboundPqDevList,getBoundPqDevList,BindPqDevList } from '@/api/plan/plan.ts'
import { type Plan } from '@/api/plan/interface'
import { ElMessage } from 'element-plus'
const unboundPqDevList=ref<Device.ReqPqDevParams[]>([])//指定模式下所有未绑定的设备
const boundPqDevList=ref<Device.ReqPqDevParams[]>([])//根据检测计划id查询出所有已绑定的设备
const dialogVisible = ref(false)
const planData = ref<Plan.ReqPlan | null>(null) // 新增状态管理
const value = ref<string[]>([])
const generateData = () => {
const unboundData = unboundPqDevList.value.map((i: Device.ReqPqDevParams) => ({
key: i.id,
label: i.name,
tips: i.description
}))
const boundData = boundPqDevList.value.map((i: Device.ReqPqDevParams) => ({
key: i.id,
label: i.name,
tips: i.description
}))
return [...unboundData, ...boundData]
}
// const generateValue = () => {
// const data: Option[] = []
// const states = [
// '山大电力测试装置1',
// '山大电力测试装置2',
// ]
// const initials = ['AB', 'CD']
// states.forEach((city, index) => {
// data.push({
// label: city,
// key: index,
// initial: initials[index],
// })
// })
// return data
// }
const data = ref<Option[]>(generateData())
const value = ref<number[]>(generateValue())
const emit = defineEmits<{
(e:'update:visible',value:boolean):void;
}>();
const allData = computed(() => generateData())
const handleCancel = () => {
emit('update:visible',false)
const filterMethod = (query: string, item: { label?: string }) => {
return item.label?.toLowerCase().includes(query.toLowerCase()) ?? false
}
// 打开弹窗,可能是新增,也可能是编辑
const open = async (data: Plan.ReqPlan,) => {
dialogVisible.value = true
planData.value = data
const pqDevList_Result1 = await getUnboundPqDevList(data);
unboundPqDevList.value = pqDevList_Result1.data as Device.ReqPqDevParams[];
const pqDevList_Result2 = await getBoundPqDevList({'planId': data.id});
boundPqDevList.value = pqDevList_Result2.data as Device.ReqPqDevParams[];
value.value = boundPqDevList.value.map((i: { id: { toString: () => any } }) => i.id.toString());
}
const close = () => {
dialogVisible.value = false
}
const filterMethod = (query, item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
const save = async () => {
if (planData.value) {
await BindPqDevList({ 'planId': planData.value.id,'pqDevIds': value.value })
ElMessage.success({ message: `设备绑定保存成功成功!` })
}
dialogVisible.value = false
}
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>

View File

@@ -1,57 +1,32 @@
<template>
<div class="device-list-container" v-if="isShow">
<el-dropdown @command="handleCommand">
<el-button link type='primary' class='table-operate'>
<el-link link type='primary' class='table-operate'>
<div class='table-operate-text'>更多...</div>
</el-button>
</el-link>
<!-- <span class="el-dropdown-link">
更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
</span> -->
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="高精度设备-PQV520-2">高精度设备-PQV-520便携式电能质量监测装置-2</el-dropdown-item>
<!-- <el-dropdown-item command="高精度设备-PQV520-2">高精度设备-PQV-520便携式电能质量监测装置-2</el-dropdown-item>
<el-dropdown-item command="高精度设备-PQV520-3">高精度设备-PQV-520便携式电能质量监测装置-3</el-dropdown-item>
<el-dropdown-item command="高精度设备-PQV520-4">高精度设备-PQV-520便携式电能质量监测装置-4</el-dropdown-item>
<el-dropdown-item command="高精度设备-PQV520-4">高精度设备-PQV-520便携式电能质量监测装置-4</el-dropdown-item> -->
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- 查看误差体系详细信息 -->
<ErrorStandardDialog
:visible='detail_dialogFormVisible'
:formData='detail_dialogForm'
:dialogTitle='detail_dialogTitle'
@update:visible='detail_dialogFormVisible = $event'
/>
</div>
</template>
<script lang="ts" setup>
import { ElMessage } from 'element-plus'
import { ArrowDown } from '@element-plus/icons-vue'
import ErrorStandardDialog from '@/views/machine/errorSystem/components/errorStandardPopup.vue' // 导入子组件
import type { ErrorSystem } from '@/api/error/interface'
const detail_dialogFormVisible = ref(false)
const detail_dialogTitle = ref('Q/GDW 10650.2-2021 误差体系')
const detail_dialogForm = ref<ErrorSystem.Error_detail>({
measured: '',//被测量
deviceLevel: '',//检测装置级别
measurementType: '',
condition: '',//测量条件
maxErrorValue: '',//最大误差
})
const props = defineProps<{
isShow: boolean;
}>();
//console.log(props.isShow,1111)
const handleCommand = (command: string | number | object) => {
detail_dialogTitle.value = command as string;
detail_dialogFormVisible.value = true // 显示对话框
}
</script>
<style scoped>

View File

@@ -1,150 +1,163 @@
<template>
<!-- 基础信息弹出框 -->
<el-dialog :model-value="visible" :title="dialogTitle" v-bind="dialogSmall" @close="handleCancel" draggable>
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogSmall">
<div>
<el-form :model="formData" ref='formRuleRef' :rules='rules'>
<el-form :model="formContent" ref='dialogFormRef' :rules='rules'>
<el-form-item label="名称" prop="name" :label-width="100">
<el-input v-model="formData.name" placeholder="请输入名称" autocomplete="off" :disabled="isReadOnly"/>
<el-input v-model="formContent.name" placeholder="请输入名称" autocomplete="off"/>
</el-form-item>
<!-- <el-form-item label="父计划" prop="father_Plan_Id" :label-width="100">
<el-select v-model="formData.father_Plan_Id" placeholder="请选择父计划" autocomplete="off" :disabled="isReadOnly" @change="fatherPlanChange">
<el-option
v-for="plan in testFatherPlanList"
:key="plan.id"
:label="plan.label"
:value="plan.id">
</el-option>
</el-select>
</el-form-item> -->
<el-form-item label='检测源' prop='source_Id' :label-width='100'>
<el-select v-model="formData.source_Id" multiple collapse-tags placeholder="请选择检测源">
<el-form-item label='检测源' prop='sourceIds' :label-width='100'>
<el-select v-model="formContent.sourceIds" multiple collapse-tags placeholder="请选择检测源">
<el-option
v-for="plan in sourceDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id"
/>
v-for="(option, index) in pqSourceArray"
:key="index"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据源" prop="dataSource_Id" :label-width="100">
<el-select v-model="formData.dataSource_Id" multiple collapse-tags placeholder="请选择数据源" autocomplete="off" :disabled="isReadOnly">
<el-form-item label="数据源" prop="datasourceIds" :label-width="100">
<el-select v-model="formContent.datasourceIds" multiple collapse-tags placeholder="请选择数据源" autocomplete="off" >
<el-option
v-for="plan in testSoureDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id">
</el-option>
v-for="item in dictStore.getDictData(dataSourceType)"
:key="item.id"
:label="item.name"
:value="item.value || ''"
/>
</el-select>
</el-form-item>
<el-form-item label="检测脚本" prop="scriptId" :label-width="100">
<el-select v-model="formContent.scriptId" placeholder="请选择检测脚本" autocomplete="off" >
<el-option
v-for="(option, index) in pqScriptArray"
:key="index"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
<el-form-item label="检测脚本" prop="script_Id" :label-width="100">
<el-select v-model="formData.script_Id" placeholder="请选择检测脚本" autocomplete="off" :disabled="isReadOnly">
<el-form-item label="误差体系" prop="errorSysId" :label-width="100">
<el-select v-model="formContent.errorSysId" placeholder="请选择误差体系" autocomplete="off">
<el-option
v-for="plan in testScriptDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id">
</el-option>
v-for="(option, index) in pqErrorArray"
:key="index"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
<el-form-item label="误差体系" prop="error_Sys_Id" :label-width="100">
<el-select v-model="formData.error_Sys_Id" placeholder="请选择误差体系" autocomplete="off" :disabled="isReadOnly">
<el-option
v-for="plan in testErrSystDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label='被检设备' :label-width='100' prop='device_Id'>
<el-select v-model="formData.device_Id" multiple collapse-tags placeholder="请选择被检设备">
<el-form-item label='被检设备' :label-width='100' prop='devIds'>
<el-select v-model="formContent.devIds" multiple collapse-tags placeholder="请选择被检设备">
<el-option
v-for="plan in deviceDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id"
/>
v-for="(option, index) in pqDevArray"
:key="index"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
<!-- <el-form-item label='检测功能' :label-width='100' prop='device_Id'>
<el-checkbox v-model="checked1" label="守时检测" size="large" />
</el-form-item> -->
<el-form-item label="守时检测" :label-width="100">
<el-radio-group v-model="timeFlag" >
<el-radio value="1"></el-radio>
<el-radio value="0"></el-radio>
</el-form-item>
<el-form-item label="守时检测" :label-width="100" prop='timeCheck'>
<el-radio-group v-model="formContent.timeCheck" >
<el-radio :value="1"></el-radio>
<el-radio :value="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleCancel"> </el-button>
<el-button type="primary" @click="handleSubmit" :disabled="isReadOnly"> </el-button>
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()' > </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import{ElMessage, FormInstance,FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, Ref } from 'vue';
import{ElMessage, type FormInstance,type FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, type Ref, computed } from 'vue';
import { dialogSmall} from '@/utils/elementBind'
import {dictPattern,dictTestState,dictReportState,dictResult,testPlanDataList,sourceDataList,deviceDataList,testSoureDataList,testScriptDataList,testErrSystDataList,planData,testFatherPlanList} from '@/api/plan/planData'
import { type Plan } from '@/api/plan/interface';
import { addPlan, updatePlan,getUnboundPqDevList,getBoundPqDevList,getPqErrSysList,getPqScriptList,getTestSourceList } 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';
const props = defineProps<{
visible: boolean;
dialogTitle: string;
isReadOnly: boolean,
formData: {
id:string;
name: string;
pattern: string; //模式,字典表(数字、模拟、比对)
father_Plan_Id: string; //父计划ID
source_Id: string;//检测源ID
dataSource_Id: string; //数据源ID
script_Id: string; //检测脚本ID
error_Sys_Id: string;//误差体系ID
device_Id: string;//被检设备ID
test_State: string; //检测状态
report_State: string; //报告生成状态
result: string;//检测结果
state: number; //状态
};
}>();
const checked1 = ref(false)
const timeFlag = ref('0')
const fatherPlanList = [
{ label: '/', value: 'type0' },
{ label: '检测计划1', value: 'type1' },
{ label: '检测计划2', value: 'type2' },
{ label: '检测计划3', value: 'type3' },
{ label: '检测计划4', value: 'type4' },
];
const dictStore = useDictStore()
// 定义弹出组件元信息
const dialogFormRef = ref()
const mode = ref()
const pqSourceList=ref<TestSource.ResTestSource[]>([])//获取指定模式下所有检测源
const pqScriptList=ref<TestScript.ResTestScript[]>([])//获取指定模式下所有检测源
const pqErrSysList=ref<ErrorSystem.ErrorSystemList[]>([])//获取指定模式下所有检测源
const sourceList = [
{ label: '分钟统计数据最大值', value: 'type0' },
{ label: '分钟统计数据最大值', value: 'type1' },
{ label: '分钟统计数据CP95值', value: 'type2' },
];
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; }[]>()
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = ref<Plan.ReqPlan>({
id:'',
planId:'',
name: '',
pattern: mode.value,
fatherPlanId: '',
dataSourceId: '',
scriptId: '',
errorSysId: '',
timeCheck:0,
testState: 0,
reportState: 0,
result: 2,
code:1,
state:1,
scriptName:'',
errorSysName:'',
sourceName:'',
devIds:[],
sourceIds:[],
datasourceIds:'',
})
return { dialogVisible, titleType, formContent }
}
const scriptList = [
{ label: '/', value: 'type0' },
{ label: '国网入网检测脚本(单影响量-模拟式)', value: 'type1' },
{ label: '国网入网检测脚本Q/GDW 10650.4 - 2021) 数字式', value: 'type1' },
];
const { dialogVisible, titleType, formContent } = useMetaInfo()
const errorList = [
{ label: 'Q/GDW 1650.2- 2016', value: 'type0' },
{ label: 'Q/GDW 10650.2 - 2021', value: 'type1' },
];
// 清空formContent
const resetFormContent = () => {
formContent.value = {
id:'',
planId:'',
name: '',
pattern: mode.value,
fatherPlanId: '',
dataSourceId: '',
scriptId: '',
errorSysId: '',
timeCheck:0,
testState: 0,
reportState: 0,
result: 2,
code:1,
state:1,
scriptName:'',
errorSysName:'',
sourceName:'',
devIds:[],
sourceIds:[],
datasourceIds:'',
}
}
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增检测计划' : '编辑检测计划'
})
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void;
(e: 'submit', data: any): void;
}>();
// 定义规则
const formRuleRef = ref<FormInstance>()
@@ -154,47 +167,150 @@ const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
dataSource_Id: [{ required: true, message: '数据源必选!', trigger: 'blur' }],
script_Id: [{ required: true, message: '检测脚本必选!', trigger: 'blur' }],
error_Sys_Id: [{ required: true, message: '误差体系必选!', trigger: 'blur' }],
// name: [{ required: true, message: '检测计划名称必填!', trigger: 'blur' }],
// father_Plan_Id: [{ required: true, message: '参照标准名称必填!', trigger: 'change' }],
});
const handleCancel = () => {
//重置表单内容
//取消表单校验状态
formRuleRef.value && formRuleRef.value.resetFields()
emit('update:visible', false); // 关闭对话框
};
const handleSubmit = () => {
// 关闭弹窗
const close = () => {
dialogVisible.value = false
// 清空dialogForm中的值
resetFormContent()
// 重置表单
dialogFormRef.value?.resetFields()
}
try {
formRuleRef.value?.validate((valid: boolean) => {
if (valid)
{
// 将表单数据转为json,发送到后端
let confirmFormData = JSON.parse(JSON.stringify(props.formData));
//console.log(confirmFormData)
emit('submit', props.formData); // 提交表单数据
emit('update:visible', false); // 提交后关闭对话框
}
else
{
ElMessage.error('请填选必填项!')
}
// 保存数据
const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
if (formContent.value.id) {
await updatePlan(formContent.value);
ElMessage.success({ message: `${dialogTitle.value}成功!` })
} else {
// 新增需要把设备模式转成字典ID
const patternItem = dictStore.getDictData('Pattern').find(item => item.name === formContent.value.pattern);
if (patternItem) {
formContent.value.pattern = patternItem.id;
}
await addPlan(formContent.value);
ElMessage.success({ message: `${dialogTitle.value}成功!` })
}
close()
// 刷新表格
await props.refreshTable!()
}
})
} catch (error) {
console.error('验证过程中发生错误', error)
} catch (err) {
console.error('验证过程中出现错误', err)
}
}
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string,
data: Plan.ReqPlan,
currentMode: string,) => {
let pqDevList=ref<Device.ResPqDev[]>([])//获取指定模式下所有检测源
//处理异步调用
const patternId = dictStore.getDictData('Pattern').find(item=>item.name=== currentMode)?.id ?? ''
data.pattern = patternId
const pqSource_Result = await getTestSourceList(data);
pqSourceList.value = pqSource_Result.data as TestSource.ResTestSource[];
const PqScript_Result = await getPqScriptList(data);
pqScriptList.value = PqScript_Result.data as TestScript.ResTestScript[];
const PqErrSys_Result = await getPqErrSysList();
pqErrSysList.value = PqErrSys_Result.data as unknown as ErrorSystem.ErrorSystemList[];
if(sign == 'add')
{
const pqDevList_Result = await getUnboundPqDevList(data);
pqDevList.value = pqDevList_Result.data as Device.ResPqDev[];
}else{
const boundPqDevList_Result = await getBoundPqDevList({ 'planId': data.id });
const unboundPqDevList_Result = await getUnboundPqDevList(data);
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[];
pqDevArray.value = pqDevList.value.map(i => ({
label: i.name,
value: i.id
})); // 设置已绑定设备为默认选中
formContent.value.devIds = boundData.map(i => i.id)// 已绑定设备id集合
console.log('123',formContent.value.devIds)
}
console.log(formContent.value)
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 => ({
// label: item.name,
// value: item.id
// }))
mode.value = currentMode
titleType.value = sign
dialogVisible.value = true
if (data.id) {
formContent.value = { ...data }
} else {
resetFormContent()
}
};
// 当 props.visible 改变时,更新 formData
watch(() => props.visible, (newVal) => {
if (!newVal) {
// 这里可以重置表单数据,如果需要的话
}
});
// 重置表单
dialogFormRef.value?.resetFields()
}
const dataSourceType = computed(() => {
switch (mode.value) {
case '模拟式':
return 'Datasource_Simulate'
case '数字式':
return 'Datasource_Digital'
default:
return 'Datasource_Contrast'
}
})
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>
<style scoped lang="scss">

View File

@@ -14,7 +14,6 @@
:data='testSourceData'
type='selection'
>
<!-- :request-api="getTableList" 如果要显示静态数据就切换该配置-->
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button type='primary' :icon='Download' plain :disabled='!scope.isSelected' @click="exportClick">移入检测计划</el-button>