From e950c38ba82e5e6bc8b0c50c35e5dbb6a180165a Mon Sep 17 00:00:00 2001
From: 13404089107 <puwei@sinata.cn>
Date: 星期二, 20 五月 2025 16:43:06 +0800
Subject: [PATCH] Merge branch 'main' of http://120.76.84.145:10101/gitblit/r/H5/leshan-laboratory

---
 culture/src/views/strain-library/production-cell-library/index.vue |  495 +++++++++++++++++++++++++++++-------------------------
 1 files changed, 266 insertions(+), 229 deletions(-)

diff --git a/culture/src/views/strain-library/production-cell-library/index.vue b/culture/src/views/strain-library/production-cell-library/index.vue
index 1364cbf..31cfb28 100644
--- a/culture/src/views/strain-library/production-cell-library/index.vue
+++ b/culture/src/views/strain-library/production-cell-library/index.vue
@@ -2,36 +2,80 @@
   <div class="list">
     <el-card class="header-box">
       <div class="box-title">
-        <img src="@/assets/public/notice.png" class="header-icon">
-        <span>【菌种源保藏出/入细胞库登记表】说明</span>
-        <el-button type="text" class="view-more" @click="handleViewMore">查看全部 >></el-button>
+        <img src="@/assets/public/notice.png" class="header-icon" />
+        <span>菌种源保藏出/入细胞库登记表说明</span>
+        <el-button type="text" class="view-more" @click="handleViewMore"
+          >查看全部 >></el-button
+        >
       </div>
-      <div class="header-content" :class="{ 'collapsed': true }">
-        <p>1、菌种全部集中登记在【菌种源保藏出/入细胞库登记表】,请将来源有3 类菌经。</p>
-        <p>1.1 原净土管理日油性的源头菌种:入细胞细胞库(现代-O)。</p>
-        <p>1.2 是到菌的源头菌种:接种入主细胞库(现代-O),经过百种、验证后,菌种被保存日油管理沙土菌种,入细胞细胞库(现代-O)。</p>
-        <p>1.3 是否菌种能自己分离后获得的源头菌种,接种入主细胞库:经过产验证后,保藏为少土管理日油管,入细胞细胞库(现代-O)。</p>
+      <div class="header-content" :class="{ collapsed: true }">
+        <p>
+          1. 菌种全部集中登记在【菌种源保藏出/入细胞库登记表】,菌种来源有 3
+          条路径。1.1 是沙土管或甘油管的源头菌种;入原始细胞库(祖代-O)。1.2
+          是斜面的源头菌种;接种入主细胞库(祖代-O)。经过育种、验证后,菌种保藏为甘油管或沙土管的,入原始细胞库(祖代-0)1.3
+          是含菌物质自己分离后获得的斜面源头菌种,接种入主细胞库;经生产验证后,保藏为沙土管或甘油管,入原始细胞库(祖代-O)。
+          2.
+          菌种细胞库,分类入三库,进行传代运行管理。三类库存空间进行区分,保藏菌种。2.1
+          原始细胞库(祖代-O)、2.2 主细胞库(母代-M)、2.3
+          生产细胞库(子代-S)、(孙代-G)3. 细胞库编码规则3.1
+          细胞库编码规则:DD-M-240919-01-(O-0109-01)DD:代表项目组。M:“O”代表祖代原始细胞库,”M“代表母代主细胞库,”S“代表子代生产细胞库,“G”代表孙代生产细胞库。240919:代表在
+          24 年 9 月 19
+          接种批次的菌种;或收到外来菌种时间的入库批次。01:代表两位序列号。(O-0109-01):代表传代菌种的编号3.1.1
+          传代编码方式演例:祖代:DD-O-240919-01
+          传母代:DD-M-241017-01-(O-091901)DD-M-241017-02-(O-091901)DD-M-241017-03-(O-091901)子代:DD-S-241019-01-(M-1017-02)版权归奥利元生物所有,禁止外传。DD-S-241019-02-(M-1017-03)孙代:DD-G-241109-01-(S-1019-02)3.1.2
+          编码规则实现了编码唯一,编码可溯源,编码直观、方便。3.2
+          细胞库说明:3.2.1
+          直接购买、自行从(土壤、相关物料、商品)等分离出来菌株进入原始细胞库。3.2.2
+          从原始细胞库中选取出来再次纯化、改造、提高性能的菌株进入主细胞库。3.2.3
+          主细胞库中选取出稳定,生产性能良好的菌株扩培后保种进入生产细胞库。4.
+          菌种选育-保藏过程编号说明4.1 菌种选育时,培养皿的编号可使用 a-01、a-02
+          等用于清晰形态观察记录;菌落编号使用序号 1/2/3等。4.2
+          接种斜面菌种编码(-O)使用原始细胞库编码;斜面转菌种保藏使用与斜面一致的编码(-O);斜面传代入主细胞库的传代菌种,按编码器规则编码(-M)。
+        </p>
       </div>
 
       <!-- 查看全部弹窗 -->
       <el-dialog
-        title="菌种源保藏出/入生产细胞库登记表说明"
+        title="菌种源保藏出/入细胞库登记表说明"
         :visible.sync="dialogVisible"
         width="50%"
         class="view-all-dialog"
       >
         <div class="dialog-content">
-          <p>1、菌种全部集中登记在【菌种源保藏出/入细胞库登记表】,请将来源有3 类菌经。</p>
-          <p>1.1 原净土管理日油性的源头菌种:入细胞细胞库(现代-O)。</p>
-          <p>1.2 是到菌的源头菌种:接种入主细胞库(现代-O),经过百种、验证后,菌种被保存日油管理沙土菌种,入细胞细胞库(现代-O)。</p>
-          <p>1.3 是否菌种能自己分离后获得的源头菌种,接种入主细胞库:经过产验证后,保藏为少土管理日油管,入细胞细胞库(现代-O)。</p>
+          <p>
+            1. 菌种全部集中登记在【菌种源保藏出/入细胞库登记表】,菌种来源有 3
+            条路径。1.1 是沙土管或甘油管的源头菌种;入原始细胞库(祖代-O)。1.2
+            是斜面的源头菌种;接种入主细胞库(祖代-O)。经过育种、验证后,菌种保藏为甘油管或沙土管的,入原始细胞库(祖代-0)1.3
+            是含菌物质自己分离后获得的斜面源头菌种,接种入主细胞库;经生产验证后,保藏为沙土管或甘油管,入原始细胞库(祖代-O)。2.
+            菌种细胞库,分类入三库,进行传代运行管理。三类库存空间进行区分,保藏菌种。2.1
+            原始细胞库(祖代-O)、2.2 主细胞库(母代-M)、2.3
+            生产细胞库(子代-S)、(孙代-G)3. 细胞库编码规则3.1
+            细胞库编码规则:DD-M-240919-01-(O-0109-01)DD:代表项目组。M:“O”代表祖代原始细胞库,”M“代表母代主细胞库,”S“代表子代生产细胞库,“G”代表孙代生产细胞库。240919:代表在
+            24 年 9 月 19
+            接种批次的菌种;或收到外来菌种时间的入库批次。01:代表两位序列号。(O-0109-01):代表传代菌种的编号3.1.1
+            传代编码方式演例:祖代:DD-O-240919-01
+            传母代:DD-M-241017-01-(O-091901)DD-M-241017-02-(O-091901)DD-M-241017-03-(O-091901)子代:DD-S-241019-01-(M-1017-02)版权归奥利元生物所有,禁止外传。DD-S-241019-02-(M-1017-03)孙代:DD-G-241109-01-(S-1019-02)3.1.2
+            编码规则实现了编码唯一,编码可溯源,编码直观、方便。3.2
+            细胞库说明:3.2.1
+            直接购买、自行从(土壤、相关物料、商品)等分离出来菌株进入原始细胞库。3.2.2
+            从原始细胞库中选取出来再次纯化、改造、提高性能的菌株进入主细胞库。3.2.3
+            主细胞库中选取出稳定,生产性能良好的菌株扩培后保种进入生产细胞库。4.
+            菌种选育-保藏过程编号说明4.1 菌种选育时,培养皿的编号可使用
+            a-01、a-02 等用于清晰形态观察记录;菌落编号使用序号 1/2/3等。4.2
+            接种斜面菌种编码(-O)使用原始细胞库编码;斜面转菌种保藏使用与斜面一致的编码(-O);斜面传代入主细胞库的传代菌种,按编码器规则编码(-M)。
+          </p>
         </div>
       </el-dialog>
     </el-card>
 
     <!-- Table -->
-    <TableCustom :queryForm="queryForm" :tableData="tableData" :total="total" @currentChange="handleCurrentChange"
-      @sizeChange="handleSizeChange">
+    <TableCustom
+      :queryForm="queryForm"
+      :tableData="tableData"
+      :total="total"
+      @currentChange="handleCurrentChange"
+      @sizeChange="handleSizeChange"
+    >
       <template #search>
         <el-form :model="form" label-width="auto" inline>
           <el-form-item label="菌种编号:">
@@ -40,15 +84,13 @@
           <el-form-item label="菌种名称:">
             <el-input v-model="form.strainName" placeholder="请输入"></el-input>
           </el-form-item>
-          <el-form-item label="状态:">
+          <el-form-item v-if="roleType == 4" label="状态:">
             <el-select v-model="form.status" placeholder="请选择">
               <el-option label="全部" value=""></el-option>
-              <el-option 
-                v-for="item in statusOptions" 
-                :key="item.value" 
-                :label="item.label" 
-                :value="item.value">
-              </el-option>
+              <el-option label="已出库" value="1"></el-option>
+              <el-option label="出库待确认" value="2"></el-option>
+              <el-option label="已入库" value="3"></el-option>
+              <el-option label="入库待确认" value="4"></el-option>
             </el-select>
           </el-form-item>
           <el-form-item class="search-btn-box">
@@ -61,236 +103,207 @@
       <template #setting>
         <div class="tableTitle">
           <div class="flex a-center">
-            <div class="title" :class="{ active: currentType === 'list' }"
-              @click="handleTypeChange('list')">
-              生产细胞列表</div>
-            <div class="drafts" :class="{ active: currentType === 'draft' }"
-              @click="handleTypeChange('draft')">
-              草稿箱</div>
+            <div
+              class="title"
+              :class="{ active: currentType === 'list' }"
+              @click="handleTypeChange('list')"
+            >
+              生产细胞列表
+            </div>
+            <div
+              class="drafts"
+              :class="{ active: currentType === 'draft' }"
+              @click="handleTypeChange('draft')"
+            >
+              草稿箱
+            </div>
           </div>
-          <div class="flex a-center">
-            <el-button @click="handleAdd" class="el-icon-plus" type="primary" style="margin-right: 12px;">新增生产细胞</el-button>
-            <el-button @click="handleAdd" class="el-icon-plus" type="primary" style="margin-right: 12px;">批量新增</el-button>
+          <div v-if="roleType == 4" class="flex a-center">
+            <el-button
+              @click="handleNewStrain"
+              class="el-icon-plus"
+              type="primary"
+              style="margin-right: 12px"
+              >新增生产细胞</el-button
+            >
+            <el-button
+              @click="handleNewStrain"
+              class="el-icon-plus"
+              type="primary"
+              >批量新增</el-button
+            >
           </div>
         </div>
       </template>
 
       <template #table>
-        <el-table-column type="selection" width="55" />
-        <el-table-column prop="strainNo" label="菌种编号" width="150" />
-        <el-table-column prop="strainName" label="菌种名称" width="180" />
-        <el-table-column prop="source" label="菌种来源" width="150" />
-        <el-table-column prop="preservationMethod" label="鉴定方法" width="120" />
-        <el-table-column prop="storageLocation" label="特征描述" width="150" />
-        <el-table-column prop="inventory" label="菌种保存方法" width="100" />
-        <el-table-column prop="inventory" label="保存位置" width="100" />
-        <el-table-column prop="inventory" label="库存余量" width="100" />
-        <el-table-column prop="inventory" label="备注"  />
-        <el-table-column prop="status" label="状态" width="100">
-          <template slot-scope="scope">
-            <el-tag :type="getStatusType(scope.row.status)">{{ scope.row.status }}</el-tag>
+        <el-table-column prop="strainCode" label="菌种编号" />
+        <el-table-column prop="strainName" label="菌种名称" />
+        <el-table-column prop="strainSource" label="菌种来源" />
+        <el-table-column prop="appraisalMethod" label="鉴定方法" />
+        <el-table-column prop="features" label="特征描述" />
+        <el-table-column prop="saveMethod" label="菌种保存方法" />
+        <el-table-column prop="saveLocation" label="保藏位置" />
+        <el-table-column prop="stock" label="库存余量" />
+        <el-table-column prop="remark" label="备注" />
+        <el-table-column
+          v-if="currentType === 'list'"
+          prop="status"
+          label="当前状态"
+        >
+          <template #default="{ row }">
+            <el-tag :type="getStatusType(row.status)">{{
+              getStatusText(row.status)
+            }}</el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="操作" width="150" fixed="right">
-          <template slot-scope="scope">
-            <el-button type="text" @click="handleView(scope.row)">详情</el-button>
-            <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
-            <el-button type="text" @click="handleDelete(scope.row)" class="delete-btn">删除</el-button>
+        <el-table-column label="操作" width="200">
+          <template #default="{ row }">
+            <el-button type="text" @click="handleDetail(row)">详情</el-button>
+            <el-button v-if="row.status == 2 || row.status == 4" type="text" @click="handleEdit(row)">编辑</el-button>
+            <el-button
+              v-if="currentType === 'list'"
+              type="text"
+              @click="handleRecord(row)"
+              >出入库记录</el-button
+            >
+            <el-button v-if="roleType == 1" type="text" @click="handleDelete(row)">删除</el-button>
           </template>
         </el-table-column>
       </template>
     </TableCustom>
-
-    <!-- 删除确认对话框 -->
-    <el-dialog
-      title="确认删除"
-      :visible.sync="deleteDialogVisible"
-      width="30%">
-      <div class="delete-dialog-content">
-        <i class="el-icon-warning-outline warning-icon"></i>
-        <span>确定要删除该菌种记录吗?删除后将无法恢复。</span>
-      </div>
-      <span slot="footer" class="dialog-footer">
-        <el-button @click="deleteDialogVisible = false">取消</el-button>
-        <el-button type="danger" @click="confirmDelete">确定</el-button>
-      </span>
-    </el-dialog>
+    <StrainDetail :visible.sync="detailVisible" :detail="currentDetail" />
   </div>
 </template>
 
 <script>
+import StrainDetail from "../strain-library-manage/components/StrainDetail.vue";
+import { getList, deleteStrainLibrary } from "../strain-library-manage/service";
+
 export default {
-  name: 'ProductionCellLibrary',
+  name: "StrainLibraryManage",
+  components: {
+    StrainDetail,
+  },
   data() {
     return {
       dialogVisible: false,
-      currentType: 'list',
+      currentType: "list",
+      detailVisible: false,
+      currentDetail: {},
       form: {
-        strainNo: '',
-        strainName: '',
-        status: ''
+        strainNo: "",
+        strainName: "",
+        status: "",
       },
       queryForm: {
         pageSize: 10,
-        pageNum: 1
+        pageNum: 1,
       },
-      total: 100,
-      loading: false,
-      sourceOptions: [
-        { value: '主细胞库', label: '主细胞库' },
-        { value: '工作细胞库', label: '工作细胞库' },
-        { value: '外部来源', label: '外部来源' }
-      ],
-      statusOptions: [
-        { value: '正常', label: '正常' },
-        { value: '缺货', label: '缺货' },
-        { value: '异常', label: '异常' },
-        { value: '已停用', label: '已停用' }
-      ],
+      total: 800,
       tableData: [],
-      selectedRows: [],
-      deleteDialogVisible: false,
-      deleteRow: null
-    }
+      roleType: "",
+    };
   },
-  created() {
-    this.fetchData();
+  activated() {
+    this.searchData();
+    // 角色类型 1=超级管理员 2=审批人 3=工程师 4=实验员
+    this.roleType = JSON.parse(sessionStorage.getItem("userInfo")).roleType;
   },
   methods: {
+    handleDelete(row) {
+      this.$confirm("确定删除该数据吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(() => {
+        deleteStrainLibrary({ id: row.id }).then((res) => {
+            this.$message.success("删除成功");
+            this.searchData();
+        });
+      });
+    },
+    handleRecord(row) {
+      this.$router.push({
+        path: `/strain-library/strain-library-manage/record?id=${row.id}`,
+      });
+    },
+    handleNewStrain() {
+      this.$router.push({ path: "/strain-library/production-cell-library/add" });
+    },
+    handleEdit(row) {
+      this.$router.push({
+        path: `/strain-library/production-cell-library/add?id=${row.id}`,
+      });
+    },
+    handleDetail(row) {
+      this.currentDetail = row;
+      this.detailVisible = true;
+    },
     handleViewMore() {
       this.dialogVisible = true;
     },
     resetForm() {
       this.form = {
-        strainNo: '',
-        strainName: '',
-        status: ''
-      }
-      this.searchData()
+        strainNo: "",
+        strainName: "",
+        status: "",
+      };
+      this.searchData();
     },
     searchData() {
-      this.queryForm.pageNum = 1;
-      this.fetchData();
-    },
-    // 获取数据
-    fetchData() {
-      this.loading = true;
-      
-      // 构建请求参数
       const params = {
-        page: this.queryForm.pageNum,
+        pageNum: this.queryForm.pageNum,
         pageSize: this.queryForm.pageSize,
-        ...this.form
+        strainCode: this.form.strainNo,
+        strainName: this.form.strainName,
+        isDraft: this.currentType === "draft" ? 1 : 0,
+        status: this.form.status,
+        type: 3,
       };
-      
-      // 模拟API请求
-      setTimeout(() => {
-        // 模拟数据,实际项目中应替换为真实API调用
-        const mockData = [];
-        for (let i = 1; i <= 10; i++) {
-          mockData.push({
-            id: `${i}`,
-            strainNo: `PCLS-2023-${String(i).padStart(3, '0')}`,
-            strainName: `枯草芽孢杆菌生产株${i}`,
-            source: i % 3 === 0 ? '外部来源' : (i % 2 === 0 ? '工作细胞库' : '主细胞库'),
-            preservationMethod: i % 2 === 0 ? '冻干保存' : '超低温冷冻保存',
-            storageLocation: `A区-A-${100 + i}-冷藏柜`,
-            inventory: 10 + i,
-            status: i % 4 === 0 ? '异常' : (i % 3 === 0 ? '缺货' : (i % 2 === 0 ? '已停用' : '正常')),
-            preparationDate: `2023-05-${String(i).padStart(2, '0')}`,
-            expiryDate: `2024-05-${String(i).padStart(2, '0')}`
-          });
-        }
-        
-        this.tableData = mockData;
-        this.total = 100; // 模拟总数
-        this.loading = false;
-      }, 500);
+      getList(params)
+        .then((res) => {
+          if (res.code === 200) {
+            this.tableData = res.data.records;
+            this.total = res.data.total;
+          }
+        })
+        .catch((err) => {
+          this.$message.error("数据加载失败");
+        });
     },
-    
-    // 状态标签类型
-    getStatusType(status) {
-      switch(status) {
-        case '正常':
-          return 'success';
-        case '缺货':
-          return 'warning';
-        case '异常':
-          return 'danger';
-        case '已停用':
-          return 'info';
-        default:
-          return 'info';
-      }
-    },
-    
     handleCurrentChange(page) {
-      this.queryForm.pageNum = page
-      this.fetchData();
+      this.queryForm.pageNum = page;
+      this.searchData();
     },
     handleSizeChange(size) {
-      this.queryForm.pageSize = size
-      this.queryForm.pageNum = 1
-      this.fetchData();
+      this.queryForm.pageSize = size;
+      this.searchData();
     },
     handleTypeChange(type) {
       this.currentType = type;
-      this.fetchData();
+      this.searchData();
     },
-    
-    // 表格多选
-    handleSelectionChange(selection) {
-      this.selectedRows = selection;
+    getStatusType(status) {
+      const types = {
+        1: "warning",
+        2: "warning",
+        3: "success",
+        4: "success",
+      };
+      return types[status] || "info";
     },
-    
-    // 新增菌种
-    handleAdd() {
-      this.$router.push('/strain-library/production-cell-library/add');
+    getStatusText(status) {
+      const texts = {
+        1: "已出库",
+        2: "出库待确认",
+        3: "已入库",
+        4: "入库待确认",
+      };
+      return texts[status] || "未知状态";
     },
-    
-    // 查看菌种详情
-    handleView(row) {
-      this.$router.push(`/strain-library/production-cell-library/record/${row.id}`);
-    },
-    
-    // 编辑菌种
-    handleEdit(row) {
-      this.$router.push(`/strain-library/production-cell-library/edit/${row.id}`);
-    },
-    
-    // 删除菌种
-    handleDelete(row) {
-      this.deleteRow = row;
-      this.deleteDialogVisible = true;
-    },
-    
-    // 确认删除
-    confirmDelete() {
-      if (!this.deleteRow) return;
-      
-      // 模拟API请求
-      this.$message({
-        type: 'success',
-        message: `删除成功: ${this.deleteRow.strainNo} - ${this.deleteRow.strainName}`
-      });
-      
-      // 移除本地数据
-      const index = this.tableData.findIndex(item => item.id === this.deleteRow.id);
-      if (index !== -1) {
-        this.tableData.splice(index, 1);
-      }
-      
-      this.deleteDialogVisible = false;
-      this.deleteRow = null;
-    },
-    
-    // 导出
-    handleExport() {
-      this.$message.info('生产细胞库菌种导出功能开发中');
-      // 实际项目中应实现导出逻辑
-    }
-  }
-}
+  },
+};
 </script>
 
 <style scoped lang="less">
@@ -320,7 +333,7 @@
     .view-more {
       position: absolute;
       right: 0;
-      color: #049C9A;
+      color: #049c9a;
     }
   }
 
@@ -343,8 +356,50 @@
   }
 }
 
-.search-btn-box {
-  margin-left: auto;
+.search-form {
+  margin-bottom: 20px;
+  background: #f5f7fa;
+  padding: 24px;
+  border-radius: 8px;
+
+  .el-form-item {
+    margin-right: 20px;
+    margin-bottom: 0;
+  }
+
+  .el-button {
+    margin-left: 10px;
+  }
+}
+
+.action-buttons {
+  margin-bottom: 20px;
+
+  .el-button {
+    margin-right: 10px;
+  }
+}
+
+.tab-container {
+  display: flex;
+  margin-bottom: 20px;
+
+  .tab {
+    padding: 10px 30px;
+    border: 1px solid #dcdfe6;
+    border-bottom: none;
+    border-radius: 8px 8px 0 0;
+    cursor: pointer;
+    margin-right: 10px;
+    background: #f5f7fa;
+
+    &.active {
+      background: #fff;
+      border-color: #049c9a;
+      color: #049c9a;
+      font-weight: bold;
+    }
+  }
 }
 
 .flex {
@@ -371,7 +426,6 @@
     line-height: 50px;
     width: 166px;
     text-align: center;
-
   }
 
   .drafts {
@@ -394,28 +448,15 @@
     background: #ffffff;
     border-radius: 8px 8px 0px 0px;
     border: 1px solid #049c9a;
-    
-  }
-}
-
-.delete-dialog-content {
-  display: flex;
-  align-items: center;
-  padding: 20px 0;
-  
-  .warning-icon {
-    font-size: 24px;
-    color: #E6A23C;
-    margin-right: 10px;
   }
 }
 
 .view-all-dialog {
   :deep(.el-dialog__header) {
     padding: 20px;
-    border-bottom: 1px solid #EBEEF5;
+    border-bottom: 1px solid #ebeef5;
     margin-right: 0;
-    
+
     .el-dialog__title {
       font-size: 18px;
       font-weight: bold;
@@ -433,11 +474,11 @@
 
       p {
         margin: 12px 0;
-        
+
         &:first-child {
           margin-top: 0;
         }
-        
+
         &:last-child {
           margin-bottom: 0;
         }
@@ -445,8 +486,4 @@
     }
   }
 }
-
-.delete-btn {
-  color: #F56C6C;
-}
-</style>
\ No newline at end of file
+</style>

--
Gitblit v1.7.1