<!-- 新建、编辑、详情 -->
<script lang="ts" setup name="InterchangeDetail">
import type { Ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, UploadUserFile } from 'element-plus'
import { ref } from 'vue'
import dayjs from 'dayjs'
import type { IRecord } from './interchange_interface'
import type { ISampleEdit, Menu, SimpleCertification, SimpleMeasureRecord, dictType } from '@/views/customer/sample/list/sample_list_interface'
import selectCustomer from '@/views/customer/sample/list/selectCustomer.vue'
import showPhoto from '@/views/system/tool/showPhoto.vue'
import TemplateTable from '@/views/customer/customerInfo/templateTable.vue'
import { addSample, getCertification, getMesureRecords, getSapmleDetail, updateSample } from '@/api/customer/sampleList'
import countries from '@/components/AddressSelect/country-code.json'
import { UploadFile } from '@/api/measure/file'
import type { ICustomer } from '@/views/customer/customerInfo/customer_interface'
import { getDictByCode } from '@/api/system/dict'
const textMap: { [key: string]: string } = {
edit: '编辑',
add: '新建',
detail: '详情',
}// 字典
const pageType = ref('add') // 页面类型: add, edit, detail
const countryList = ref(countries) // 国家列表
const loading = ref(false) // 表单加载状态
const infoId = ref('') // id
const visible = ref(false) // 控制对话框显隐
const mesureCategoryList = ref<dictType[]>([]) // 校检类别
const measureTypeList = ref<dictType[]>([]) // 检定方式
const powerVoltageList = ref<dictType[]>([]) // 电源电压
const total = ref(0)
const dataForm: Ref<ISampleEdit> = ref({
id: '',
sampleNo: '', // 样品编号
sampleName: '', // 样品名称
sampleModel: '', // 样品型号
manufacturingNo: '', // 出厂编号
customerId: '', // 委托方id
customerNo: '', // 委托方代码
customerName: '', // 委托方名称
phone: '', // 委托方电话
postalCode: '', // 委托方邮编
customerAddress: '', // 委托方地址
measureCategory: '', // 检校类别
manufacturer: '', // 生产厂家
manufacturerCountry: '', // 厂家国别
manufacturingDate: '', // 出厂年月
ABC: '', // ABC
// deliverer: '', // 送检人
// delivererTel: '', // 送检人联系方式
measureContent: '', // 检定项目
measurePeriod: '', // 检定周期
remark: '', // 备注
minioFileName: '', // 说明书
labelBind: '', // 标签绑定
measureType: '1', // 检定方式 1自检、2外包、3外检
measureLastTime: '', // 检定日期
validDeadline: '', // 有效日期
powerVoltage: '', // 电源电压
})// 表单
const ruleFormRef = ref<FormInstance>()
// 自定义校验规则--检定周期为正整数
const validateMesurePeriod = (rule: any, value: string, callback: Function) => {
if (value === '') {
callback()
}
else if (!(/(^[1-9]\d*$)/.test(value))) {
callback(new Error('请输入一个正整数'))
}
else {
callback()
}
}
// 校验规则
const rules = ref({
sampleName: [{ required: true, message: '要求样品名称不能为空', trigger: 'blur' }],
sampleModel: [{ required: true, message: '要求样品型号不能为空', trigger: 'blur' }],
manufacturingNo: [{ required: true, message: '要求出厂编号不能为空', trigger: 'blur' }],
customerNo: [{ required: true, message: '要求委托方代码不能为空', trigger: 'change' }],
customerName: [{ required: true, message: '要求委托方名称不能为空', trigger: 'change' }],
phone: [{ required: true, message: '要求委托方电话不能为空', trigger: 'change' }],
postalCode: [{ required: true, message: '要求委托方邮编不能为空', trigger: 'change' }],
customerAddress: [{ required: true, message: '要求委托方地址不能为空', trigger: 'change' }],
measureContent: [{ required: true, message: '要求检定项目不能为空', trigger: 'blur' }],
measurePeriod: [{ validator: validateMesurePeriod, trigger: 'blur' }],
powerVoltage: [{ required: true, message: '要求电源电压不能为空', trigger: 'change' }],
}) // 表单验证规则
// 获取字典值
function getDict() {
// 校检类别
getDictByCode('measureCategory').then((response) => {
mesureCategoryList.value = response.data
})
// 检定方式
getDictByCode('measureType').then((response) => {
measureTypeList.value = response.data
})
// 电源电压
getDictByCode('powerVoltage').then((response) => {
powerVoltageList.value = response.data
})
}
getDict()
// --------------------------检定记录、检定证书-----------------------------------------
// 其他关联数据列表
const dataList = ref({
measureRecords: [] as SimpleMeasureRecord[],
certificationRecords: [] as SimpleCertification[],
})
const listQuery = ref<IRecord>({
sampleId: infoId.value, // 样品id
customerId: '', // 客户id
offset: 1,
limit: 10,
})
const totalRecords = ref(0) // 检定记录总条数
const totalCertifications = ref(0) // 检定证书总条数
// 获取检定记录
const fetchMeasureRecords = (query = null) => {
if (pageType.value === 'detail') {
getMesureRecords(listQuery.value).then((res) => {
dataList.value.measureRecords = res.data.rows.map((item: { orderTime: string; deliverTime: string }) => {
return {
...item,
orderTime: item.orderTime ? dayjs(item.orderTime).format('YYYY-MM-DD') : '',
deliverTime: item.deliverTime ? dayjs(item.deliverTime).format('YYYY-MM-DD') : '',
}
})
totalRecords.value = parseInt(res.data.total)
})
}
}
// 获取检定证书
const fetchCertifications = (query = null) => {
if (pageType.value === 'detail') {
getCertification(listQuery.value).then((res) => {
dataList.value.certificationRecords = res.data.rows.map((item: { effectiveDate: string; expirationDate: string }) => {
return {
...item,
effectiveDate: item.effectiveDate ? dayjs(item.effectiveDate).format('YYYY-MM-DD') : '',
expirationDate: item.expirationDate ? dayjs(item.expirationDate).format('YYYY-MM-DD') : '',
}
})
totalCertifications.value = parseInt(res.data.total)
})
}
}
// 菜单
const menu: Menu[] = [
{
name: '检定记录',
columns: [
{ text: '委托单编号', value: 'orderCode', align: 'center' },
{ text: '委托单日期', value: 'orderTime', align: 'center', width: '120' },
{ text: '委托方代码', value: 'customerCode', align: 'center' },
{ text: '委托方名称', value: 'customerName', align: 'center' },
{ text: '送检人', value: 'deliverer', align: 'center' },
{ text: '送检日期', value: 'deliverTime', align: 'center', width: '120' },
],
list: 'measureRecords',
pagination: true,
searchFunc: fetchMeasureRecords,
},
{
name: '检定证书',
columns: [
{ text: '证书编号', value: 'certificationCode', align: 'center' },
{ text: '证书名称', value: 'certificationName', align: 'center' },
{ text: '证书类型', value: 'certificationClassName', align: 'center' },
{ text: '证书出具日期', value: 'effectiveDate', align: 'center', width: '120' },
{ text: '证书有效期', value: 'expirationDate', align: 'center', width: '120' },
],
list: 'certificationRecords',
pagination: true,
searchFunc: fetchCertifications,
},
]
const currentMenu = ref('检定记录')
const currentMenuObj = computed(() => {
return menu.find(item => item.name === currentMenu.value)
})
watch(currentMenuObj, () => {
listQuery.value.offset = 1
currentMenuObj.value?.searchFunc()
},
{
deep: true,
immediate: true,
})
// 监听检定记录和证书报告页数变化
const changePage = (val: any) => {
if (val.value && currentMenuObj) {
listQuery.value.offset = val.value.offset
listQuery.value.limit = val.value.limit
currentMenuObj.value?.searchFunc()
}
}
// -------------------------------------底部--------------------------------------
// 从路由中获取页面类型参数
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
}
}
const $router = useRouter()
// 关闭新增页面的回调
const close = () => {
$router.back()
}
// 打印表单
const printObj = ref({
id: 'form', // 需要打印元素的id
popTitle: '样品详情', // 打印配置页上方的标题
extraHead: '<div style="display: flex;flex-direction: column;text-align: center"><h3>样品详情</h3></div>', // 最上方的头部文字,附加在head标签上的额外标签,使用逗号分割
preview: false, // 是否启动预览模式,默认是false
standard: '',
extarCss: '',
})
const fileRef = ref() // 文件上传input
const onFileChange = (event: any) => {
// 原生上传
console.log(event.target.files)
if (event.target.files?.length !== 0) {
// 创建formdata对象
const fd = new FormData()
fd.append('multipartFile', event.target.files[0])
UploadFile(fd).then((res) => {
if (res.code === 200) {
dataForm.value.minioFileName = res.data[0]
// 重置当前验证
ElMessage.success('文件上传成功')
}
else {
ElMessage.error(res.message)
}
})
}
}
const upload = () => {
fileRef.value.click()
}
// 委托方代码获取焦点
const customerNoFocus = () => {
visible.value = true
}
// 选好委托方
const confirmCheckout = (val: Array<ICustomer>) => {
if (val && val.length) {
const getValue = val[0]
dataForm.value.customerNo = getValue.customerNo // 委托方代码
dataForm.value.customerId = getValue.id // 委托方id
dataForm.value.customerName = getValue.customerName // 委托方名称
dataForm.value.phone = getValue.phone // 电话
dataForm.value.postalCode = getValue.postalCode // 邮编
dataForm.value.customerAddress = getValue.fullAddress // 委托方地址
}
}
// 控制选择委托方对话框显隐
const changeVisible = (val: boolean) => {
visible.value = val
}
// 保存
function saveForm(formEl: FormInstance | undefined) {
if (!formEl) { return }
formEl.validate((valid, fields) => {
if (valid) {
ElMessageBox.confirm(
'确认保存吗?',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
},
).then(() => {
if (dataForm.value.id) {
updateSample(dataForm.value).then((res) => {
if (res.code === 200) {
dataForm.value.id = res.data.id
dataForm.value.customerNo = res.data.customerNo
ElMessage.success('已保存')
$router.go(-1)
}
})
}
else {
addSample(dataForm.value).then((res) => {
if (res.code === 200) {
dataForm.value.id = res.data.id
dataForm.value.customerNo = res.data.customerNo
ElMessage.success('已保存')
$router.go(-1)
}
})
}
})
}
})
}
// 获取详细信息
const getInfo = () => {
getSapmleDetail({ id: infoId.value }).then((res) => {
dataForm.value = res.data
dataForm.value.ABC = res.data.abc
listQuery.value.sampleId = infoId.value
for (const item of menu) {
item.searchFunc()
}
})
}
// 非添加页面获取详情
if (pageType.value !== 'add') {
getInfo()
}
</script>
<template>
<app-container>
<detail-page :title="`样品-${textMap[pageType]}`">
<template #btns>
<el-button v-if="pageType === 'detail'" v-print="printObj" type="primary">
打印
</el-button>
<el-button v-if="pageType !== 'detail'" type="primary" @click="saveForm(ruleFormRef)">
保存
</el-button>
<el-button type="info" @click="close">
关闭
</el-button>
</template>
<div id="form">
<el-form
ref="ruleFormRef"
:model="dataForm"
:label-width="120"
label-position="right"
:rules="rules"
>
<el-row :gutter="24">
<el-col :span="6">
<el-form-item label="样品编号:" prop="sampleNo">
<el-input
v-model="dataForm.sampleNo"
:placeholder="pageType === 'detail' ? '' : '系统自动生成'"
:class="{ 'detail-input': pageType === 'detail' }"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="样品名称:" prop="sampleName">
<el-input
v-model="dataForm.sampleName"
:placeholder="pageType === 'detail' ? '' : '请输入样品名称'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col><el-col :span="6">
<el-form-item label="样品型号:" prop="sampleModel">
<el-input
v-model="dataForm.sampleModel"
:placeholder="pageType === 'detail' ? '' : '请输入样品型号'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="出厂编号:" prop="manufacturingNo">
<el-input
v-model="dataForm.manufacturingNo"
:placeholder="pageType === 'detail' ? '' : '请输入出厂编号'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="委托方代码" prop="customerNo">
<el-input
v-model="dataForm.customerNo"
:placeholder="pageType === 'detail' ? '' : '请选择委托方代码'"
:class="{ 'detail-input': pageType === 'detail' }"
disabled
>
<template v-if="pageType !== 'detail'" #append>
<el-button size="small" @click="customerNoFocus">
选择
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="委托方名称" prop="customerName">
<el-input
v-model="dataForm.customerName"
:placeholder="pageType === 'detail' ? '' : '请输入委托方名称'"
:class="{ 'detail-input': pageType === 'detail' }"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="委托方电话" prop="phone">
<el-input
v-model="dataForm.phone"
:placeholder="pageType === 'detail' ? '' : '请输入委托方电话'"
:class="{ 'detail-input': pageType === 'detail' }"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="委托方邮编" prop="postalCode">
<el-input
v-model="dataForm.postalCode"
:placeholder="pageType === 'detail' ? '' : '请输入委托方邮编'"
:class="{ 'detail-input': pageType === 'detail' }"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="18">
<el-form-item label="委托方地址:" prop="customerAddress">
<el-input
v-model="dataForm.customerAddress"
type="textarea"
autosize
:placeholder="pageType === 'detail' ? '' : '请输入委托方地址'"
:class="{ 'detail-input': pageType === 'detail' }"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="校检类别:">
<el-select
v-model="dataForm.measureCategory"
:placeholder="pageType === 'detail' ? '' : '请选择校检类别'"
:disabled="pageType === 'detail'"
class="full-width-input"
>
<el-option v-for="item of mesureCategoryList" :key="item.value" :label="item.name" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="生产厂家:">
<el-input
v-model="dataForm.manufacturer"
:placeholder="pageType === 'detail' ? '' : '请输入生产厂家'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="厂家国别:">
<el-select
v-model="dataForm.manufacturerCountry"
:placeholder="pageType === 'detail' ? '' : '请选择厂家国别'"
:disabled="pageType === 'detail'"
class="full-width-input"
>
<el-option v-for="country of countryList" :key="country.code" :label="country.CNName" :value="country.code" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="出厂年月:">
<el-date-picker
v-model="dataForm.manufacturingDate"
type="month"
format="YYYY-MM"
value-format="YYYY-MM"
class="full-width-input"
:placeholder="pageType === 'detail' ? '' : '请输入出厂年月'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="ABC:">
<el-select
v-model="dataForm.ABC"
:placeholder="pageType === 'detail' ? '' : '请选择ABC'"
:disabled="pageType === 'detail'"
class="full-width-input"
>
<el-option v-for="item of ['A', 'B', 'C']" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="电源电压:" prop="powerVoltage">
<el-select
v-model="dataForm.powerVoltage"
:placeholder="pageType === 'detail' ? '' : '请选择电源电压'"
:disabled="pageType === 'detail'"
class="full-width-input"
>
<el-option v-for="item of powerVoltageList" :key="item.value" :label="item.name" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="检定周期(月):" prop="measurePeriod">
<el-input
v-model="dataForm.measurePeriod"
:placeholder="pageType === 'detail' ? '' : '请输入检定周期'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col>
<el-col v-if="pageType === 'detail'" :span="6">
<el-form-item label="检定日期:">
<el-date-picker
v-model="dataForm.measureLastTime"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
class="full-width-input"
:placeholder="pageType === 'detail' ? '' : '请输入检定日期'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col>
<el-col v-if="pageType === 'detail'" :span="6">
<el-form-item label="有效日期:">
<el-date-picker
v-model="dataForm.validDeadline"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
class="full-width-input"
:placeholder="pageType === 'detail' ? '' : '请输入有效日期'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col>
<el-col v-if="pageType === 'detail'" :span="6">
<el-form-item label="送检人:">
<el-input
v-model="dataForm.deliverer"
:placeholder="pageType === 'detail' ? '' : '请输入送检人'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col>
<el-col v-if="pageType === 'detail'" :span="6">
<el-form-item label="联系方式:">
<el-input
v-model="dataForm.delivererTel"
:placeholder="pageType === 'detail' ? '' : '请输入联系方式'"
:class="{ 'detail-input': pageType === 'detail' }"
:disabled="pageType === 'detail'"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="检定方式:">
<el-select
v-model="dataForm.measureType"
:placeholder="pageType === 'detail' ? '' : '请选择检定方式'"
disabled
class="full-width-input"
>
<el-option v-for="item of measureTypeList" :key="item.value" :label="item.name" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="标签绑定:">
<el-input
v-model="dataForm.labelBind"
:placeholder="pageType === 'detail' ? '' : '标签绑定'"
:disabled="pageType === 'detail'"
:class="{ 'detail-input': pageType === 'detail' }"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" class="marg">
<el-col :span="12">
<el-form-item label="检定项目:" prop="measureContent">
<el-input
v-model="dataForm.measureContent"
:placeholder="pageType === 'detail' ? '' : '请输入检定项目'"
:disabled="pageType === 'detail'"
:class="{ 'detail-input': pageType === 'detail' }"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" class="marg">
<el-col :span="12">
<el-form-item label="备注:">
<el-input
v-model="dataForm.remark"
type="textarea"
autosize
:placeholder="pageType === 'detail' ? '' : '请输入备注'"
:disabled="pageType === 'detail'"
:class="{ 'detail-input': pageType === 'detail' }"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" class="marg">
<el-col :span="12">
<el-form-item label="说明书:">
<show-photo v-if="dataForm.minioFileName" :minio-file-name="dataForm.minioFileName" />
<span v-else-if="pageType === 'detail'">无</span>
<input v-show="pageType === ''" ref="fileRef" type="file" @change="onFileChange">
<el-button v-if="pageType !== 'detail'" id="file" type="primary" :disabled="pageType === 'detail'" :style="{ 'margin-left': dataForm.minioFileName === '' ? '0px' : '20px' }" @click="upload">
{{ dataForm.minioFileName === '' ? '上传' : '更换附件' }}
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</detail-page>
<!-- 检定记录、检定证书 -->
<detail-block-switch v-if="pageType === 'detail'" :title="currentMenu">
<template #menu>
<el-radio-group v-model="currentMenu">
<el-radio-button v-for="item in menu" :key="item.name" :label="item.name">
{{ item.name }}
</el-radio-button>
</el-radio-group>
</template>
<!-- <template-table v-if="currentMenuObj" :columns="currentMenuObj.columns" :list="dataList[currentMenuObj.list]" :loading="false" :pagination="currentMenuObj.pagination" @change-page="currentMenuObj?.searchFunc" /> -->
<template-table v-if="currentMenuObj" :total="currentMenu === '检定记录' ? totalRecords : totalCertifications" :columns="currentMenuObj.columns" :list="dataList[currentMenuObj.list]" :loading="false" :pagination="currentMenuObj.pagination" @change-page="changePage" />
</detail-block-switch>
<!-- 选择委托方组件 -->
<select-customer v-model:visible="visible" @confirmCheckout="confirmCheckout" @changeVisible="changeVisible" />
</app-container>
</template>
<style lang="scss" scoped>
// 样式
</style>