<!-- 标准装置台账信息详情 配置核查项 第8套:E2等砝码标准装置 -->
<script name="StandardBookEquipmentConfig" lang="ts" setup>
import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import type { IList } from './eighth-interface'
import type { dictType } from '@/global'
import { useCheckList } from '@/commonMethods/useCheckList'
import type { TableColumn } from '@/components/NormalTable/table_interface'
import { config, getCheckItemDetail } from '@/api/equipment/standard/book'
import { getDictByCode } from '@/api/system/dict'
import SelectByDict from '@/components/SelectByDict/index.vue'
import SelectEquipmentDialog from '@/views/business/fieldTest/approve/dialog/selectEquipmentDialog.vue'
const textMap: { [key: string]: string } = {
edit: '编辑',
detail: '详情',
}// 页面类型字典
const form = ref({ // 表单
equipmentNo: '', // 统一编号
equipmentName: '', // 设备名称
model: '', // 规格型号
manufactureNo: '', // 出厂编号
measureRange: '', // 测量范围
uncertainty: '', // 不确定度或允许误差极限或准确度等级
itemCategoryName: '', // 核查项分类名称
itemCategoryId: '', // 核查项分类id
remark: '', // 核查项备注
belongStandardEquipment: '', // 检校标准装置
belongStandardEquipmentName: '', // 检校标准装置名称
})
const pageType = ref('detail') // 页面类型: add, edit, detail
const infoId = ref('') // id
const $router = useRouter() // 路由实例
const loading = ref(false) // loading
const equipmentId = ref('') // 设备id
// -----------------------------------路由参数------------------------------------------------------
// 从路由中获取页面类型参数
const $route = useRoute()
if ($route.params && $route.params.type) {
pageType.value = $route.params.type as string
if ($route.params.id) {
infoId.value = $route.params.id as string
}
console.log('pageType.value', pageType.value)
}
// ------------------------------------------字典----------------------------------------------
const checkTypeList = ref<dictType[]>([]) // 核查类型
const checkPointList = ref<dictType[]>([]) // 核查类型
/**
* 获取字典
*/
function getDict() {
// 核查类型
getDictByCode('bizFirstStandardCheckType').then((response) => {
checkTypeList.value = response.data
})
// 核查点
getDictByCode('Standard8CheckPoint').then((response) => {
checkPointList.value = response.data
})
}
getDict()
// -------------------------------------------核查项-----------------------------------------------
const list = ref<IList[]>([])
const checkoutList = ref<IList[]>([])
const columns = ref<TableColumn[]>([
{ text: '核查点', value: 'checkPoint', align: 'center', required: true },
{ text: '示值设备名称', value: 'valueEquipmentName', align: 'center', required: true, width: '220' },
{ text: '规格型号', value: 'model', align: 'center' },
{ text: '出厂编号', value: 'manufactureNo', align: 'center' },
{ text: '循环次数', value: 'cycleNumber', align: 'center', required: true, width: '180' },
{ text: '核查类型', value: 'checkType', align: 'center', required: true, width: '180' },
{ text: 'U(k=2)', value: 'urel', align: 'center', required: true, width: '180' },
])
// 多选
const handleSelectionChange = (e: any) => {
checkoutList.value = e
}
// 校验表格(点击保存的时候、增加行用)
const checkList = (list: any) => {
return useCheckList(list, columns.value, '核查项表格')
}
/**
* 增加行
* @param list 要操作的数组
* @param title 操作的表格
*/
const addRow = () => {
if (checkList(list.value)) {
if (list.value.length) { // 增加行时默认上一行数据
list.value.push({
id: `custom-${new Date().getTime()}`, // id,更新/删除使用参数
checkPoint: list.value[list.value.length - 1].checkPoint, // 核查点
checkType: list.value[list.value.length - 1].checkType, // 核查类型(直接存字典value)
cycleNumber: list.value[list.value.length - 1].cycleNumber, // 循环次数
manufactureNo: list.value[list.value.length - 1].manufactureNo, // 出厂编号
model: list.value[list.value.length - 1].model, // 规格型号
params: list.value[list.value.length - 1].params, // 核查项目(直接存字典value)
remark: list.value[list.value.length - 1].remark, // 核查项备注
urel: list.value[list.value.length - 1].urel, // U(k=2)
valueEquipmentId: list.value[list.value.length - 1].valueEquipmentId, // 设备台账id
valueEquipmentName: list.value[list.value.length - 1].valueEquipmentName, // 示值设备名称
equipmentId: list.value[list.value.length - 1].equipmentId, // 配套设备id
itemCategoryId: list.value[list.value.length - 1].itemCategoryId, // 核查项分类id(能够确定是哪个标准装置)
})
}
else {
list.value.push({
id: `custom-${new Date().getTime()}`, // id,更新/删除使用参数
checkPoint: '', // 核查点
checkType: ['重复性', '稳定性'], // 核查类型(直接存字典value)
cycleNumber: '6', // 循环次数
manufactureNo: '', // 出厂编号
model: '', // 规格型号
params: '', // 核查项目(直接存字典value)
remark: '', // 核查项备注
urel: undefined, // U(k=2)
valueEquipmentId: '', // 设备台账id
valueEquipmentName: '', // 示值设备名称
equipmentId: infoId.value, // 配套设备id
itemCategoryId: form.value.itemCategoryId, // 核查项分类id(能够确定是哪个标准装置)
})
}
}
}
/**
* 删除行公共方法
* @param checkoutList 选中的数组
* @param list 操作的数组
*/
const delRow = (checkoutList: IList[], listParam: IList[]) => {
if (!checkoutList.length) {
ElMessage.warning('请选中要删除的行')
}
else {
list.value = listParam.filter((item: any) => {
return !checkoutList.includes(item)
})
}
}
// --------------------------------------选择设备-------------------------------------------------
const selectEquipmentDialogRef = ref() // 选择设备组件ref
const selectIndex = ref() // 选择设备的行数
// 点击选择设备
const selectEquipment = (index: number) => {
selectIndex.value = index
selectEquipmentDialogRef.value.initDialog()
}
// 确定选择设备
const confirmSelectEquipment = (value: any) => {
if (value.length) {
list.value[selectIndex.value].valueEquipmentId = value[0].id // 设备台账id
list.value[selectIndex.value].model = value[0].model // 规格型号
list.value[selectIndex.value].manufactureNo = value[0].manufactureNo // 出厂编号
list.value[selectIndex.value].valueEquipmentName = value[0].equipmentName // 示值设备名称
}
}
// ---------------------------------------按钮-----------------------------------------------------
// 点击关闭
const close = () => {
$router.back()
}
// 清空配置
const clear = () => {
ElMessageBox.confirm(
'确认清空配置项吗?',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
},
)
.then(() => {
list.value = []
form.value.remark = ''
})
}
// 点击保存
const save = () => {
if (!list.value.length) { ElMessage.warning('核查项不能为空'); return false }
if (!checkList(list.value)) { return false }
if (!checkArrayDataUnique()) { return false }
const params = {
itemCategoryId: form.value.itemCategoryId, // 核查项分类id
checkItemDataETwoList: list.value.map((item: any) => {
return {
...item,
checkType: item.checkType.join(','), // 核查类型
remark: form.value.remark,
id: item.id.includes('custom') ? '' : item.id,
}
}),
equipmentId: infoId.value, // 配套设备id
standardId: $route.query.standardId,
}
const loading = ElLoading.service({
lock: true,
text: '加载中',
background: 'rgba(255, 255, 255, 0.6)',
})
config(params).then((res) => {
ElMessage.success('已保存')
pageType.value = 'detail'
loading.close()
})
}
// 校验表格中不能同时存在核查点两个属性的两条数据
function checkArrayDataUnique() {
for (let i = 0; i < list.value.length; i++) {
const j = i + 1
for (let j = 0; j < list.value.length; j++) {
if (i !== j && list.value[i].checkPoint === list.value[j].checkPoint) {
ElMessage.warning(`核查项表格第${i + 1}行和第${j + 1}行的核查点重复了`)
return false
}
}
}
return true
}
// 获取详情
const getInfo = () => {
const loading = ElLoading.service({
lock: true,
text: '加载中',
background: 'rgba(255, 255, 255, 0.6)',
})
const params = {
equipmentId: equipmentId.value, // 设备id
belongStandardEquipment: form.value.belongStandardEquipment, // 检校标准装置code
itemCategoryId: form.value.itemCategoryId, // 核查项分类id
itemCategoryName: form.value.itemCategoryName, // 核查项分类名称
}
getCheckItemDetail(params).then((res) => {
if (res && res.data && res.data.checkItemDataETwoList && res.data.checkItemDataETwoList.length) {
list.value = res.data.checkItemDataETwoList.map((e: any) => {
return {
...e,
checkType: e.checkType ? e.checkType.split(',') : [], // 核查类型
}
})
form.value.remark = list.value[0].remark // 核查项备注
}
loading.close()
})
}
// ------------------------------------------钩子--------------------------------------------------
onMounted(() => {
form.value.equipmentNo = $route.query.equipmentNo as string // 统一编号
form.value.equipmentName = $route.query.equipmentName as string // 设备名称
form.value.model = $route.query.model as string // 规格型号
form.value.manufactureNo = $route.query.manufactureNo as string // 出厂编号
form.value.measureRange = $route.query.measureRange as string // 测量范围
form.value.uncertainty = $route.query.uncertainty as string // 不确定度或允许误差极限或准确度等级
form.value.itemCategoryName = $route.query.itemCategoryName as string // 核查项分类名称
form.value.itemCategoryId = $route.query.itemCategoryId as string // 核查项分类id
form.value.belongStandardEquipment = $route.query.belongStandardEquipment as string // 核查项标准装置id
form.value.belongStandardEquipmentName = $route.query.belongStandardEquipmentName as string // 核查项标准装置id
equipmentId.value = $route.query.equipmentId as string // 设备id
getInfo()
})
// ---------------------------------表格操作---------------------------------
const table = ref()
const randomNum = `${new Date().getTime}${Math.random()}`
// 右击当前行操作
const clickIndex = ref(-1)
const contextmenu = (row: any, column: any, event: any, index: number) => {
if (pageType.value === 'detail') { return }
// 阻止默认的右键菜单
event.preventDefault()
clickIndex.value = list.value.findIndex(item => item === row)
// console.log('右击', clickIndex.value)
// 获取自定义菜单元素
var menu = document.getElementById(randomNum) as HTMLElement
// 设置自定义菜单的位置并显示
let positionX = event.clientX
let positionY = event.clientY
if (window.innerHeight - event.clientY < 268) {
positionY = window.innerHeight - 268
}
else {
positionY = event.clientY
}
if (window.innerWidth - event.clientX < 146) {
positionX = window.innerWidth - 146
}
else if (event.clientX - 180 < 146) {
positionX = 180
}
else {
positionX = event.clientX - 146 / 2
}
menu.style.top = `${positionY}px`
menu.style.left = `${positionX}px`
menu.style.display = 'block'
}
// 点击其他位置隐藏自定义菜单
document.addEventListener('click', () => {
if (pageType.value === 'detail') { return }
if (document.getElementById(randomNum)) {
(document.getElementById(randomNum) as HTMLElement).style.display = 'none'
}
})
const mouseoutTable = () => {
console.log('鼠标移出')
if (pageType.value === 'detail') { return }
if (document.getElementById(randomNum)) {
(document.getElementById(randomNum) as HTMLElement).style.display = 'none'
}
}
// 添加行
const costomAddRow = (type: string) => {
if (type === 'current-pre') {
// 当前行前方插入
list.value.splice(clickIndex.value, 0, JSON.parse(JSON.stringify({ ...list.value[clickIndex.value], id: `custom-${new Date().getTime()}` })))
}
else if (type === 'current-next') {
// 当前行后方方插入
list.value.splice(clickIndex.value + 1, 0, JSON.parse(JSON.stringify({ ...list.value[clickIndex.value], id: `custom-${new Date().getTime()}` })))
}
else if (type === 'list-head') {
// 列表头行插入
list.value.splice(0, 0, JSON.parse(JSON.stringify({ ...list.value[clickIndex.value], id: `custom-${new Date().getTime()}` })))
}
else if (type === 'list-tail') {
// 列表尾行插入
list.value.splice(list.value.length, 0, JSON.parse(JSON.stringify({ ...list.value[clickIndex.value], id: `custom-${new Date().getTime()}` })))
}
else if (type === 'select-pre') {
// 选中行前方插入
if (!checkoutList.value.length) {
ElMessage.warning('未选择数据')
return
}
checkoutList.value.forEach((item, index) => {
const dataIndex = list.value.findIndex(citem => item === citem)
list.value.splice(dataIndex, 0, JSON.parse(JSON.stringify({ ...item, id: `custom-${new Date().getTime()}` })))
})
table.value!.clearSelection()
}
else if (type === 'select-next') {
// 选中行后方插入
if (!checkoutList.value.length) {
ElMessage.warning('未选择数据')
return
}
checkoutList.value.forEach((item, index) => {
const dataIndex = list.value.findIndex(citem => item === citem)
list.value.splice(dataIndex + 1, 0, JSON.parse(JSON.stringify({ ...item, id: `custom-${new Date().getTime()}` })))
})
table.value!.clearSelection()
}
else if (type === 'del-current') {
list.value.splice(clickIndex.value, 1)
}
else if (type === 'del-select') {
if (!checkoutList.value.length) {
ElMessage.warning('未选择数据')
return
}
checkoutList.value.forEach((item, index) => {
const dataIndex = list.value.findIndex(citem => item === citem)
list.value.splice(dataIndex, 1)
})
table.value!.clearSelection()
}
clickIndex.value = -1
}
</script>
<template>
<app-container>
<detail-page v-loading="loading" :title="`配置核查项(${textMap[pageType]})`">
<template #btns>
<el-button v-if="pageType === 'edit'" type="warning" @click="clear">
清空配置
</el-button>
<el-button v-if="pageType === 'edit'" type="primary" @click="save">
保存
</el-button>
<el-button type="info" @click="close">
关闭
</el-button>
</template>
<el-form
ref="ruleFormRef"
:model="form"
:label-width="130"
label-position="right"
>
<el-row :gutter="24" class="marg">
<el-col :span="6">
<el-form-item label="统一编号:" prop="equipmentNo">
<el-input
v-model="form.equipmentNo"
disabled
:placeholder="pageType === 'detail' ? '' : '统一编号'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="设备名称:" prop="equipmentName">
<el-input
v-model="form.equipmentName"
disabled
:placeholder="pageType === 'detail' ? '' : '设备名称'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="规格型号:" prop="model">
<el-input
v-model="form.model"
disabled
:placeholder="pageType === 'detail' ? '' : '规格型号'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="出厂编号:" prop="manufactureNo">
<el-input
v-model="form.manufactureNo"
disabled
:placeholder="pageType === 'detail' ? '' : '出厂编号'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="测量范围:" prop="measureRange">
<el-input
v-model="form.measureRange"
disabled
type="textarea"
autosize
:placeholder="pageType === 'detail' ? '' : '测量范围'"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label-width="260" label="不确定度或允许误差极限或准确度等级:" prop="uncertainty">
<el-input
v-model="form.uncertainty"
type="textarea"
autosize
disabled
:placeholder="pageType === 'detail' ? '' : '不确定度或允许误差极限或准确度等级'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="核查项分类名称:" prop="itemCategoryName">
<el-input
v-model="form.itemCategoryName"
disabled
:placeholder="pageType === 'detail' ? '' : '核查项分类名称'"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</detail-page>
<detail-block title="核查项" style="padding-bottom: 20px;" @mouseleave="mouseoutTable">
<template v-if="pageType !== 'detail'" #btns>
<el-button type="primary" @click="addRow">
增加行
</el-button>
<el-button type="info" @click="delRow(checkoutList, list)">
删除行
</el-button>
</template>
<el-table
ref="table"
:data="list"
border
:height="list.length > 10 ? 500 : null"
style="width: 100%;"
@selection-change="handleSelectionChange"
@row-contextmenu="contextmenu"
>
<el-table-column v-if="pageType !== 'detail'" type="selection" width="38" />
<el-table-column align="center" label="序号" width="80" type="index" />
<el-table-column
v-for="item in columns"
:key="item.value"
:prop="item.value"
:label="item.text"
:width="item.width"
align="center"
>
<template #header>
<span v-show="item.required" style="color: red;">*</span><span>{{ item.text }}</span>
</template>
<template #default="scope">
<!-- 核查点 -->
<el-select
v-if="item.value === 'checkPoint' && pageType !== 'detail'"
v-model="scope.row[item.value]"
filterable
:placeholder="pageType === 'detail' ? ' ' : `${item.text}`"
>
<el-option v-for="i of checkPointList" :key="i.id" :label="i.name" :value="i.name" />
</el-select>
<!-- 设备名称 -->
<el-input v-if="item.value === 'valueEquipmentName' && pageType !== 'detail'" v-model="scope.row[item.value]" :placeholder="pageType === 'detail' ? ' ' : `${item.text}`" disabled>
<template #append>
<el-button size="small" @click="selectEquipment(scope.$index)">
选择
</el-button>
</template>
</el-input>
<el-input
v-if="(item.value === 'model' || item.value === 'manufactureNo') && pageType !== 'detail'"
v-model="scope.row[item.value]"
:placeholder="pageType === 'detail' ? ' ' : `${item.text}`"
disabled
/>
<!-- 循环次数 -->
<el-input-number
v-if="item.value === 'cycleNumber' && pageType !== 'detail'"
v-model="scope.row[item.value]"
:placeholder="`${item.text}`"
class="input"
:step="1"
:precision="0"
disabled
/>
<!-- U(k=2) -->
<select-by-dict
v-if="item.value === 'urel' && pageType !== 'detail'"
v-model:model-value="scope.row[item.value]"
placeholder="U(k=2)"
dict-code="standard8U"
/>
<!-- 核查类型 -->
<el-select v-if="pageType !== 'detail' && item.value === 'checkType'" v-model="scope.row[item.value]" disabled clearable multiple placeholder="请选择">
<el-option
v-for="item in checkTypeList"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
</el-table>
<!-- 自定义菜单 -->
<div :id="randomNum" class="custom-menu">
<p class="menu-item" @click="costomAddRow('current-pre')">
当前行前方插入
</p>
<p class="menu-item" @click="costomAddRow('current-next')">
当前行后方插入
</p>
<p class="menu-item" @click="costomAddRow('list-head')">
列表头行插入
</p>
<p class="menu-item" @click="costomAddRow('list-tail')">
列表尾行插入
</p>
<p v-if="pageType !== 'detail'" class="menu-item" @click="costomAddRow('select-pre')">
选中行前方插入
</p>
<!-- -->
<p v-if="pageType !== 'detail'" class="menu-item" @click="costomAddRow('select-next')">
选中行后方插入
</p>
<p class="menu-item" @click="costomAddRow('del-current')">
删除当前行
</p>
<p v-if="pageType !== 'detail'" class="menu-item" @click="costomAddRow('del-select')">
删除选中行
</p>
</div>
</detail-block>
<!-- 核查项备注 -->
<el-form
:model="form"
label-width="120"
label-position="right"
style="margin-top: 20px;"
>
<el-row>
<el-col :span="12">
<el-form-item label="核查项备注:" prop="remark">
<el-input
v-model="form.remark"
class="full-width-input"
autosize
type="textarea"
:disabled="pageType === 'detail'"
:placeholder="pageType === 'detail' ? ' ' : '请输入核查项备注'"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</app-container>
<!-- 选择设备台账 -->
<select-equipment-dialog ref="selectEquipmentDialogRef" :is-multi="false" @confirm="confirmSelectEquipment" />
</template>
<style lang="scss" scoped>
.custom-menu {
display: none;
position: fixed;
background-color: #fff;
border-radius: 5px;
padding: 5px 0;
z-index: 1000;
border: 1px solid #c8c9cc;
box-shadow: 0 0 12px rgb(0 0 0 / 12%);
.menu-item {
display: flex;
align-items: center;
white-space: nowrap;
list-style: none;
line-height: 22px;
padding: 5px 16px;
margin: 0;
// font-size: var(--el-font-size-base);
color: #606266;
cursor: pointer;
outline: none;
&:hover {
background-color: #ecf5ff;
color: #409eff;
}
}
}
</style>