<template>
|
<div class="record-page">
|
<!-- 基本信息展示区域 -->
|
<el-card class="header-box">
|
<div class="header-content">
|
<!-- 第一行 -->
|
<div class="info-row">
|
<div class="info-item left-column">
|
<span class="label">菌种编号:</span>
|
<span class="value">{{ detail.strainCode }}</span>
|
</div>
|
<div class="info-item flex-column">
|
<span class="label">鉴定方法:</span>
|
<span class="value">{{ detail.appraisalMethod }}</span>
|
</div>
|
<div class="info-item flex-column">
|
<span class="label">保藏位置:</span>
|
<span class="value">{{ detail.saveLocation }}</span>
|
</div>
|
</div>
|
|
<!-- 第二行 -->
|
<div class="info-row">
|
<div class="info-item left-column">
|
<span class="label">菌种名称:</span>
|
<span class="value">{{ detail.strainName }}</span>
|
</div>
|
<div class="info-item flex-column full-width">
|
<span class="label">特性描述:</span>
|
<span class="value">{{ detail.features }}</span>
|
</div>
|
</div>
|
|
<!-- 第三行 -->
|
<div class="info-row">
|
<div class="info-item left-column">
|
<span class="label">菌种来源:</span>
|
<span class="value">{{ detail.strainSource }}</span>
|
</div>
|
<div class="info-item flex-column">
|
<span class="label">菌种保存方法:</span>
|
<span class="value">{{ detail.saveMethod }}</span>
|
</div>
|
</div>
|
</div>
|
</el-card>
|
|
<!-- 出入库记录表格 -->
|
<TableCustom
|
:queryForm="queryForm"
|
:tableData="recordList"
|
:total="total"
|
@currentChange="handlePageChange"
|
>
|
<template #setting>
|
<div class="tableTitle">
|
<div class="flex a-center">
|
<div
|
class="title"
|
:class="{ active: currentType === 'table' }"
|
@click="handleTypeChange('table')"
|
>
|
原始细胞保藏出/入库登记表
|
</div>
|
<div
|
class="drafts"
|
:class="{ active: currentType === 'timeline' }"
|
@click="handleTypeChange('timeline')"
|
>
|
原始细胞保藏出/入库时间轴
|
</div>
|
</div>
|
<div class="flex a-center">
|
<el-button
|
v-if="roleType == 4"
|
@click="handleAddRecord"
|
class="el-icon-plus"
|
type="primary"
|
>新增出入库记录</el-button
|
>
|
</div>
|
</div>
|
</template>
|
|
<template #table v-if="currentType === 'table'">
|
<el-table-column prop="type" label="出库/入库">
|
<template #default="{ row }">
|
<span>
|
{{ row.type === 1 ? "出库" : "入库" }}
|
</span>
|
</template>
|
</el-table-column>
|
<el-table-column prop="boundTime" label="操作时间" />
|
<el-table-column prop="handleSignature" label="操作人签字">
|
<template #default="{ row }">
|
<el-image
|
v-if="row.handleSignature"
|
style="width: 100px; height: 100px"
|
:src="row.handleSignature"
|
:preview-src-list="[row.handleSignature]"
|
>
|
</el-image>
|
</template>
|
</el-table-column>
|
<el-table-column prop="preserveSignature" label="菌种保藏人签字">
|
<template #default="{ row }">
|
<el-image
|
v-if="row.preserveSignature"
|
style="width: 100px; height: 100px"
|
:src="row.preserveSignature"
|
:preview-src-list="[row.preserveSignature]"
|
>
|
</el-image>
|
</template>
|
</el-table-column>
|
<el-table-column prop="status" label="状态">
|
<template #default="{ row }">
|
<el-tag :type="row.preserveSignature ? 'success' : 'warning'">
|
{{ row.preserveSignature ? "已确认" : "待确认" }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" width="180">
|
<template #default="{ row }">
|
<el-button
|
v-if="!row.preserveSignature && roleType == 3"
|
type="text"
|
class="operation-btn"
|
@click="handleConfirm(row)"
|
>确认</el-button
|
>
|
<el-button
|
type="text"
|
class="operation-btn"
|
@click="handleView(row)"
|
>详情</el-button
|
>
|
<el-button v-if="roleType == 1" type="text" @click="handleDelete(row)">删除</el-button>
|
</template>
|
</el-table-column>
|
</template>
|
<template #tableCustom v-if="currentType === 'timeline'">
|
<record-timeline :list="timelineList" />
|
</template>
|
</TableCustom>
|
|
<!-- 详情弹窗 -->
|
<record-detail-dialog
|
:visible.sync="dialogVisible"
|
:record-data="currentRecord"
|
@close="handleDialogClose"
|
@confirm="handleOutbound"
|
:type="dialogType"
|
/>
|
<!-- 新增出入库记录弹窗 -->
|
<add-record-dialog
|
:visible.sync="addDialogVisible"
|
@confirm="handleAddRecordConfirm"
|
/>
|
</div>
|
</template>
|
|
<script>
|
import RecordDetailDialog from "./components/RecordDetailDialog.vue";
|
import AddRecordDialog from "./components/AddRecordDialog.vue";
|
import RecordTimeline from "./components/RecordTimeline.vue";
|
import {
|
timeList,
|
getDetail,
|
addWarehousing,
|
getDetailById,
|
confirmWarehousing,
|
} from "./service";
|
|
export default {
|
name: "StrainRecord",
|
components: {
|
RecordDetailDialog,
|
AddRecordDialog,
|
RecordTimeline,
|
},
|
data() {
|
return {
|
currentType: "table",
|
detail: {},
|
currentPage: 1,
|
pageSize: 10,
|
total: 0,
|
queryForm: {
|
pageSize: 10,
|
pageNum: 1,
|
},
|
recordList: [],
|
timelineList: [],
|
dialogVisible: false,
|
currentRecord: {},
|
addDialogVisible: false,
|
dialogType: "detail",
|
roleType: "",
|
};
|
},
|
created() {
|
this.roleType = JSON.parse(sessionStorage.getItem("userInfo")).roleType;
|
|
// 获取路由参数中的菌种信息
|
const strainId = this.$route.query.id;
|
this.queryForm.id = strainId;
|
if (strainId) {
|
this.getStrainDetail(strainId);
|
this.getRecordList();
|
}
|
},
|
methods: {
|
handleDelete(row) {
|
this.$confirm("确定删除该数据吗?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
}).then(() => {
|
deleteWarehousing({ id: row.id }).then((res) => {
|
this.$message.success("删除成功");
|
this.getRecordList();
|
});
|
});
|
},
|
getStrainDetail(id) {
|
// 这里应该调用接口获取菌种详情
|
getDetail({ id }).then((res) => {
|
this.detail = res;
|
});
|
},
|
getRecordList() {
|
// 这里应该调用接口获取出入库记录
|
timeList(this.queryForm).then((res) => {
|
this.timelineList = res.data;
|
});
|
getDetailById({ id: this.$route.query.id }).then((res) => {
|
this.recordList = res.warehousingList.records;
|
this.total = res.warehousingList.total;
|
});
|
},
|
handleView(row) {
|
this.dialogType = "detail";
|
this.currentRecord = row;
|
this.dialogVisible = true;
|
},
|
handleConfirm(row) {
|
this.dialogType = "confirm";
|
this.currentRecord = row;
|
this.dialogVisible = true;
|
},
|
handlePageChange(page) {
|
this.queryForm.pageNum = page;
|
// 这里应该调用接口获取对应页码的数据
|
},
|
handleTypeChange(type) {
|
this.currentType = type;
|
},
|
handleAddRecord() {
|
this.addDialogVisible = true;
|
},
|
handleDialogClose() {
|
this.currentRecord = {};
|
this.dialogVisible = false;
|
},
|
handleOutbound(data) {
|
// 这里调用出库API
|
confirmWarehousing({
|
id: this.currentRecord.id,
|
preserveSignature: data.preserveSignature,
|
}).then((res) => {
|
console.log(res);
|
if (res.code == 200) {
|
this.$message.success("操作成功");
|
this.dialogVisible = false;
|
// 刷新列表
|
this.getRecordList();
|
} else {
|
this.$message.error(res.msg);
|
}
|
});
|
},
|
handleAddRecordConfirm(record) {
|
addWarehousing({ ...record, trainLibraryId: this.$route.query.id }).then(
|
(res) => {
|
this.$message.success("操作成功");
|
this.getRecordList();
|
}
|
);
|
},
|
goBack() {
|
this.$router.go(-1);
|
},
|
},
|
};
|
</script>
|
|
<style lang="less" scoped>
|
.record-page {
|
min-height: 100vh;
|
|
.header-box {
|
margin-bottom: 20px;
|
border-radius: 16px;
|
background: rgba(255, 255, 255, 0.8);
|
height: 130px;
|
overflow: hidden;
|
|
.header-content {
|
color: rgba(0, 0, 0, 0.88);
|
font-size: 14px;
|
line-height: 1.5;
|
|
.info-row {
|
display: flex;
|
flex-wrap: wrap;
|
margin-bottom: 8px;
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
.info-item {
|
display: flex;
|
align-items: flex-start;
|
margin-right: 24px;
|
margin-bottom: 6px;
|
|
&.left-column {
|
width: 33%;
|
min-width: 200px;
|
}
|
|
&.flex-column {
|
flex: 1;
|
min-width: 150px;
|
}
|
|
&.full-width {
|
flex: 1;
|
min-width: 300px;
|
}
|
|
.label {
|
color: #606266;
|
margin-right: 8px;
|
white-space: nowrap;
|
}
|
|
.value {
|
flex: 1;
|
color: #303133;
|
word-break: break-all;
|
display: -webkit-box;
|
-webkit-line-clamp: 1;
|
-webkit-box-orient: vertical;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
}
|
}
|
}
|
}
|
}
|
|
.flex {
|
display: flex;
|
align-items: center;
|
}
|
|
.tableTitle {
|
display: flex;
|
padding-bottom: 20px;
|
justify-content: space-between;
|
align-items: center;
|
|
.title {
|
background: #fafafc;
|
border-radius: 8px 8px 0px 0px;
|
border: 1px solid #dcdfe6;
|
font-weight: bold;
|
font-size: 18px;
|
color: #606266;
|
cursor: pointer;
|
height: 50px;
|
line-height: 50px;
|
width: 280px;
|
text-align: center;
|
}
|
|
.drafts {
|
background: #fafafc;
|
border-radius: 8px 8px 0px 0px;
|
border: 1px solid #dcdfe6;
|
font-weight: 400;
|
font-size: 18px;
|
color: #606266;
|
margin-left: 16px;
|
cursor: pointer;
|
height: 50px;
|
line-height: 50px;
|
width: 280px;
|
text-align: center;
|
}
|
|
.active {
|
color: #049c9a;
|
background: #ffffff;
|
border-radius: 8px 8px 0px 0px;
|
border: 1px solid #049c9a;
|
}
|
}
|
|
.timeline-container {
|
padding: 20px;
|
background: rgba(255, 255, 255, 0.8);
|
|
.timeline-card {
|
margin-bottom: 10px;
|
background: rgba(255, 255, 255, 0.8);
|
|
h4 {
|
margin: 0 0 10px;
|
font-size: 16px;
|
font-weight: bold;
|
}
|
|
p {
|
margin: 5px 0;
|
font-size: 14px;
|
}
|
}
|
}
|
|
.operation-btn {
|
margin-right: 12px;
|
}
|
}
|
</style>
|