| | |
| | | title: "新增菌种传代生产谱系图", |
| | | }, |
| | | component: () => import("../views/pedigree-chart/add"), |
| | | }, |
| | | { |
| | | path: 'breeding-record', |
| | | name: 'BreedingRecord', |
| | | meta: { |
| | | title: "菌种选育保藏记录", |
| | | }, |
| | | component: () => import("../views/strain-library/breeding-record"), |
| | | }, |
| | | { |
| | | path: 'add-breeding-record', |
| | | name: 'AddBreedingRecord', |
| | | meta: { |
| | | title: "新增菌种选育保藏记录", |
| | | hide: true, |
| | | }, |
| | | component: () => import("../views/strain-library/breeding-record/add"), |
| | | }, |
| | | { |
| | | path: 'validation', |
| | | meta: { |
| | | title: "菌种验证数据资料", |
| | | }, |
| | | children: [ |
| | | { |
| | | path: 'primitive-cell', |
| | | meta: { |
| | | title: '原始细胞库资料' |
| | | }, |
| | | component: () => import("../views/strain-library/validation/primitive-cell") |
| | | }, |
| | | { |
| | | path: 'chief-cell', |
| | | meta: { |
| | | title: '主细胞库资料' |
| | | }, |
| | | component: () => import("../views/strain-library/validation/chief-cell") |
| | | } |
| | | ] |
| | | }, |
| | | ] |
| | | }, { |
| | | path: "/strainReportLibrary", |
| | | component: Layouts, |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <Card> |
| | | <el-form ref="form" :model="form" :rules="rules" inline label-position="top"> |
| | | <div class="header-title" style="width: 100%"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>来源类型</div> |
| | | </div> |
| | | </div> |
| | | <div class="flex" style="margin-bottom: 20px"> |
| | | <div class="tabs"> |
| | | <div :class="{ active: activeTab === 'strain' }" @click="activeTab = 'strain'"> |
| | | 来源菌株 |
| | | </div> |
| | | <div :class="{ active: activeTab === 'material' }" @click="activeTab = 'material'"> |
| | | 来源物资 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 来源菌株 --> |
| | | <el-row v-if="activeTab === 'strain'" :gutter="10"> |
| | | <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8"> |
| | | <el-form-item label="菌株编号" prop="strainCode" required> |
| | | <el-input v-model="form.strainCode" class="w-380" placeholder="请输入菌株编号" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8"> |
| | | <el-form-item label="菌株名称" prop="strainName" required> |
| | | <el-input v-model="form.strainName" class="w-380" placeholder="请输入菌株名称" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8"> |
| | | <el-form-item label="培养基配方" prop="mediumFormula" required> |
| | | <el-input v-model="form.mediumFormula" class="w-380" placeholder="请输入培养基配方" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- 来源物资 --> |
| | | <el-row v-if="activeTab === 'material'" :gutter="10"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="来源物资、时间及批号" prop="materialCode" required> |
| | | <el-input v-model="form.materialCode" placeholder="请输入物资编号" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="培养基配方" prop="materialName" required> |
| | | <el-input v-model="form.materialName" placeholder="请输入物资名称" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="分离菌落编号" prop="materialDescription" required> |
| | | <el-input v-model="form.materialDescription" placeholder="请输入物资描述" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="header-title" style="margin-top: 20px;"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>培养条件</div> |
| | | </div> |
| | | </div> |
| | | <el-row :gutter="10"> |
| | | <el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6"> |
| | | <el-form-item label="培养基" prop="strainCode" required> |
| | | <el-input v-model="form.strainCode" class="w-380" placeholder="请输入培养基" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6"> |
| | | <el-form-item label="培养温度" prop="strainName" required> |
| | | <el-input v-model="form.strainName" class="w-380" placeholder="请输入培养温度" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6"> |
| | | <el-form-item label="需氧类型" prop="mediumFormula" required> |
| | | <el-input v-model="form.mediumFormula" class="w-380" placeholder="请输入需氧类型" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6"> |
| | | <el-form-item label="培养时间" prop="mediumFormula" required> |
| | | <el-input v-model="form.mediumFormula" class="w-380" placeholder="请输入培养时间" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="header-title" style="margin-top: 20px;"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>一、培养基分离记录</div> |
| | | </div> |
| | | <div class="header-title-right"> |
| | | <el-button @click="showSeparationDialog = true" class="el-icon-circle-plus-outline" type="primary"> |
| | | 新增培养皿分离记录</el-button> |
| | | </div> |
| | | </div> |
| | | <SeparationRecordDialog |
| | | :visible.sync="showSeparationDialog" |
| | | @save="handleSeparationSave" |
| | | /> |
| | | <Table :height="null" :queryForm="queryForm" :total="0"> |
| | | <template> |
| | | <el-table-column prop="name" label="培养皿序号" /> |
| | | <el-table-column prop="age" label="分离菌落编号" /> |
| | | <el-table-column prop="age" label="接种操作人签字" /> |
| | | <el-table-column prop="age" label="操作时间" /> |
| | | <el-table-column prop="address" label="操作"> |
| | | <template slot-scope="scope"><el-button type="text" |
| | | @click="handleEdit(scope.row)">编辑</el-button> |
| | | <el-button type="text" |
| | | @click="handleEdit(scope.row)">删除</el-button></template> |
| | | </el-table-column> |
| | | </template> |
| | | </Table> |
| | | <div class="header-title" style="margin-top: 20px;"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>二、培养皿生物学形态观察记录</div> |
| | | </div> |
| | | <div class="header-title-right"> |
| | | <el-button @click="showChoose = true" class="el-icon-circle-plus-outline" type="primary"> |
| | | 新增观察记录</el-button> |
| | | </div> |
| | | </div> |
| | | <Table :height="null" :queryForm="queryForm" :total="0"> |
| | | <template> |
| | | <el-table-column prop="age" label="分离菌落编号" /> |
| | | <el-table-column prop="age" label="形状强壮度排名" /> |
| | | <el-table-column prop="address" label="操作"> |
| | | <template slot-scope="scope"><el-button type="text" |
| | | @click="handleEdit(scope.row)">形态记录</el-button> |
| | | <el-button type="text" |
| | | @click="handleEdit(scope.row)">删除</el-button></template> |
| | | </el-table-column> |
| | | </template> |
| | | </Table> |
| | | <div class="header-title" style="margin-top: 20px;"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>三、接种斜面记录</div> |
| | | </div> |
| | | <div class="header-title-right"> |
| | | <el-button @click="showInoculationSlopeDialog = true" class="el-icon-circle-plus-outline" type="primary"> |
| | | 新增斜面记录</el-button> |
| | | </div> |
| | | </div> |
| | | <InoculationSlopeRecordDialog |
| | | :visible.sync="showInoculationSlopeDialog" |
| | | @save="handleInoculationSlopeSave" |
| | | /> |
| | | <Table :height="null" :queryForm="queryForm" :total="0"> |
| | | <template> |
| | | <el-table-column prop="age" label="分离菌落编号" /> |
| | | <el-table-column prop="age" label="接种斜面编号" /> |
| | | <el-table-column prop="age" label="接种操作人" /> |
| | | <el-table-column prop="age" label="接种操作人签字" /> |
| | | <el-table-column prop="age" label="接种操作时间" /> |
| | | <el-table-column prop="age" label="入库/废弃" /> |
| | | <el-table-column prop="age" label="入库总数(只)" /> |
| | | <el-table-column prop="age" label="菌种保藏人签字" /> |
| | | <el-table-column prop="age" label="入库保藏/废弃时间" /> |
| | | |
| | | <el-table-column prop="address" label="操作"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" |
| | | @click="handleEdit(scope.row)">删除</el-button> |
| | | <el-button type="text" |
| | | @click="showConfirmStorageDialog = true">确认入库</el-button></template> |
| | | </el-table-column> |
| | | </template> |
| | | </Table> |
| | | <ConfirmStorageDialog |
| | | :visible.sync="showConfirmStorageDialog" |
| | | @confirm="handleConfirmStorage" |
| | | /> |
| | | <div class="header-title" style="margin-top: 20px;"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>四、菌种保藏记录</div> |
| | | </div> |
| | | <div class="header-title-right"> |
| | | <el-button @click="showPreserveStrainDialog = true" class="el-icon-circle-plus-outline" type="primary"> |
| | | 新增菌种保藏记录</el-button> |
| | | </div> |
| | | </div> |
| | | <Table :height="null" :queryForm="queryForm" :total="0"> |
| | | <template> |
| | | <el-table-column prop="age" label="用于保藏的菌种编号" /> |
| | | <el-table-column prop="age" label="实验验证结论" /> |
| | | <el-table-column prop="age" label="保藏方法" /> |
| | | <el-table-column prop="age" label="保藏菌种编号" /> |
| | | <el-table-column prop="age" label="菌种保藏人签字" /> |
| | | <el-table-column prop="age" label="保藏时间" /> |
| | | <el-table-column prop="address" label="操作"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" |
| | | @click="handleEdit(scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </template> |
| | | </Table> |
| | | <PreserveStrainRecordDialog |
| | | :visible.sync="showPreserveStrainDialog" |
| | | @save="handlePreserveStrainSave" |
| | | /> |
| | | <div class="end-btn"> |
| | | <el-button type="primary">提交</el-button> |
| | | <el-button type="primary">同步给保藏人</el-button> |
| | | <el-button type="default">存草稿</el-button> |
| | | </div> |
| | | </el-form> |
| | | </Card> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | import AiEditor from "@/components/AiEditor"; |
| | | import SeparationRecordDialog from './separation-record-dialog.vue'; |
| | | import InoculationSlopeRecordDialog from './inoculation-slope-record-dialog.vue'; |
| | | import PreserveStrainRecordDialog from './preserve-strain-record-dialog.vue'; |
| | | import ConfirmStorageDialog from './confirm-storage-dialog.vue'; |
| | | export default { |
| | | components: { AiEditor, SeparationRecordDialog, InoculationSlopeRecordDialog, PreserveStrainRecordDialog, ConfirmStorageDialog }, |
| | | name: "AddBreedingRecord", |
| | | data() { |
| | | return { |
| | | form: { |
| | | strainCode: "", |
| | | strainName: "", |
| | | mediumFormula: "", |
| | | materialCode: "", |
| | | materialName: "", |
| | | materialDescription: "", |
| | | planName: "", |
| | | planCode: "", |
| | | stage: "", |
| | | creator: "", |
| | | createTime: "", |
| | | approvalComment: "", |
| | | status: "pending", |
| | | approver: "", |
| | | approveTime: "", |
| | | }, |
| | | rules: { |
| | | strainCode: [{ required: true, message: "请输入菌株编号", trigger: "blur" }], |
| | | strainName: [{ required: true, message: "请输入菌株名称", trigger: "blur" }], |
| | | mediumFormula: [{ required: true, message: "请输入培养基配方", trigger: "blur" }], |
| | | materialCode: [{ required: true, message: "请输入物资编号", trigger: "blur" }], |
| | | materialName: [{ required: true, message: "请输入物资名称", trigger: "blur" }], |
| | | materialDescription: [{ required: true, message: "请输入物资描述", trigger: "blur" }], |
| | | }, |
| | | activeTab: "strain", // 默认显示来源菌株表单 |
| | | fileList: [], // 附件列表 |
| | | showChoose: false, |
| | | radio1: 1, |
| | | status: "1", |
| | | remark: "", |
| | | queryForm: {}, |
| | | showSeparationDialog: false, |
| | | separationRecords: [], // 用于存储分离记录 |
| | | showInoculationSlopeDialog: false, |
| | | inoculationSlopeRecords: [], |
| | | showPreserveStrainDialog: false, |
| | | preserveStrainRecords: [], |
| | | showConfirmStorageDialog: false, |
| | | }; |
| | | }, |
| | | methods: { |
| | | handleSeparationSave(record) { |
| | | this.separationRecords.push(record); |
| | | // 这里可以根据需要将数据同步到表格等 |
| | | }, |
| | | handleInoculationSlopeSave(record) { |
| | | this.inoculationSlopeRecords.push(record); |
| | | }, |
| | | handlePreserveStrainSave(record) { |
| | | this.preserveStrainRecords.push(record); |
| | | }, |
| | | handleConfirmStorage() { |
| | | // 这里可以处理确认入库后的逻辑 |
| | | this.showConfirmStorageDialog = false; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | ::v-deep(.el-form-item) { |
| | | width: 100%; |
| | | |
| | | .el-input__inner { |
| | | width: 100%; |
| | | } |
| | | |
| | | .w-380 { |
| | | width: 280px; |
| | | } |
| | | } |
| | | |
| | | .mt-unset { |
| | | margin-top: unset !important; |
| | | } |
| | | |
| | | .flex { |
| | | display: flex; |
| | | } |
| | | |
| | | .tabs { |
| | | display: flex; |
| | | align-items: center; |
| | | border: 2px solid rgba(4, 156, 154, 0.5); |
| | | border-radius: 10px; |
| | | padding: 4px; |
| | | |
| | | div { |
| | | width: 183px; |
| | | height: 32px; |
| | | border-radius: 10px; |
| | | text-align: center; |
| | | line-height: 32px; |
| | | font-size: 16px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .active { |
| | | background: #ebfefd; |
| | | color: #049c9a; |
| | | } |
| | | |
| | | .inactive { |
| | | background: #fff; |
| | | color: #333333; |
| | | } |
| | | } |
| | | |
| | | .header-title { |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | margin-bottom: 20px; |
| | | gap: 13px; |
| | | |
| | | .header-title-left { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 13px; |
| | | |
| | | 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 { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | } |
| | | } |
| | | |
| | | .header-title-left :first-child { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | |
| | | .header-title:first-child { |
| | | .header-title-left { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | |
| | | .end-btn { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 10px; |
| | | margin-top: 20px; |
| | | |
| | | button { |
| | | width: 180px; |
| | | height: 36px; |
| | | // background: #409EFF; |
| | | } |
| | | } |
| | | |
| | | .member-list { |
| | | margin-top: 18px; |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 28px; |
| | | |
| | | .member-list-card { |
| | | width: 340px; |
| | | height: 400px; |
| | | border-radius: 8px; |
| | | border: 1px solid #dcdfe6; |
| | | background: linear-gradient(to bottom, |
| | | rgba(5, 160, 193, 0.2) 0%, |
| | | rgba(5, 242, 194, 0) 70%); |
| | | |
| | | .member-item { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .member-title { |
| | | margin-top: 20px; |
| | | width: 100%; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | font-weight: bold; |
| | | font-size: 16px; |
| | | color: rgba(0, 0, 0, 0.8); |
| | | line-height: 16px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .flex1 { |
| | | flex: 1; |
| | | } |
| | | |
| | | .member-name-box { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .member-name-box-2 { |
| | | flex: 1; |
| | | padding: 0 20px; |
| | | padding-top: 40px; |
| | | display: grid; |
| | | grid-template-columns: repeat(4, 1fr); |
| | | gap: 20px; |
| | | justify-items: center; |
| | | align-items: start; |
| | | } |
| | | |
| | | .member-name { |
| | | width: 60px; |
| | | height: 60px; |
| | | background: #7d8b79; |
| | | border-radius: 50%; |
| | | text-align: center; |
| | | line-height: 60px; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | color: #ffffff; |
| | | margin: 0; |
| | | } |
| | | |
| | | .member-change { |
| | | display: flex; |
| | | justify-content: center; |
| | | padding: 10px 0; |
| | | margin-top: auto; |
| | | cursor: pointer; |
| | | |
| | | .member-change-btn { |
| | | background: #fff1f0; |
| | | border-radius: 4px; |
| | | border: 1px solid #ffccc7; |
| | | padding: 1px 8px; |
| | | font-weight: 400; |
| | | font-size: 12px; |
| | | color: #ff4d4f; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-dialog |
| | | :visible.sync="visible" |
| | | title="" |
| | | width="520px" |
| | | :close-on-click-modal="false" |
| | | custom-class="record-detail-dialog" |
| | | @close="handleClose" |
| | | > |
| | | <div class="dialog-content"> |
| | | <div class="confirm-tip"> |
| | | 是否确认该项菌种信息? |
| | | <span class="danger">确认后将无法再次编辑菌种传代项内容</span> |
| | | </div> |
| | | <el-form :model="form" :rules="rules" ref="form" label-position="top"> |
| | | <el-form-item required> |
| | | <template #label> |
| | | <span>菌种保藏人签字</span> |
| | | <el-button type="primary" class="sign-btn" @click="showSignature = true">签名</el-button> |
| | | </template> |
| | | <div class="signature-area" :class="{ 'waiting': !form.signature }"> |
| | | <template v-if="form.signature"> |
| | | <img :src="form.signature" alt="菌种保藏人签字" /> |
| | | </template> |
| | | <template v-else> |
| | | <span class="waiting-text">等待确认</span> |
| | | </template> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <div class="footer-btns"> |
| | | <el-button @click="handleClose" style="margin-right: 16px;">取消</el-button> |
| | | <el-button type="primary" @click="handleConfirm">确认</el-button> |
| | | </div> |
| | | <signature-canvas :visible.sync="showSignature" @confirm="handleSignatureConfirm" /> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script> |
| | | import SignatureCanvas from '@/components/SignatureCanvas.vue'; |
| | | export default { |
| | | name: 'ConfirmStorageDialog', |
| | | components: { SignatureCanvas }, |
| | | props: { |
| | | visible: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | form: { |
| | | signature: '' |
| | | }, |
| | | rules: { |
| | | signature: [ |
| | | { required: true, message: '请签名', trigger: 'change' } |
| | | ] |
| | | }, |
| | | showSignature: false |
| | | } |
| | | }, |
| | | methods: { |
| | | handleClose() { |
| | | this.$emit('update:visible', false) |
| | | }, |
| | | handleConfirm() { |
| | | this.$refs.form.validate(valid => { |
| | | if (!valid) return |
| | | this.$emit('confirm', { ...this.form }) |
| | | this.handleClose() |
| | | }) |
| | | }, |
| | | handleSignatureConfirm(dataUrl) { |
| | | this.form.signature = dataUrl |
| | | this.showSignature = false |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .confirm-tip { |
| | | color: #f5222d; |
| | | font-size: 16px; |
| | | margin-bottom: 24px; |
| | | .danger { |
| | | margin-left: 12px; |
| | | } |
| | | } |
| | | .signature-area { |
| | | height: 120px; |
| | | width: 100%; |
| | | background: #F5F7FA; |
| | | border-radius: 4px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border: 1px solid #DCDFE6; |
| | | overflow: hidden; |
| | | padding: 0; |
| | | } |
| | | .signature-area.waiting { |
| | | border-style: dashed; |
| | | background: #FAFAFA; |
| | | } |
| | | .signature-area img { |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: cover; |
| | | display: block; |
| | | } |
| | | .waiting-text { |
| | | color: #909399; |
| | | font-size: 14px; |
| | | } |
| | | .sign-btn { |
| | | height: 32px; |
| | | border-radius: 4px; |
| | | font-size: 14px; |
| | | padding: 0 20px; |
| | | font-weight: 400; |
| | | margin-left: 12px; |
| | | } |
| | | .footer-btns { |
| | | display: flex; |
| | | justify-content: center; |
| | | padding: 24px; |
| | | padding-top: 0; |
| | | .el-button { |
| | | width: 150px; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="list"> |
| | | <TableCustom :queryForm="form" :tableData="tableData" :total="total"> |
| | | <template #search> |
| | | <el-form :model="form" labelWidth="auto" inline> |
| | | <el-form-item label="来源类型:"> |
| | | <el-input v-model="form.planName" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="培养基:"> |
| | | <el-input v-model="form.planCode" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="培养基配方:"> |
| | | <el-input v-model="form.planCode" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="需氧类型"> |
| | | <el-input v-model="form.creator" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label=""> |
| | | <el-button type="default" @click="resetForm">重置</el-button> |
| | | <el-button type="primary" style="margin-left: 10px;" @click="handleSearch">查询</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | <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> |
| | | <div class="flex a-center"> |
| | | <el-button |
| | | @click="handleNewStrain" |
| | | class="el-icon-plus" |
| | | type="primary" |
| | | style="margin-right: 12px" |
| | | >新增保藏记录</el-button |
| | | > |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <template #table> |
| | | <el-table-column prop="stage" label="来源类型"></el-table-column> |
| | | <el-table-column prop="creator" label="培养基"></el-table-column> |
| | | <el-table-column prop="creator" label="培养基配方"></el-table-column> |
| | | <el-table-column prop="createTime" label="培养温度"></el-table-column> |
| | | <el-table-column prop="approver" label="需氧类型"></el-table-column> |
| | | <el-table-column prop="approver" label="创建人"></el-table-column> |
| | | <el-table-column prop="approveTime" label="创建时间"></el-table-column> |
| | | <el-table-column label="操作" width="250"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" @click="handleDetail(scope.row)" |
| | | >详情</el-button |
| | | > |
| | | <el-button type="text" @click="handleEdit(scope.row)" |
| | | >编辑</el-button |
| | | > |
| | | <el-button type="text" @click="handleDelete(scope.row)" |
| | | >删除</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </template> |
| | | </TableCustom> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: "BreedingRecord", |
| | | components: {}, |
| | | data() { |
| | | return { |
| | | currentType: "list", // 当前显示类型:list-列表,draft-草稿箱 |
| | | form: { |
| | | planName: "", |
| | | planCode: "", |
| | | creator: "", |
| | | createTime: [], |
| | | approver: "", |
| | | status: "", |
| | | }, |
| | | tableData: [], |
| | | total: 0, |
| | | // 模拟数据 |
| | | mockListData: [ |
| | | { |
| | | planCode: "PLAN-2024-001", |
| | | planName: "2024年度实验室设备升级方案", |
| | | stage: "规划阶段", |
| | | creator: "张三", |
| | | createTime: "2024-03-15", |
| | | status: "pending", |
| | | approver: "李四", |
| | | approveTime: "2024-03-16", |
| | | }, |
| | | { |
| | | planCode: "PLAN-2024-002", |
| | | planName: "实验室安全管理制度更新方案", |
| | | stage: "实施阶段", |
| | | creator: "王五", |
| | | createTime: "2024-03-14", |
| | | status: "approved", |
| | | approver: "赵六", |
| | | approveTime: "2024-03-15", |
| | | }, |
| | | { |
| | | planCode: "PLAN-2024-003", |
| | | planName: "实验室人员培训计划", |
| | | stage: "准备阶段", |
| | | creator: "孙七", |
| | | createTime: "2024-03-13", |
| | | status: "rejected", |
| | | approver: "周八", |
| | | approveTime: "2024-03-14", |
| | | }, |
| | | ], |
| | | mockDraftData: [ |
| | | { |
| | | planCode: "DRAFT-2024-001", |
| | | planName: "实验室设备采购计划(草稿)", |
| | | stage: "规划阶段", |
| | | creator: "张三", |
| | | createTime: "2024-03-16", |
| | | status: "draft", |
| | | approver: "", |
| | | approveTime: "", |
| | | }, |
| | | { |
| | | planCode: "DRAFT-2024-002", |
| | | planName: "实验室改造方案(草稿)", |
| | | stage: "准备阶段", |
| | | creator: "李四", |
| | | createTime: "2024-03-15", |
| | | status: "draft", |
| | | approver: "", |
| | | approveTime: "", |
| | | }, |
| | | ], |
| | | approvalDialogVisible: false, |
| | | approvalDialogType: "approve", |
| | | currentApprovalData: null, |
| | | }; |
| | | }, |
| | | created() { |
| | | this.getTableData(); |
| | | }, |
| | | methods: { |
| | | resetForm() { |
| | | this.form = { |
| | | planName: "", |
| | | planCode: "", |
| | | creator: "", |
| | | createTime: [], |
| | | approver: "", |
| | | status: "", |
| | | }; |
| | | }, |
| | | handleNewStrain() { |
| | | this.$router.push({ |
| | | path: "/strain/add-breeding-record", |
| | | }); |
| | | }, |
| | | handleSearch() { |
| | | // 实现查询逻辑 |
| | | console.log("查询条件:", this.form); |
| | | }, |
| | | getStatusType(status) { |
| | | const statusMap = { |
| | | pending: "warning", |
| | | rejected: "danger", |
| | | approved: "success", |
| | | archived: "info", |
| | | draft: "info", |
| | | }; |
| | | return statusMap[status] || "info"; |
| | | }, |
| | | getStatusText(status) { |
| | | const statusMap = { |
| | | pending: "待审批", |
| | | rejected: "已驳回", |
| | | approved: "已通过", |
| | | archived: "已封存", |
| | | draft: "草稿", |
| | | }; |
| | | return statusMap[status] || "未知"; |
| | | }, |
| | | handleAddPlan() { |
| | | this.$router.push({ |
| | | path: "/dataManagement/addPlan", |
| | | }); |
| | | }, |
| | | handleApprove(row) { |
| | | this.currentApprovalData = row; |
| | | this.approvalDialogType = "approve"; |
| | | this.approvalDialogVisible = true; |
| | | }, |
| | | handleApproveSubmit(data) { |
| | | // 处理审批通过 |
| | | console.log("审批通过:", data); |
| | | this.approvalDialogVisible = false; |
| | | this.$message.success("审批通过成功"); |
| | | this.getTableData(); |
| | | }, |
| | | handleRejectSubmit(data) { |
| | | // 处理审批驳回 |
| | | console.log("审批驳回:", data); |
| | | this.approvalDialogVisible = false; |
| | | this.$message.success("审批驳回成功"); |
| | | this.getTableData(); |
| | | }, |
| | | handleRevokeApprove(row) { |
| | | // 实现撤销审批逻辑 |
| | | console.log("撤销审批数据:", row); |
| | | }, |
| | | handleEdit(row) { |
| | | // 实现编辑逻辑 |
| | | console.log("编辑数据:", row); |
| | | }, |
| | | handleDelete(row) { |
| | | // 实现删除逻辑 |
| | | console.log("删除数据:", row); |
| | | }, |
| | | handleDetail(row) { |
| | | this.currentApprovalData = row; |
| | | this.approvalDialogType = "view"; |
| | | this.approvalDialogVisible = true; |
| | | }, |
| | | handleTypeChange(type) { |
| | | this.currentType = type; |
| | | this.getTableData(); |
| | | }, |
| | | getTableData() { |
| | | // 根据currentType请求不同的数据 |
| | | if (this.currentType === "list") { |
| | | this.tableData = this.mockListData; |
| | | this.total = this.mockListData.length; |
| | | } else { |
| | | this.tableData = this.mockDraftData; |
| | | this.total = this.mockDraftData.length; |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .list { |
| | | height: 100%; |
| | | } |
| | | .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; |
| | | padding: 16px 29px; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #606266; |
| | | width: unset; |
| | | cursor: pointer; |
| | | } |
| | | .drafts { |
| | | padding: 16px 65px; |
| | | 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; |
| | | } |
| | | .active { |
| | | color: #049c9a; |
| | | background: #ffffff; |
| | | border-radius: 8px 8px 0px 0px; |
| | | border: 1px solid #049c9a; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-dialog |
| | | :visible.sync="visible" |
| | | title="新增接种斜面记录" |
| | | width="700px" |
| | | @close="handleClose" |
| | | > |
| | | <el-form |
| | | :model="form" |
| | | :rules="rules" |
| | | ref="form" |
| | | label-width="120px" |
| | | label-position="top" |
| | | > |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="分离菌落编号" prop="colonyCode" required> |
| | | <el-input v-model="form.colonyCode" placeholder="请输入" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="接种斜面编号" prop="slopeCode" required> |
| | | <el-input v-model="form.slopeCode" placeholder="请输入" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="保存/废弃" prop="status" required> |
| | | <el-button |
| | | :type="form.status === '保存' ? 'primary' : 'default'" |
| | | @click="form.status = '保存'" |
| | | >保存</el-button |
| | | > |
| | | <el-button |
| | | :type="form.status === '废弃' ? 'primary' : 'default'" |
| | | @click="form.status = '废弃'" |
| | | >废弃</el-button |
| | | > |
| | | </el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="菌种入库时间" prop="storageTime" required> |
| | | <el-input |
| | | v-model="form.storageTime" |
| | | disabled |
| | | placeholder="自动回填" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="接种操作时间" prop="operationTime" required> |
| | | <el-input |
| | | v-model="form.operationTime" |
| | | disabled |
| | | placeholder="自动填入" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item required> |
| | | <template #label> |
| | | <span>接种操作人签字</span> |
| | | <el-button type="primary" class="sign-btn" @click="showSignature = true">签名</el-button> |
| | | </template> |
| | | <div class="signature-area" :class="{ 'waiting': !form.signature }"> |
| | | <template v-if="form.signature"> |
| | | <img :src="form.signature" alt="接种操作人签字" /> |
| | | </template> |
| | | <template v-else> |
| | | <span class="waiting-text">等待确认</span> |
| | | </template> |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div style="text-align: center; margin-top: 20px"> |
| | | <el-button @click="handleClose" style="margin-right: 16px;">取消</el-button> |
| | | <el-button type="primary" @click="handleSave">确认</el-button> |
| | | </div> |
| | | <signature-canvas :visible.sync="showSignature" @confirm="handleSignatureConfirm" /> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script> |
| | | import SignatureCanvas from '@/components/SignatureCanvas.vue'; |
| | | |
| | | export default { |
| | | components: { SignatureCanvas }, |
| | | props: { visible: Boolean }, |
| | | data() { |
| | | return { |
| | | form: { |
| | | colonyCode: "", |
| | | slopeCode: "", |
| | | status: "保存", |
| | | storageTime: this.getNowTime(), |
| | | operationTime: this.getNowTime(), |
| | | signature: "", |
| | | }, |
| | | rules: { |
| | | colonyCode: [ |
| | | { required: true, message: "请输入分离菌落编号", trigger: "blur" }, |
| | | ], |
| | | slopeCode: [ |
| | | { required: true, message: "请输入接种斜面编号", trigger: "blur" }, |
| | | ], |
| | | status: [ |
| | | { required: true, message: "请选择保存/废弃", trigger: "change" }, |
| | | ], |
| | | signature: [{ required: true, message: "请签名", trigger: "change" }], |
| | | }, |
| | | showSignature: false, |
| | | }; |
| | | }, |
| | | methods: { |
| | | getNowTime() { |
| | | const d = new Date(); |
| | | return ( |
| | | d.getFullYear() + |
| | | "-" + |
| | | (d.getMonth() + 1).toString().padStart(2, "0") + |
| | | "-" + |
| | | d.getDate().toString().padStart(2, "0") + |
| | | " " + |
| | | d.getHours().toString().padStart(2, "0") + |
| | | ":" + |
| | | d.getMinutes().toString().padStart(2, "0") |
| | | ); |
| | | }, |
| | | handleSave() { |
| | | this.$refs.form.validate((valid) => { |
| | | if (valid) { |
| | | this.$emit("save", { ...this.form }); |
| | | this.handleClose(); |
| | | } |
| | | }); |
| | | }, |
| | | handleClose() { |
| | | this.$emit("update:visible", false); |
| | | }, |
| | | handleSignatureConfirm(dataUrl) { |
| | | this.form.signature = dataUrl; |
| | | this.showSignature = false; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .signature-area { |
| | | height: 120px; |
| | | width: 100%; |
| | | background: #F5F7FA; |
| | | border-radius: 4px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border: 1px solid #DCDFE6; |
| | | overflow: hidden; |
| | | padding: 0; |
| | | } |
| | | .signature-area.waiting { |
| | | border-style: dashed; |
| | | background: #FAFAFA; |
| | | } |
| | | .signature-area img { |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: cover; |
| | | display: block; |
| | | } |
| | | .waiting-text { |
| | | color: #909399; |
| | | font-size: 14px; |
| | | } |
| | | .sign-btn { |
| | | height: 32px; |
| | | border-radius: 4px; |
| | | font-size: 14px; |
| | | padding: 0 20px; |
| | | font-weight: 400; |
| | | margin-left: 12px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-dialog |
| | | :visible.sync="visible" |
| | | title="新增菌种保藏记录" |
| | | width="900px" |
| | | @close="handleClose" |
| | | > |
| | | <el-form |
| | | :model="form" |
| | | :rules="rules" |
| | | ref="form" |
| | | label-width="120px" |
| | | label-position="top" |
| | | > |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="用于保藏的菌种编号" prop="strainCode" required> |
| | | <el-input v-model="form.strainCode" placeholder="请输入" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="实验验证结论" prop="experimentConclusion" required> |
| | | <el-input type="textarea" :rows="4" v-model="form.experimentConclusion" placeholder="请输入" /> |
| | | </el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="保藏方法" prop="preserveMethod" required> |
| | | <el-input v-model="form.preserveMethod" placeholder="请输入" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="保藏菌种编号" prop="preserveStrainCode" required> |
| | | <el-input v-model="form.preserveStrainCode" placeholder="请输入" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item required> |
| | | <template #label> |
| | | <span>操作人签字</span> |
| | | <el-button type="primary" class="sign-btn" @click="showSignature = true">签名</el-button> |
| | | </template> |
| | | <div class="signature-area" :class="{ 'waiting': !form.signature }"> |
| | | <template v-if="form.signature"> |
| | | <img :src="form.signature" alt="操作人签字" /> |
| | | </template> |
| | | <template v-else> |
| | | <span class="waiting-text">等待确认</span> |
| | | </template> |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div style="text-align: center; margin-top: 20px"> |
| | | <el-button @click="handleClose" style="margin-right: 16px;">取消</el-button> |
| | | <el-button type="primary" @click="handleSave">保存</el-button> |
| | | </div> |
| | | <signature-canvas :visible.sync="showSignature" @confirm="handleSignatureConfirm" /> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script> |
| | | import SignatureCanvas from '@/components/SignatureCanvas.vue'; |
| | | export default { |
| | | components: { SignatureCanvas }, |
| | | props: { visible: Boolean }, |
| | | data() { |
| | | return { |
| | | form: { |
| | | strainCode: '', |
| | | experimentConclusion: '', |
| | | preserveMethod: '', |
| | | preserveStrainCode: '', |
| | | signature: '', |
| | | }, |
| | | rules: { |
| | | strainCode: [ |
| | | { required: true, message: '请输入用于保藏的菌种编号', trigger: 'blur' }, |
| | | ], |
| | | experimentConclusion: [ |
| | | { required: true, message: '请输入实验验证结论', trigger: 'blur' }, |
| | | ], |
| | | preserveMethod: [ |
| | | { required: true, message: '请输入保藏方法', trigger: 'blur' }, |
| | | ], |
| | | preserveStrainCode: [ |
| | | { required: true, message: '请输入保藏菌种编号', trigger: 'blur' }, |
| | | ], |
| | | signature: [ |
| | | { required: true, message: '请签名', trigger: 'change' }, |
| | | ], |
| | | }, |
| | | showSignature: false, |
| | | }; |
| | | }, |
| | | methods: { |
| | | handleSave() { |
| | | this.$refs.form.validate((valid) => { |
| | | if (valid) { |
| | | this.$emit('save', { ...this.form }); |
| | | this.handleClose(); |
| | | } |
| | | }); |
| | | }, |
| | | handleClose() { |
| | | this.$emit('update:visible', false); |
| | | }, |
| | | handleSignatureConfirm(dataUrl) { |
| | | this.form.signature = dataUrl; |
| | | this.showSignature = false; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .signature-area { |
| | | height: 120px; |
| | | width: 100%; |
| | | background: #F5F7FA; |
| | | border-radius: 4px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border: 1px solid #DCDFE6; |
| | | overflow: hidden; |
| | | padding: 0; |
| | | } |
| | | .signature-area.waiting { |
| | | border-style: dashed; |
| | | background: #FAFAFA; |
| | | } |
| | | .signature-area img { |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: cover; |
| | | display: block; |
| | | } |
| | | .waiting-text { |
| | | color: #909399; |
| | | font-size: 14px; |
| | | } |
| | | .sign-btn { |
| | | height: 32px; |
| | | border-radius: 4px; |
| | | font-size: 14px; |
| | | padding: 0 20px; |
| | | font-weight: 400; |
| | | margin-left: 12px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-dialog |
| | | title="添加出入库记录" |
| | | :visible.sync="visible" |
| | | width="520px" |
| | | :close-on-click-modal="false" |
| | | custom-class="record-detail-dialog" |
| | | @close="handleClose" |
| | | > |
| | | <div class="dialog-content"> |
| | | <el-form :model="formData" label-position="top"> |
| | | <el-form-item label="分离菌落编号" required> |
| | | <el-input v-model="formData.colonyCode" placeholder="请输入" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item required> |
| | | <template #label> |
| | | <span>操作人签字</span> |
| | | <el-button type="primary" class="sign-btn" @click="showSignature = true">签名</el-button> |
| | | </template> |
| | | <div class="signature-area" :class="{ 'waiting': !formData.operatorSignature }"> |
| | | <template v-if="formData.operatorSignature"> |
| | | <img :src="formData.operatorSignature" alt="操作人签字" /> |
| | | </template> |
| | | <template v-else> |
| | | <span class="waiting-text">等待确认</span> |
| | | </template> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <div class="footer-btns"> |
| | | <el-button @click="handleClose">取消</el-button> |
| | | <el-button type="primary" @click="handleConfirm">确认</el-button> |
| | | </div> |
| | | <signature-canvas :visible.sync="showSignature" @confirm="handleSignatureConfirm" /> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script> |
| | | import SignatureCanvas from '@/components/SignatureCanvas.vue' |
| | | export default { |
| | | name: 'AddRecordDialog', |
| | | components: { SignatureCanvas }, |
| | | props: { |
| | | visible: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | formData: { |
| | | type: '出库', |
| | | operatorSignature: '' |
| | | }, |
| | | showSignature: false |
| | | } |
| | | }, |
| | | methods: { |
| | | handleClose() { |
| | | this.$emit('update:visible', false) |
| | | this.$emit('close') |
| | | }, |
| | | handleConfirm() { |
| | | if (!this.formData.operatorSignature) { |
| | | this.$message.warning('请先签名') |
| | | return |
| | | } |
| | | this.$emit('confirm', this.formData) |
| | | this.handleClose() |
| | | }, |
| | | handleSignatureConfirm(dataUrl) { |
| | | this.formData.operatorSignature = dataUrl |
| | | this.showSignature = false |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .record-detail-dialog { |
| | | :deep(.el-dialog__header) { |
| | | padding: 20px 24px; |
| | | margin: 0; |
| | | border-bottom: 1px solid #DCDFE6; |
| | | .el-dialog__title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | } |
| | | :deep(.el-dialog__body) { |
| | | padding: 24px; |
| | | } |
| | | } |
| | | .dialog-content { |
| | | :deep(.el-form-item__label) { |
| | | padding-bottom: 8px; |
| | | line-height: 20px; |
| | | font-size: 14px; |
| | | color: #606266; |
| | | &::before { |
| | | content: '*'; |
| | | color: #F56C6C; |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | .type-buttons { |
| | | display: flex; |
| | | gap: 12px; |
| | | .el-button { |
| | | width: 80px; |
| | | border-radius: 4px; |
| | | font-size: 14px; |
| | | font-weight: 400; |
| | | box-sizing: border-box; |
| | | } |
| | | } |
| | | .signature-area { |
| | | height: 120px; |
| | | width: 100%; |
| | | background: #F5F7FA; |
| | | border-radius: 4px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border: 1px solid #DCDFE6; |
| | | overflow: hidden; |
| | | padding: 0; |
| | | &.waiting { |
| | | border-style: dashed; |
| | | background: #FAFAFA; |
| | | } |
| | | img { |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: cover; |
| | | display: block; |
| | | } |
| | | .waiting-text { |
| | | color: #909399; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | .sign-btn { |
| | | height: 32px; |
| | | border-radius: 4px; |
| | | font-size: 14px; |
| | | padding: 0 20px; |
| | | font-weight: 400; |
| | | margin-left: 12px; |
| | | } |
| | | } |
| | | .footer-btns { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | padding: 24px; |
| | | padding-top: 0; |
| | | .el-button { |
| | | width: 150px; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <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> |
| | | </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> |
| | | |
| | | <!-- 查看全部弹窗 --> |
| | | <el-dialog |
| | | 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> |
| | | </div> |
| | | </el-dialog> |
| | | </el-card> |
| | | |
| | | <!-- Table --> |
| | | <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="菌种编号:"> |
| | | <el-input v-model="form.strainNo" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="菌种名称:"> |
| | | <el-input v-model="form.strainName" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="状态:"> |
| | | <el-select v-model="form.status" placeholder="请选择"> |
| | | <el-option label="全部" 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-select> |
| | | </el-form-item> |
| | | <el-form-item class="search-btn-box"> |
| | | <el-button type="default" @click="resetForm">重置</el-button> |
| | | <el-button type="primary" @click="searchData">查询</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <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> |
| | | <div class="flex a-center"> |
| | | <el-button @click="handleNewStrain" class="el-icon-plus" type="primary" style="margin-right: 12px;">新增原始细胞</el-button> |
| | | <el-button @click="handleBatchAdd" class="el-icon-plus" type="primary">批量新增</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <template #table> |
| | | <el-table-column prop="strainNo" label="菌种编号" /> |
| | | <el-table-column prop="strainName" label="菌种名称" /> |
| | | <el-table-column prop="source" label="菌种来源" /> |
| | | <el-table-column prop="method" label="鉴定方法" /> |
| | | <el-table-column prop="certificate" label="特征描述" /> |
| | | <el-table-column prop="storage" label="菌种保存方法" /> |
| | | <el-table-column prop="amount" label="保存位置" /> |
| | | <el-table-column prop="inventory" label="库存余量" /> |
| | | <el-table-column prop="notes" label="备注" /> |
| | | <el-table-column 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="200"> |
| | | <template #default="{ row }"> |
| | | <el-button type="text" @click="handleDetail(row)">详情</el-button> |
| | | <el-button type="text" @click="handleEdit(row)">编辑</el-button> |
| | | <el-button type="text" @click="handleRecord(row)">出入库记录</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </template> |
| | | </TableCustom> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | export default { |
| | | name: 'StrainLibraryManage', |
| | | components: { |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogVisible: false, |
| | | currentType: 'list', |
| | | detailVisible: false, |
| | | currentDetail: {}, |
| | | form: { |
| | | strainNo: '', |
| | | strainName: '', |
| | | status: '' |
| | | }, |
| | | queryForm: { |
| | | pageSize: 10, |
| | | pageNum: 1 |
| | | }, |
| | | total: 800, |
| | | tableData: [ |
| | | { |
| | | strainNo: 'YX-2024001', |
| | | strainName: '大肠杆菌', |
| | | source: '实验室分离', |
| | | method: '形态学鉴定、生理生化试验', |
| | | certificate: '革兰氏阴性杆菌,可发酵葡萄糖产酸产气,IMViC试验++--', |
| | | storage: '斜面培养', |
| | | amount: 'A区-01-001', |
| | | inventory: '50', |
| | | notes: '用于质粒转化', |
| | | status: '1' |
| | | }, |
| | | { |
| | | strainNo: 'YX-2024002', |
| | | strainName: '枯草芽孢杆菌', |
| | | source: '菌种保藏中心', |
| | | method: '16S rDNA测序', |
| | | certificate: '革兰氏阳性芽孢杆菌,可水解淀粉,产生溶菌素', |
| | | storage: '冷冻保存', |
| | | amount: 'B区-02-005', |
| | | inventory: '30', |
| | | notes: '工业发酵菌种', |
| | | status: '1' |
| | | }, |
| | | { |
| | | strainNo: 'YX-2024003', |
| | | strainName: '酿酒酵母', |
| | | source: '发酵工厂', |
| | | method: '显微镜观察、生理特性', |
| | | certificate: '椭圆形单细胞真菌,可发酵葡萄糖产生乙醇', |
| | | storage: '甘油管保存', |
| | | amount: 'A区-03-002', |
| | | inventory: '40', |
| | | notes: '发酵工艺优化', |
| | | status: '2' |
| | | }, |
| | | { |
| | | strainNo: 'YX-2024004', |
| | | strainName: '乳酸菌', |
| | | source: '乳制品分离', |
| | | method: '生化鉴定、API条', |
| | | certificate: '革兰氏阳性球菌,产生乳酸,耐酸性强', |
| | | storage: '冷冻干燥', |
| | | amount: 'C区-01-003', |
| | | inventory: '25', |
| | | notes: '益生菌研究', |
| | | status: '3' |
| | | }, |
| | | { |
| | | strainNo: 'YX-2024005', |
| | | strainName: '青霉菌', |
| | | source: '环境样本', |
| | | method: '形态学特征、ITS测序', |
| | | certificate: '丝状真菌,产生蓝绿色分生孢子,可产青霉素', |
| | | storage: '斜面培养', |
| | | amount: 'B区-04-001', |
| | | inventory: '35', |
| | | notes: '次级代谢产物研究', |
| | | status: '1' |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | methods: { |
| | | handleViewMore() { |
| | | this.dialogVisible = true; |
| | | }, |
| | | resetForm() { |
| | | this.form = { |
| | | strainNo: '', |
| | | strainName: '', |
| | | status: '' |
| | | } |
| | | this.searchData() |
| | | }, |
| | | searchData() { |
| | | // 模拟搜索逻辑 |
| | | const { strainNo, strainName, status } = this.form |
| | | let filteredData = [...this.tableData] |
| | | |
| | | if (strainNo) { |
| | | filteredData = filteredData.filter(item => |
| | | item.strainNo.toLowerCase().includes(strainNo.toLowerCase()) |
| | | ) |
| | | } |
| | | if (strainName) { |
| | | filteredData = filteredData.filter(item => |
| | | item.strainName.toLowerCase().includes(strainName.toLowerCase()) |
| | | ) |
| | | } |
| | | if (status) { |
| | | filteredData = filteredData.filter(item => |
| | | item.status === status |
| | | ) |
| | | } |
| | | |
| | | this.total = filteredData.length |
| | | // 实际项目中这里应该调用API |
| | | console.log('搜索条件:', this.form) |
| | | console.log('分页信息:', this.queryForm) |
| | | }, |
| | | handleNewStrain() { |
| | | this.$router.push('/strain-library/strain-library-manage/add') |
| | | // Implement new strain logic |
| | | }, |
| | | handleBatchAdd() { |
| | | // Implement batch add logic |
| | | }, |
| | | handleDetail(row) { |
| | | this.currentDetail = row; |
| | | this.detailVisible = true; |
| | | }, |
| | | handleEdit(row) { |
| | | // Implement edit logic |
| | | }, |
| | | handleRecord(row) { |
| | | this.$router.push({ |
| | | path: '/strain-library/strain-library-manage/record', |
| | | query: { |
| | | id: row.strainNo |
| | | } |
| | | }) |
| | | }, |
| | | handleCurrentChange(page) { |
| | | this.queryForm.pageNum = page |
| | | // Implement page change logic |
| | | }, |
| | | handleSizeChange(size) { |
| | | this.queryForm.pageSize = size |
| | | // Implement size change logic |
| | | }, |
| | | handleTypeChange(type) { |
| | | this.currentType = type; |
| | | // Implement type change logic |
| | | }, |
| | | getStatusType(status) { |
| | | const types = { |
| | | 1: 'success', |
| | | 2: 'info', |
| | | 3: 'warning' |
| | | } |
| | | return types[status] || 'info' |
| | | }, |
| | | getStatusText(status) { |
| | | const texts = { |
| | | 1: '已入库', |
| | | 2: '已出库', |
| | | 3: '入库待确认' |
| | | } |
| | | return texts[status] || '未知状态' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .list { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .header-box { |
| | | margin-bottom: 20px; |
| | | border-radius: 16px; |
| | | background: rgba(255, 255, 255, 0.8); |
| | | |
| | | .box-title { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | margin-bottom: 15px; |
| | | position: relative; |
| | | |
| | | .header-icon { |
| | | width: 20px; |
| | | height: 20px; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .view-more { |
| | | position: absolute; |
| | | right: 0; |
| | | color: #049C9A; |
| | | } |
| | | } |
| | | |
| | | .header-content { |
| | | color: rgba(0, 0, 0, 0.88); |
| | | font-size: 14px; |
| | | line-height: 1.8; |
| | | margin-left: 30px; |
| | | transition: max-height 0.3s ease-in-out; |
| | | overflow: hidden; |
| | | |
| | | &.collapsed { |
| | | max-height: 48px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | p { |
| | | margin: 5px 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .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 { |
| | | 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; |
| | | width: unset; |
| | | cursor: pointer; |
| | | height: 50px; |
| | | line-height: 50px; |
| | | width: 166px; |
| | | 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: 166px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .active { |
| | | color: #049c9a; |
| | | background: #ffffff; |
| | | border-radius: 8px 8px 0px 0px; |
| | | border: 1px solid #049c9a; |
| | | |
| | | } |
| | | } |
| | | |
| | | .view-all-dialog { |
| | | :deep(.el-dialog__header) { |
| | | padding: 20px; |
| | | border-bottom: 1px solid #EBEEF5; |
| | | margin-right: 0; |
| | | |
| | | .el-dialog__title { |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | color: #303133; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-dialog__body) { |
| | | padding: 20px; |
| | | |
| | | .dialog-content { |
| | | font-size: 14px; |
| | | line-height: 1.8; |
| | | color: #606266; |
| | | |
| | | p { |
| | | margin: 12px 0; |
| | | |
| | | &:first-child { |
| | | margin-top: 0; |
| | | } |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <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> |
| | | </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> |
| | | |
| | | <!-- 查看全部弹窗 --> |
| | | <el-dialog |
| | | 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> |
| | | </div> |
| | | </el-dialog> |
| | | </el-card> |
| | | |
| | | <!-- Table --> |
| | | <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="菌种编号:"> |
| | | <el-input v-model="form.strainNo" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="菌种名称:"> |
| | | <el-input v-model="form.strainName" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="状态:"> |
| | | <el-select v-model="form.status" placeholder="请选择"> |
| | | <el-option label="全部" 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-select> |
| | | </el-form-item> |
| | | <el-form-item class="search-btn-box"> |
| | | <el-button type="default" @click="resetForm">重置</el-button> |
| | | <el-button type="primary" @click="searchData">查询</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <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> |
| | | <div class="flex a-center"> |
| | | <el-button @click="handleNewStrain" class="el-icon-plus" type="primary" style="margin-right: 12px;">新增原始细胞</el-button> |
| | | <el-button @click="handleBatchAdd" class="el-icon-plus" type="primary">批量新增</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <template #table> |
| | | <el-table-column prop="strainNo" label="菌种编号" /> |
| | | <el-table-column prop="strainName" label="菌种名称" /> |
| | | <el-table-column prop="source" label="菌种来源" /> |
| | | <el-table-column prop="method" label="鉴定方法" /> |
| | | <el-table-column prop="certificate" label="特征描述" /> |
| | | <el-table-column prop="storage" label="菌种保存方法" /> |
| | | <el-table-column prop="amount" label="保存位置" /> |
| | | <el-table-column prop="inventory" label="库存余量" /> |
| | | <el-table-column prop="notes" label="备注" /> |
| | | <el-table-column 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="200"> |
| | | <template #default="{ row }"> |
| | | <el-button type="text" @click="handleDetail(row)">详情</el-button> |
| | | <el-button type="text" @click="handleEdit(row)">编辑</el-button> |
| | | <el-button type="text" @click="handleRecord(row)">出入库记录</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </template> |
| | | </TableCustom> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | export default { |
| | | name: 'StrainLibraryManage', |
| | | components: { |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogVisible: false, |
| | | currentType: 'list', |
| | | detailVisible: false, |
| | | currentDetail: {}, |
| | | form: { |
| | | strainNo: '', |
| | | strainName: '', |
| | | status: '' |
| | | }, |
| | | queryForm: { |
| | | pageSize: 10, |
| | | pageNum: 1 |
| | | }, |
| | | total: 800, |
| | | tableData: [ |
| | | { |
| | | strainNo: 'YX-2024001', |
| | | strainName: '大肠杆菌', |
| | | source: '实验室分离', |
| | | method: '形态学鉴定、生理生化试验', |
| | | certificate: '革兰氏阴性杆菌,可发酵葡萄糖产酸产气,IMViC试验++--', |
| | | storage: '斜面培养', |
| | | amount: 'A区-01-001', |
| | | inventory: '50', |
| | | notes: '用于质粒转化', |
| | | status: '1' |
| | | }, |
| | | { |
| | | strainNo: 'YX-2024002', |
| | | strainName: '枯草芽孢杆菌', |
| | | source: '菌种保藏中心', |
| | | method: '16S rDNA测序', |
| | | certificate: '革兰氏阳性芽孢杆菌,可水解淀粉,产生溶菌素', |
| | | storage: '冷冻保存', |
| | | amount: 'B区-02-005', |
| | | inventory: '30', |
| | | notes: '工业发酵菌种', |
| | | status: '1' |
| | | }, |
| | | { |
| | | strainNo: 'YX-2024003', |
| | | strainName: '酿酒酵母', |
| | | source: '发酵工厂', |
| | | method: '显微镜观察、生理特性', |
| | | certificate: '椭圆形单细胞真菌,可发酵葡萄糖产生乙醇', |
| | | storage: '甘油管保存', |
| | | amount: 'A区-03-002', |
| | | inventory: '40', |
| | | notes: '发酵工艺优化', |
| | | status: '2' |
| | | }, |
| | | { |
| | | strainNo: 'YX-2024004', |
| | | strainName: '乳酸菌', |
| | | source: '乳制品分离', |
| | | method: '生化鉴定、API条', |
| | | certificate: '革兰氏阳性球菌,产生乳酸,耐酸性强', |
| | | storage: '冷冻干燥', |
| | | amount: 'C区-01-003', |
| | | inventory: '25', |
| | | notes: '益生菌研究', |
| | | status: '3' |
| | | }, |
| | | { |
| | | strainNo: 'YX-2024005', |
| | | strainName: '青霉菌', |
| | | source: '环境样本', |
| | | method: '形态学特征、ITS测序', |
| | | certificate: '丝状真菌,产生蓝绿色分生孢子,可产青霉素', |
| | | storage: '斜面培养', |
| | | amount: 'B区-04-001', |
| | | inventory: '35', |
| | | notes: '次级代谢产物研究', |
| | | status: '1' |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | methods: { |
| | | handleViewMore() { |
| | | this.dialogVisible = true; |
| | | }, |
| | | resetForm() { |
| | | this.form = { |
| | | strainNo: '', |
| | | strainName: '', |
| | | status: '' |
| | | } |
| | | this.searchData() |
| | | }, |
| | | searchData() { |
| | | // 模拟搜索逻辑 |
| | | const { strainNo, strainName, status } = this.form |
| | | let filteredData = [...this.tableData] |
| | | |
| | | if (strainNo) { |
| | | filteredData = filteredData.filter(item => |
| | | item.strainNo.toLowerCase().includes(strainNo.toLowerCase()) |
| | | ) |
| | | } |
| | | if (strainName) { |
| | | filteredData = filteredData.filter(item => |
| | | item.strainName.toLowerCase().includes(strainName.toLowerCase()) |
| | | ) |
| | | } |
| | | if (status) { |
| | | filteredData = filteredData.filter(item => |
| | | item.status === status |
| | | ) |
| | | } |
| | | |
| | | this.total = filteredData.length |
| | | // 实际项目中这里应该调用API |
| | | console.log('搜索条件:', this.form) |
| | | console.log('分页信息:', this.queryForm) |
| | | }, |
| | | handleNewStrain() { |
| | | this.$router.push('/strain-library/strain-library-manage/add') |
| | | // Implement new strain logic |
| | | }, |
| | | handleBatchAdd() { |
| | | // Implement batch add logic |
| | | }, |
| | | handleDetail(row) { |
| | | this.currentDetail = row; |
| | | this.detailVisible = true; |
| | | }, |
| | | handleEdit(row) { |
| | | // Implement edit logic |
| | | }, |
| | | handleRecord(row) { |
| | | this.$router.push({ |
| | | path: '/strain-library/strain-library-manage/record', |
| | | query: { |
| | | id: row.strainNo |
| | | } |
| | | }) |
| | | }, |
| | | handleCurrentChange(page) { |
| | | this.queryForm.pageNum = page |
| | | // Implement page change logic |
| | | }, |
| | | handleSizeChange(size) { |
| | | this.queryForm.pageSize = size |
| | | // Implement size change logic |
| | | }, |
| | | handleTypeChange(type) { |
| | | this.currentType = type; |
| | | // Implement type change logic |
| | | }, |
| | | getStatusType(status) { |
| | | const types = { |
| | | 1: 'success', |
| | | 2: 'info', |
| | | 3: 'warning' |
| | | } |
| | | return types[status] || 'info' |
| | | }, |
| | | getStatusText(status) { |
| | | const texts = { |
| | | 1: '已入库', |
| | | 2: '已出库', |
| | | 3: '入库待确认' |
| | | } |
| | | return texts[status] || '未知状态' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .list { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .header-box { |
| | | margin-bottom: 20px; |
| | | border-radius: 16px; |
| | | background: rgba(255, 255, 255, 0.8); |
| | | |
| | | .box-title { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | margin-bottom: 15px; |
| | | position: relative; |
| | | |
| | | .header-icon { |
| | | width: 20px; |
| | | height: 20px; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .view-more { |
| | | position: absolute; |
| | | right: 0; |
| | | color: #049C9A; |
| | | } |
| | | } |
| | | |
| | | .header-content { |
| | | color: rgba(0, 0, 0, 0.88); |
| | | font-size: 14px; |
| | | line-height: 1.8; |
| | | margin-left: 30px; |
| | | transition: max-height 0.3s ease-in-out; |
| | | overflow: hidden; |
| | | |
| | | &.collapsed { |
| | | max-height: 48px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | p { |
| | | margin: 5px 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .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 { |
| | | 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; |
| | | width: unset; |
| | | cursor: pointer; |
| | | height: 50px; |
| | | line-height: 50px; |
| | | width: 166px; |
| | | 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: 166px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .active { |
| | | color: #049c9a; |
| | | background: #ffffff; |
| | | border-radius: 8px 8px 0px 0px; |
| | | border: 1px solid #049c9a; |
| | | |
| | | } |
| | | } |
| | | |
| | | .view-all-dialog { |
| | | :deep(.el-dialog__header) { |
| | | padding: 20px; |
| | | border-bottom: 1px solid #EBEEF5; |
| | | margin-right: 0; |
| | | |
| | | .el-dialog__title { |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | color: #303133; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-dialog__body) { |
| | | padding: 20px; |
| | | |
| | | .dialog-content { |
| | | font-size: 14px; |
| | | line-height: 1.8; |
| | | color: #606266; |
| | | |
| | | p { |
| | | margin: 12px 0; |
| | | |
| | | &:first-child { |
| | | margin-top: 0; |
| | | } |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | </style> |