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/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