From 8ac7e0ca090ab5ce0f8435e8af6f78a23c0dd6e0 Mon Sep 17 00:00:00 2001
From: pyt <626651354@qq.com>
Date: 星期一, 19 五月 2025 18:04:45 +0800
Subject: [PATCH] feat

---
 culture/src/views/strain-library/strain-library-manage/record.vue |  791 +++++++++++++++++++++++++++++---------------------------
 1 files changed, 408 insertions(+), 383 deletions(-)

diff --git a/culture/src/views/strain-library/strain-library-manage/record.vue b/culture/src/views/strain-library/strain-library-manage/record.vue
index 0db0f96..03eab17 100644
--- a/culture/src/views/strain-library/strain-library-manage/record.vue
+++ b/culture/src/views/strain-library/strain-library-manage/record.vue
@@ -1,413 +1,438 @@
 <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 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>
-        </el-card>
+            <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>
 
-        <!-- 出入库记录表格 -->
-        <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 @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>
 
-            <template #table v-if="currentType === 'table'">
-                <el-table-column prop="type" label="出库/入库" />
-                <el-table-column prop="operateTime" label="操作时间" />
-                <el-table-column prop="operator" label="操作人签字" />
-                <el-table-column prop="reviewer" label="菌种保藏人签字" />
-                    <el-table-column prop="status" label="状态">
-                        <template #default="{ row }">
-                            <el-tag :type="row.status === '已确认' ? 'success' : 'warning'">
-                                {{ row.status }}
-                            </el-tag>
-                        </template>
-                    </el-table-column>
-                    <el-table-column label="操作" width="180">
-                        <template #default="{ row }">
-                            <el-button type="text" class="operation-btn" @click="handleView(row)">详情</el-button>
-                            <el-button type="text" class="operation-btn" @click="handleEdit(row)">编辑</el-button>
-                            <el-button 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"
-        />
-
-        <add-record-dialog
-            :visible.sync="addDialogVisible"
-            @confirm="handleAddRecordConfirm"
-        />
-    </div>
+    <!-- 详情弹窗 -->
+    <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 } from './service' 
+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: [
-                {
-                    type: '入库',
-                    operateTime: '2025-1-21 15:46:50',
-                    operator: '张三',
-                    reviewer: '李四',
-                    status: '已确认'
-                },
-                {
-                    type: '出库',
-                    operateTime: '2025-1-21 15:46:50',
-                    operator: '张三',
-                    reviewer: '李四',
-                    status: '已确认'
-                },
-                {
-                    type: '入库',
-                    operateTime: '2025-1-21 15:46:50',
-                    operator: '张三',
-                    reviewer: '李四',
-                    status: '已确认'
-                },
-                {
-                    type: '出库',
-                    operateTime: '2025-1-21 15:46:50',
-                    operator: '张三',
-                    reviewer: '李四',
-                    status: '已确认'
-                },
-                {
-                    type: '入库',
-                    operateTime: '2025-1-21 15:46:50',
-                    operator: '李四',
-                    reviewer: '李四',
-                    status: '已确认'
-                }
-            ],
-            timelineList: [],
-            dialogVisible: false,
-            currentRecord: {},
-            addDialogVisible: false
-        }
-    },
-    computed: {
-        // timelineList() {
-        //     // 可根据需要处理数据格式,这里直接用 recordList
-        //     return this.recordList.map(item => ({
-        //         ...item,
-        //         confirmTime: item.confirmTime || item.operateTime // 若无确认时间则用操作时间
-        //     }))
-        // }
-    },
-    created() {
-        // 获取路由参数中的菌种信息
-        const strainId = this.$route.query.id
-        this.queryForm.id = strainId
-        if (strainId) {
-            this.getStrainDetail(strainId)
-            this.getRecordList()
-        }
-    },
-    methods: {
-        getStrainDetail(id) {
-            // 这里应该调用接口获取菌种详情
-            getDetail({id}).then(res => {
-                this.detail = res
-            })
-        },
-        getRecordList() {
-            // 这里应该调用接口获取出入库记录
-            timeList(this.queryForm).then(res => {
-               this.timelineList = res.data
-            })
-            this.total = this.recordList.length
-        },
-        handleView(row) {
-            this.currentRecord = { 
-                ...row,
-                operatorSignature: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', // 模拟操作人签字图片
-                reviewerSignature: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', // 模拟保藏人签字图片
-                operateTime: '2025-1-22 13:49:51',
-                confirmTime: '2025-1-22 14:30:00'
-            }
-            this.dialogVisible = true
-        },
-        handlePageChange(page) {
-            this.queryForm.pageNum = page
-            // 这里应该调用接口获取对应页码的数据
-        },
-        handleTypeChange(type) {
-            this.currentType = type
-        },
-        handleAddRecord() {
-            this.addDialogVisible = true
-        },
-        handleEdit(row) {
-            console.log('编辑记录:', row)
-            // 实现编辑记录逻辑
-        },
-        handleDelete(row) {
-            this.$confirm('确认删除该记录吗?', '提示', {
-                confirmButtonText: '确定',
-                cancelButtonText: '取消',
-                type: 'warning'
-            }).then(() => {
-                console.log('删除记录:', row)
-                // 实际项目中这里应该调用删除API
-                this.$message({
-                    type: 'success',
-                    message: '删除成功!'
-                })
-            }).catch(() => {
-                this.$message({
-                    type: 'info',
-                    message: '已取消删除'
-                })          
-            })
-        },
-        handleDialogClose() {
-            this.currentRecord = {}
-            this.dialogVisible = false
-        },
-        handleOutbound(data) {
-            // 这里调用出库API
-            console.log('出库操作:', data)
-            this.$message.success('出库成功')
-            this.dialogVisible = false
-            // 刷新列表
-            this.getRecordList()
-        },
-        handleAddRecordConfirm(record) {
-            addWarehousing({...record,trainLibraryId: this.$route.query.id}).then(res => {
-                this.$message.success('操作成功')
-                this.getRecordList() 
-            })
-        },
-        goBack() {
-            this.$router.go(-1)
-        }
+  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;
+  min-height: 100vh;
 
-    .header-box {
-        margin-bottom: 20px;
-        border-radius: 16px;
-        background: rgba(255, 255, 255, 0.8);
-        height: 130px;
-        overflow: hidden;
+  .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;
+    .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 {
+      .info-row {
         display: flex;
-        align-items: center;
-    }
+        flex-wrap: wrap;
+        margin-bottom: 8px;
 
-    .tableTitle {
-        display: flex;
-        padding-bottom: 20px;
-        justify-content: space-between;
-        align-items: center;
+        &:last-child {
+          margin-bottom: 0;
+        }
 
-        .title {
-            background: #fafafc;
-            border-radius: 8px 8px 0px 0px;
-            border: 1px solid #dcdfe6;
-            font-weight: bold;
-            font-size: 18px;
+        .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;
-            cursor: pointer;
-            height: 50px;
-            line-height: 50px;
-            width: 280px;
-            text-align: center;
-        }
+            margin-right: 8px;
+            white-space: nowrap;
+          }
 
-        .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;
+          .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;
+          }
         }
+      }
+    }
+  }
 
-        .active {
-            color: #049c9a;
-            background: #ffffff;
-            border-radius: 8px 8px 0px 0px;
-            border: 1px solid #049c9a;
-        }
+  .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;
     }
 
-    .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;
-            }
-        }
+    .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;
     }
 
-    .operation-btn {
-        margin-right: 12px;
+    .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> 
\ No newline at end of file
+</style>

--
Gitblit v1.7.1