From 0db8c9b94a9ac655549d5eba5c2a6c92ac386c06 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期四, 08 十月 2026 11:20:56 +0800
Subject: [PATCH] 提交最新代码
---
culture/src/views/strain-library/breeding-record/SlantRecordDialog.vue | 223 +++++++++++++++++++++++++++++++++++++------------------
1 files changed, 150 insertions(+), 73 deletions(-)
diff --git a/culture/src/views/strain-library/breeding-record/SlantRecordDialog.vue b/culture/src/views/strain-library/breeding-record/SlantRecordDialog.vue
index f16bb5e..a2194f6 100644
--- a/culture/src/views/strain-library/breeding-record/SlantRecordDialog.vue
+++ b/culture/src/views/strain-library/breeding-record/SlantRecordDialog.vue
@@ -1,15 +1,15 @@
<template>
- <el-dialog :visible.sync="visible" :title="editData ? '编辑培养皿观察记录' : '新增培养皿观察记录'" width="80%" @close="handleClose">
+ <el-dialog :visible.sync="visible" :title="readOnly ? '培养皿观察记录详情' : editData ? '编辑培养皿观察记录' : '新增培养皿观察记录'" width="80%" @close="handleClose">
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px" label-position="top">
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="分离菌落编号" prop="separateColonyCode">
- <el-input :disabled="roleType!=4" v-model="form.separateColonyCode" placeholder="请输入分离菌落编号" />
+ <el-input :disabled="!editable" v-model="form.separateColonyCode" placeholder="请输入分离菌落编号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="形状强壮度排名" prop="strength">
- <el-input :disabled="roleType!=4" v-model="form.strength" placeholder="请输入形状强壮度排名" />
+ <el-input :disabled="!editable" v-model="form.strength" placeholder="请输入形状强壮度排名" />
</el-form-item>
</el-col>
</el-row>
@@ -22,24 +22,49 @@
</el-table-column>
<el-table-column prop="desc" label="形态记录">
<template #default="{ row }">
- <el-input class="el-input-full" style="width: 100%;" :disabled="roleType!=4" v-model="row.desc" placeholder="请输入形态记录"
+ <el-input class="el-input-full" style="width: 100%;" :disabled="!editable" v-model="row.desc" placeholder="请输入形态记录"
@blur="handleDescBlur(row)" />
</template>
</el-table-column>
- <el-table-column prop="images" label="拍照上传" width="180">
+ <el-table-column prop="images" label="拍照上传" width="160">
<template #default="{ row }">
- <el-upload :file-list="row.images" :disabled="roleType!=4 || row.uploading" list-type="picture-card"
- :on-preview="file => handlePreview(row, file)"
- :on-remove="(file, fileList) => handleRemove(row, file, fileList)"
- :on-success="(res, file, fileList) => handleUpload(row, file, fileList)"
- :before-upload="file => beforeUpload(file, row)"
- action="#" class="mini-upload">
- <template v-if="row.uploading">
- <i class="el-icon-loading"></i>
- </template>
- <template v-else>
- <i class="el-icon-plus"></i>
- </template>
+ <el-upload
+ class="custom-upload-row"
+ :ref="'uploadRef' + row.index"
+ action="#"
+ :file-list="[]"
+ :http-request="options => rowHandleUpload(options, row)"
+ :before-upload="file => rowBeforeUpload(file, row)"
+ :show-file-list="false"
+ :disabled="!editable || row.uploading"
+ accept="image/*"
+ :auto-upload="true"
+ >
+ <div class="upload-flex-box">
+ <div
+ v-for="(img, idx) in row.images"
+ :key="img.uid || img.url"
+ class="upload-thumb"
+ @click.stop="handlePreview(row, img)"
+ >
+ <el-image
+ :src="getFullUrl(img.url)"
+ :preview-src-list="row.images.map(i => getFullUrl(i.url))"
+ :initial-index="idx"
+ fit="cover"
+ style="width: 100%; height: 100%;"
+ @click.stop.native="handlePreview(row, img)"
+ />
+ <i class="el-icon-delete" v-if="editable" @click.stop="rowHandleRemove(row, img, row.images.filter(f => f !== img))"></i>
+ </div>
+ <div
+ v-if="editable"
+ class="upload-thumb upload-btn"
+ @click.stop="triggerUpload(row.index)"
+ >
+ <i class="el-icon-plus"></i>
+ </div>
+ </div>
</el-upload>
</template>
</el-table-column>
@@ -49,7 +74,7 @@
</template>
</el-table-column>
</el-table>
- <div style="text-align: center;" v-if="roleType==4">
+ <div style="text-align: center;" v-if="editable">
<el-button type="primary" @click="handleOk" :disabled="hasUploading">保存</el-button>
</div>
</el-dialog>
@@ -57,10 +82,15 @@
<script>
import moment from 'moment'
+import { customUploadRequest, getFullUrl, getUploadedFilePath, normalizeFileList } from '@/utils/utils'
export default {
name: 'SlantRecordDialog',
props: {
visible: Boolean,
+ readOnly: {
+ type: Boolean,
+ default: false
+ },
editData: {
type: Object,
default: null
@@ -106,7 +136,8 @@
index: index + 1,
desc: record.desc || '',
time: record.time || this.getNowTime(),
- images: record.images || []
+ images: this.normalizeImages(record.images),
+ uploading: false
}))
while (this.tableData.length < 10) {
this.tableData.push({
@@ -142,7 +173,18 @@
}
},
visible(val) {
- if (!val) {
+ if (val) {
+ if (!this.editData) {
+ this.reset()
+ this.tableData = Array.from({ length: 10 }, (_, i) => ({
+ index: i + 1,
+ desc: '',
+ time: '',
+ images: [],
+ uploading: false
+ }))
+ }
+ } else {
this.reset()
}
}
@@ -166,6 +208,7 @@
}
},
handleOk() {
+ if (!this.editable) return
this.$refs.formRef.validate(valid => {
if (!valid) return
@@ -197,37 +240,79 @@
handleClose() {
this.$emit('update:visible', false)
},
- beforeUpload(file, row) {
- row.uploading = true
- return new Promise(resolve => {
- const reader = new FileReader()
- reader.onload = e => {
- resolve()
+ rowBeforeUpload(file, row) {
+ if (!file.type || !file.type.startsWith('image/')) {
+ this.$message.error('只能上传图片文件')
+ return false
+ }
+ if (file.size > 10 * 1024 * 1024) {
+ this.$message.error('图片大小不能超过 10MB')
+ return false
+ }
+ return true
+ },
+ rowHandleUpload(options, row) {
+ row.uploading = true;
+ const { file, onSuccess, onError } = options;
+ customUploadRequest({
+ file,
+ onSuccess: (res) => {
+ const uploadedPath = getUploadedFilePath(res)
+ if (uploadedPath) {
+ const fileObj = {
+ name: file.name,
+ url: uploadedPath,
+ uid: new Date().getTime()
+ };
+ if (!Array.isArray(row.images)) this.$set(row, 'images', []);
+ row.images.push(fileObj);
+ this.$set(row, 'images', [...row.images]);
+ this.$message.success('文件上传成功');
+ onSuccess(res);
+ } else {
+ this.$message.error(res && res.msg ? res.msg : '上传接口未返回文件地址');
+ onError(new Error('missing uploaded file path'));
+ }
+ row.uploading = false;
+ },
+ onError: (err) => {
+ this.$message.error('文件上传失败');
+ row.uploading = false;
+ onError(err);
}
- reader.readAsDataURL(file)
- })
+ });
},
- handleUpload(row, file, fileList) {
- row.images = fileList.map(f => ({ ...f, url: f.url || URL.createObjectURL(f.raw) }))
- row.uploading = false
- },
- handleRemove(row, file, fileList) {
- row.images = fileList
- row.uploading = false
+ rowHandleRemove(row, file, fileList) {
+ row.images = fileList;
+ row.uploading = false;
},
handlePreview(row, file) {
this.previewImg = file.url
this.previewVisible = true
},
handleDescBlur(row) {
- console.log(row)
- if (row.desc) {
+ if (this.editable && row.desc) {
row.time = this.getNowTime()
this.$forceUpdate()
}
+ },
+ triggerUpload(index) {
+ if (!this.editable) return
+ const uploadRef = this.$refs['uploadRef' + index];
+ if (uploadRef && uploadRef.$el) {
+ const input = uploadRef.$el.querySelector('input[type=file]');
+ if (input) input.click();
+ }
+ },
+ getFullUrl,
+ normalizeImages(images) {
+ return normalizeFileList(images)
}
},
computed: {
+ editable() {
+ return [1, 4].includes(Number(this.roleType)) && !this.readOnly
+ },
hasUploading() {
return this.tableData.some(row => row.uploading)
}
@@ -240,52 +325,44 @@
width: 100% !important;
}
-::v-deep(.mini-upload){
+::v-deep(.custom-upload-row .upload-flex-box) {
display: flex;
flex-wrap: wrap;
+ gap: 8px;
+ max-width: 140px;
}
-
-::v-deep(.el-upload--picture-card) {
- width: 40px !important;
- height: 40px !important;
- line-height: 40px !important;
-}
-
-::v-deep(.mini-upload .el-upload-list--picture-card .el-upload-list__item) {
- width: 40px !important;
- height: 40px !important;
-}
-
-::v-deep(.mini-upload .el-upload-list--picture-card .el-upload-list__item-thumbnail) {
- width: 40px !important;
- height: 40px !important;
- object-fit: cover;
-}
-
-::v-deep(.mini-upload .el-upload-list--picture-card .el-upload-list__item-preview),
-::v-deep(.mini-upload .el-upload-list--picture-card .el-upload-list__item-delete) {
- width: 18px;
- height: 18px;
- font-size: 14px;
-}
-
-::v-deep(.el-upload--picture-card) {
- width: 40px !important;
- height: 40px !important;
- line-height: 40px !important;
+.upload-thumb {
+ width: 40px;
+ height: 40px;
+ position: relative;
+ border: 1px solid #eee;
+ border-radius: 4px;
+ overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
-
-::v-deep(.mini-upload .el-upload--picture-card i.el-icon-plus) {
- font-size: 18px;
- /* 缩小icon */
+.upload-thumb img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+.upload-thumb .el-icon-delete {
+ position: absolute;
+ top: 0px;
+ right: 0px;
+ font-size: 14px;
+ color: #f56c6c;
+ background: #fff;
+ border-radius: 50%;
+ cursor: pointer;
+}
+.upload-btn {
+ cursor: pointer;
+ background: #fafafa;
color: #999;
display: flex;
align-items: center;
justify-content: center;
- width: 100%;
- height: 100%;
}
</style>
--
Gitblit v1.7.1