<template>
|
<Card>
|
<div class="header-title-left">
|
<img src="@/assets/public/headercard.png" />
|
<div>所属实验调度</div>
|
<el-button @click="showScheduling = true" class="el-icon-plus" type="primary">
|
选择实验调度</el-button>
|
</div>
|
<Table :data="tableData" :total="total" :height="null">
|
<template>
|
<el-table-column prop="planCode" label="所属项目课题方案"></el-table-column>
|
<el-table-column prop="planName" label="实验编号"></el-table-column>
|
<el-table-column prop="testName" label="实验名称"></el-table-column>
|
<el-table-column prop="notifyTime" label="通知时间"></el-table-column>
|
<el-table-column prop="startTime" label="实验开始时间"></el-table-column>
|
<el-table-column prop="endTime" label="实验结束时间"></el-table-column>
|
<el-table-column prop="participants" label="参加人员"></el-table-column>
|
<el-table-column prop="status" label="状态"></el-table-column>
|
</template>
|
</Table>
|
<div class="header-title-left" style="margin-top: 60px;">
|
<img src="@/assets/public/headercard.png" />
|
<div>检测明细</div>
|
<el-button @click="showAddTestItem" type="primary" class="el-icon-plus">
|
新增检测项</el-button>
|
<span>【注意:这里有多少个检测项 系统就会自动创建对应数量的《检测项的检验方法及数据记录》】</span>
|
</div>
|
<Table :data="testItems" :total="testItems.length" :height="null">
|
<template>
|
<el-table-column type="index" label="序号" width="80"></el-table-column>
|
<el-table-column prop="termName" label="检测项名称"></el-table-column>
|
<el-table-column prop="termCode" label="检测项编号"></el-table-column>
|
<el-table-column prop="termType" label="定性/定量">
|
<template slot-scope="scope">
|
{{ scope.row.termType === 1 ? '定性' : '定量' }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="termMethodCode" label="检测方法编号"></el-table-column>
|
<el-table-column prop="termMethod" label="检测方法"></el-table-column>
|
<el-table-column prop="sampleRequire" label="收样要求"></el-table-column>
|
<el-table-column label="操作" width="150">
|
<template slot-scope="scope">
|
<el-button type="text" @click="handleEditTestItem(scope.row)">编辑</el-button>
|
<el-button type="text" @click="handleDeleteTestItem(scope.$index)" class="delete-btn">删除</el-button>
|
</template>
|
</el-table-column>
|
</template>
|
</Table>
|
<div class="btn_box flex ">
|
<el-button type="primary" @click="handleSubmit">提交确认单</el-button>
|
<el-button @click="handleSaveDraft">存草稿</el-button>
|
</div>
|
<experimentalScheduling :show="showScheduling" @close="showScheduling = false" @submit="setSelectedScheduling"/>
|
<add-test-item
|
:dialogVisible="testItemDialogVisible"
|
:editData="currentTestItem"
|
@close="handleTestItemDialogClose"
|
@confirm="handleTestItemConfirm"
|
/>
|
<confirm-dialog
|
:visible.sync="confirmDialogVisible"
|
:formData="confirmFormData"
|
:sampleData="testItems"
|
@confirm="handleConfirmSubmit"
|
/>
|
</Card>
|
</template>
|
|
<script>
|
import experimentalScheduling from './experimental-scheduling.vue';
|
import AddTestItem from './add-test-item.vue'
|
import ConfirmDialog from './confirm-dialog.vue'
|
import { add, update, getDetail } from '../service'
|
|
export default {
|
name: 'AddConfirmationSheet',
|
components: {
|
experimentalScheduling,
|
AddTestItem,
|
ConfirmDialog
|
},
|
props: {},
|
data() {
|
return {
|
showScheduling: false,
|
tableData: [],
|
testItems: [], // 检测项列表
|
total: 0,
|
form: {
|
roleName: "",
|
remark: "",
|
},
|
rules: {
|
roleName: [
|
{ required: true, message: "请输入角色名称", trigger: "blur" },
|
],
|
},
|
menu: [],
|
testItemDialogVisible: false,
|
confirmDialogVisible: false,
|
confirmFormData: {
|
planName: '', // 项目课题方案名称
|
testCode: '', // 实验编号
|
testName: '', // 实验名称
|
sampleCode: '' // 取样单编号
|
},
|
selectedScheduling: null, // 添加选中的实验调度数据
|
currentTestItem: null, // 当前编辑的检测项
|
formData: {
|
id: '', // 确认单ID
|
dispatchId: '', // 实验调度ID
|
auditStatus: -1, // 审核状态,默认草稿
|
testMethodConfirmSheetTerms: [], // 确认单检测项
|
confirmSign: '', // 签字
|
signTime: '', // 签字时间
|
}
|
};
|
},
|
computed: {
|
height() {
|
return this.$baseTableHeight()
|
},
|
},
|
watch: {},
|
created() {
|
// 判断是否是编辑模式
|
const id = this.$route.query.id
|
if (id) {
|
this.getDetailData(id)
|
}
|
},
|
mounted() { },
|
methods: {
|
setSelectedScheduling(data) {
|
console.log('data',data)
|
if (!data || data.length === 0) return;
|
const selectedData = data[0]; // 获取选中的第一条数据
|
this.selectedScheduling = selectedData;
|
|
// 更新表格数据
|
this.tableData = [{
|
planCode: selectedData.projectName || '', // 所属项目课题方案
|
planName: selectedData.experimentCode || '', // 实验编号
|
testName: selectedData.experimentName || '', // 实验名称
|
notifyTime: selectedData.experimentDate || '', // 通知时间
|
startTime: selectedData.experimentStartTime || '', // 实验开始时间
|
endTime: selectedData.experimentEndTime || '', // 实验结束时间
|
participants: selectedData.participantsName || '', // 参加人员
|
status: this.getStatusText(selectedData.status) // 状态
|
}];
|
this.total = this.tableData.length;
|
|
// 更新确认表单数据
|
this.confirmFormData = {
|
planName: selectedData.projectName || '',
|
testCode: selectedData.experimentCode || '',
|
testName: selectedData.experimentName || '',
|
sampleCode: selectedData.experimentCode || '' // 使用实验编号作为取样单编号
|
};
|
},
|
|
// 添加状态转换方法
|
getStatusText(status) {
|
const statusMap = {
|
"-1": "草稿箱",
|
"1": "待确认",
|
"2": "已确认",
|
"3": "已封存"
|
};
|
return statusMap[status] || "未知";
|
},
|
setSelectedIds(arr, selectKeyList) {
|
function traverse(item) {
|
item.selected = selectKeyList.includes(item.menuId);
|
if (item.children && item.children.length > 0) {
|
item.children.forEach(traverse);
|
}
|
}
|
arr.forEach(traverse);
|
return arr;
|
},
|
onSubmit() {
|
this.$refs['form'].validate((valid) => {
|
if (valid) {
|
if (this.getSelectedIds(this.menu).length == 0) {
|
this.msgwarning('请勾选操作权限')
|
return
|
}
|
let obj = {
|
...this.form,
|
menuIds: this.getSelectedIds(this.menu)
|
}
|
if (this.$route.query && this.$route.query.roleId) {
|
obj.roleId = this.$route.query.roleId
|
edit(obj).then(() => {
|
this.msgsuccess('保存成功')
|
this.$router.go(-1)
|
})
|
} else {
|
add(obj).then(() => {
|
this.msgsuccess('保存成功')
|
this.form = {
|
roleName: "",
|
remark: "",
|
}
|
this.menu = []
|
this.$router.go(-1)
|
})
|
}
|
}
|
})
|
},
|
getSelectedIds(arr) {
|
let result = [];
|
function traverse(item) {
|
if (item.selected) {
|
result.push(item.menuId);
|
}
|
if (item.children && item.children.length > 0) {
|
for (let children of item.children) {
|
traverse(children);
|
}
|
}
|
}
|
|
for (let item of arr) {
|
traverse(item);
|
}
|
return result;
|
},
|
setCheckStatus1(id, status) { //点击第1级
|
if (!status) {
|
this.menu = this.menu.map(item => {
|
if (item.menuId == id) {
|
item.selected = status
|
if (item.children.length > 0) {
|
item.children = item.children.map(item1 => {
|
item1.selected = status
|
if (item1.children.length > 0) {
|
item1.children = item1.children.map(item2 => {
|
item2.selected = status
|
return { ...item2 }
|
})
|
}
|
return { ...item1 }
|
})
|
}
|
}
|
return { ...item }
|
})
|
} else {
|
this.menu = this.menu.map(item => {
|
if (item.menuId == id) {
|
item.selected = true
|
}
|
return { ...item }
|
})
|
}
|
},
|
setCheckStatus2(id, status, aId) { //点击第2级
|
this.menu = this.menu.map(item => {
|
if (item.menuId == aId) {
|
item.selected = true
|
if (item.children.length > 0) {
|
item.children = item.children.map(item1 => {
|
if (item1.menuId == id) {
|
item1.selected = status
|
}
|
return { ...item1 }
|
})
|
}
|
}
|
return { ...item }
|
})
|
},
|
setCheckStatus3(id, status, bId, aId) {//点击第3级
|
this.menu = this.menu.map(item => {
|
if (item.menuId == aId) {
|
item.selected = true
|
if (item.children.length > 0) {
|
item.children = item.children.map(item1 => {
|
if (item1.menuId == bId) {
|
item1.selected = true
|
if (item1.children.length > 0) {
|
item1.children = item1.children.map(item2 => {
|
if (item2.menuId == id) {
|
item2.selected = status
|
}
|
return { ...item2 }
|
})
|
}
|
}
|
return { ...item1 }
|
})
|
}
|
}
|
return { ...item }
|
})
|
},
|
showAddTestItem() {
|
this.currentTestItem = null // 清空当前编辑项
|
this.testItemDialogVisible = true
|
},
|
handleTestItemDialogClose() {
|
this.testItemDialogVisible = false
|
this.currentTestItem = null
|
},
|
handleTestItemConfirm(formData) {
|
if (this.currentTestItem) {
|
// 编辑模式
|
const index = this.testItems.findIndex(item => item.termCode === this.currentTestItem.termCode)
|
if (index !== -1) {
|
this.testItems.splice(index, 1, {
|
...formData,
|
id: this.currentTestItem.id // 保留原有ID
|
})
|
}
|
} else {
|
// 新增模式
|
this.testItems.push({
|
...formData,
|
id: this.generateUniqueId() // 生成唯一ID
|
})
|
}
|
this.testItemDialogVisible = false
|
this.currentTestItem = null
|
this.$message.success(this.currentTestItem ? '编辑成功' : '添加成功')
|
},
|
handleEditTestItem(row) {
|
this.currentTestItem = { ...row } // 深拷贝当前行数据
|
this.testItemDialogVisible = true
|
},
|
handleDeleteTestItem(index) {
|
this.$confirm('确认删除该检测项吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
this.testItems.splice(index, 1)
|
this.$message.success('删除成功')
|
}).catch(() => {})
|
},
|
generateUniqueId() {
|
return 'test_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
|
},
|
handleSubmit() {
|
if (this.testItems.length === 0) {
|
this.$message.warning('请至少添加一个检测项')
|
return
|
}
|
if (!this.selectedScheduling) {
|
this.$message.warning('请选择实验调度')
|
return
|
}
|
// 设置确认弹窗的数据
|
this.confirmFormData = {
|
planName: this.selectedScheduling.projectName || '', // 所属项目课题方案
|
testCode: this.selectedScheduling.experimentCode || '', // 实验编号
|
testName: this.selectedScheduling.experimentName || '', // 实验名称
|
sampleCode: this.selectedScheduling.experimentCode || '' // 取样单编号
|
}
|
this.confirmDialogVisible = true
|
},
|
async handleConfirmSubmit(signatureImage) {
|
try {
|
// 构建提交数据
|
const submitData = {
|
dispatchId: this.selectedScheduling.id, // 实验调度ID
|
auditStatus: 1, // 待确认状态
|
confirmSign:'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'|| signatureImage, // 签字图片
|
signTime: new Date().toISOString(), // 签字时间
|
testMethodConfirmSheetTerms: this.testItems.map(item => ({
|
id: item.id, // 保留原有ID(编辑时使用)
|
termCode: item.termCode,
|
termName: item.termName,
|
termType: item.termType,
|
termMethodCode: item.termMethodCode,
|
termMethod: item.termMethod,
|
sampleRequire: item.sampleRequire,
|
status: 2, // 已填写状态
|
testId: item.testId
|
}))
|
}
|
|
// 打印提交参数
|
console.log('提交确认单参数:', JSON.stringify(submitData, null, 2))
|
|
// 根据是否有 id 决定调用新增还是更新接口
|
if (this.formData.id) {
|
submitData.id = this.formData.id
|
console.log('调用更新接口,参数:', JSON.stringify(submitData, null, 2))
|
await update(submitData)
|
this.$message.success('更新成功')
|
} else {
|
console.log('调用新增接口,参数:', JSON.stringify(submitData, null, 2))
|
await add(submitData)
|
this.$message.success('提交成功')
|
}
|
|
this.confirmDialogVisible = false // 关闭弹窗
|
this.$router.go(-1)
|
} catch (error) {
|
this.$message.error((this.formData.id ? '更新' : '提交') + '失败:' + (error.message || '未知错误'))
|
}
|
},
|
async handleSaveDraft() {
|
try {
|
if (!this.selectedScheduling) {
|
this.$message.warning('请选择实验调度')
|
return
|
}
|
|
// 构建草稿数据
|
const draftData = {
|
dispatchId: this.selectedScheduling.id,
|
auditStatus: -1, // 草稿箱状态
|
testMethodConfirmSheetTerms: this.testItems.map(item => ({
|
id: item.id, // 保留原有ID(编辑时使用)
|
termCode: item.termCode,
|
termName: item.termName,
|
termType: item.termType,
|
termMethodCode: item.termMethodCode,
|
termMethod: item.termMethod,
|
sampleRequire: item.sampleRequire,
|
status: -1, // 草稿箱状态
|
testId: item.testId
|
}))
|
}
|
|
// 打印草稿参数
|
console.log('保存草稿参数:', JSON.stringify(draftData, null, 2))
|
|
// 根据是否有 id 决定调用新增还是更新接口
|
if (this.formData.id) {
|
draftData.id = this.formData.id
|
console.log('调用更新草稿接口,参数:', JSON.stringify(draftData, null, 2))
|
await update(draftData)
|
this.$message.success('更新草稿成功')
|
} else {
|
console.log('调用新增草稿接口,参数:', JSON.stringify(draftData, null, 2))
|
await add(draftData)
|
this.$message.success('保存草稿成功')
|
}
|
|
this.$router.push('/dataManagement/confirmation-sheet')
|
} catch (error) {
|
this.$message.error((this.formData.id ? '更新' : '保存') + '草稿失败:' + (error.message || '未知错误'))
|
}
|
},
|
async getDetailData(id) {
|
try {
|
const res = await getDetail({ id })
|
if (res.data) {
|
// 设置实验调度数据
|
this.selectedScheduling = {
|
id: res.data.dispatchId,
|
// ... 其他调度相关字段
|
}
|
|
// 设置检测项数据
|
this.testItems = res.data.testMethodConfirmSheetTerms.map(item => ({
|
...item,
|
id: item.id // 使用后端返回的ID
|
}))
|
|
// 设置表单数据
|
this.formData = {
|
id: res.data.id,
|
dispatchId: res.data.dispatchId,
|
auditStatus: res.data.auditStatus,
|
confirmSign: res.data.confirmSign,
|
signTime: res.data.signTime
|
}
|
}
|
} catch (error) {
|
this.$message.error('获取详情失败:' + (error.message || '未知错误'))
|
}
|
},
|
|
async handleEditSubmit(signatureImage) {
|
try {
|
const submitData = {
|
id: this.formData.id,
|
dispatchId: this.selectedScheduling.id,
|
auditStatus: 1,
|
confirmSign: signatureImage,
|
signTime: new Date().toISOString(),
|
testMethodConfirmSheetTerms: this.testItems.map(item => ({
|
id: item.id, // 保留原有ID
|
termCode: item.termCode,
|
termName: item.termName,
|
termType: item.termType,
|
termMethodCode: item.termMethodCode,
|
termMethod: item.termMethod,
|
sampleRequire: item.sampleRequire,
|
status: item.status,
|
testId: item.testId
|
}))
|
}
|
|
await update(submitData)
|
this.$message.success('更新成功')
|
this.$router.push('/dataManagement/confirmation-sheet')
|
} catch (error) {
|
this.$message.error('更新失败:' + (error.message || '未知错误'))
|
}
|
},
|
},
|
};
|
</script>
|
<style lang="less" scoped>
|
.title_box {
|
display: flex;
|
align-items: center;
|
margin-bottom: 20px;
|
font-weight: bold;
|
|
div:first-child {
|
width: 4px;
|
height: 16px;
|
background: #598DEC;
|
margin-right: 8px;
|
}
|
}
|
|
.no-data {
|
height: 100%;
|
background-color: #fff;
|
border-radius: 0 0 6px 6px;
|
border-left: 1px solid #e8e8e8;
|
border-right: 1px solid #e8e8e8;
|
border-bottom: 1px solid #e8e8e8;
|
box-sizing: border-box;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
color: #909399;
|
font-size: 14px;
|
}
|
|
.btn_box {
|
margin-top: 40px;
|
text-align: center;
|
|
button {
|
width: 220px;
|
}
|
}
|
|
.el-checkbox {
|
display: flex;
|
align-items: center;
|
}
|
|
.row,
|
.header {
|
display: flex;
|
align-items: center;
|
border: 1px solid #e8e8e8;
|
|
.w20 {
|
width: 15%;
|
padding: 8px 20px;
|
}
|
|
.sconed {
|
flex: 1;
|
|
.subpage {
|
.title {
|
border: 1px solid #e8e8e8;
|
border-top: none;
|
border-bottom: none;
|
}
|
|
.two {
|
display: flex;
|
align-items: center;
|
border: 1px solid #e8e8e8;
|
border-top: none;
|
border-right: none;
|
|
.left {
|
width: 200px;
|
padding: 13px 20px;
|
border-right: 1px solid #e8e8e8;
|
}
|
|
.right {
|
display: flex;
|
flex: 1;
|
|
div {
|
padding: 13px 0 13px 20px;
|
}
|
}
|
}
|
|
.two:last-child {
|
border-bottom: none;
|
}
|
|
.btns {
|
display: flex;
|
align-items: center;
|
padding: 0 20px;
|
}
|
}
|
}
|
}
|
|
.header {
|
border-radius: 16px 16px 0 0;
|
background-color: #FAFAFA;
|
color: #909399;
|
|
.subpage {
|
display: flex;
|
}
|
|
.title {
|
width: 200px;
|
padding: 8px 20px;
|
}
|
}
|
|
.header-title-left {
|
display: flex;
|
align-items: center;
|
gap: 13px;
|
margin-bottom: 20px;
|
|
img {
|
width: 12px;
|
height: 19px;
|
}
|
|
div {
|
flex-shrink: 0;
|
font-weight: bold;
|
font-size: 18px;
|
color: #222222;
|
line-height: 27px;
|
font-family: 'Source Han Sans CN Bold Bold';
|
}
|
|
span {
|
color: rgb(254, 115, 115);
|
font-size: 15px;
|
}
|
}
|
</style>
|