基因型数据完成

master
贾肃 4 months ago
parent 5eda5444b7
commit 91c8148a9d
  1. BIN
      src/assets/images/empty-image.png
  2. 8
      src/components/LeftDrawer/index.vue
  3. 7
      src/components/fileUploader/index.vue
  4. 21
      src/utils/ruoyi.js
  5. 24
      src/views/genoTypeData/genoManage/index.vue
  6. 49
      src/views/genoTypeData/genoManage/uploadGeno.vue

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

@ -14,6 +14,10 @@ let props = defineProps({
zIndex: { zIndex: {
type: Number, type: Number,
default: 165 default: 165
},
allowClose: {
type:Boolean,
default:true
} }
}); });
const drawerWidth= computed(()=>appStore.device === 'mobile'?'100%':props.width) const drawerWidth= computed(()=>appStore.device === 'mobile'?'100%':props.width)
@ -25,12 +29,12 @@ const close = () => {
<template> <template>
<el-drawer :size="drawerWidth" v-model="showDrawer" direction="ltr" append-to-body class="drawer" modal-class="drawer-modal" :z-index="zIndex" <el-drawer :size="drawerWidth" v-model="showDrawer" direction="ltr" append-to-body class="drawer" modal-class="drawer-modal" :z-index="zIndex"
:with-header="false"> :with-header="false" :close-on-click-modal="allowClose">
<div> <div>
<div v-if="!!title" class="drawer-title"> <div v-if="!!title" class="drawer-title">
{{title}} {{title}}
</div> </div>
<div class="close-icon" @click="close"> <div class="close-icon" @click="close" v-if="allowClose">
<el-icon size="20"> <el-icon size="20">
<Close/> <Close/>
</el-icon> </el-icon>

@ -19,7 +19,7 @@ const props = defineProps({
// //
const initChunkSize = 5 * 1024 * 1024 const initChunkSize = 5 * 1024 * 1024
// keyfileUid value queue object // keyfileUid value queue object
const fileUploadChunkQueue = ref({}).value const fileUploadChunkQueue = reactive({})
const mergeParams = ref({}) const mergeParams = ref({})
/** /**
* 获取一个上传任务没有则初始化一个 * 获取一个上传任务没有则初始化一个
@ -221,11 +221,12 @@ const handleRemoveFile = (uploadFile, uploadFiles) => {
queueObject.stop() queueObject.stop()
fileUploadChunkQueue[uploadFile.file.uid] = undefined fileUploadChunkQueue[uploadFile.file.uid] = undefined
} }
modelValue.value = modelValue.value.filter(item => item.file.uid!==uploadFile.file.uid) modelValue.value = modelValue.value.filter(item => {
return item.file ? item.file.uid !== uploadFile.file.uid : true;
})
}else{ }else{
modelValue.value = modelValue.value.filter(item => item.id!==uploadFile.id) modelValue.value = modelValue.value.filter(item => item.id!==uploadFile.id)
} }
} }
const settingsStore = useSettingsStore() const settingsStore = useSettingsStore()
const theme = computed(() => settingsStore.theme); const theme = computed(() => settingsStore.theme);

@ -2,6 +2,7 @@
* 通用js方法封装处理 * 通用js方法封装处理
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
*/ */
import {ElLoading} from "element-plus";
// 日期格式化 // 日期格式化
export function parseTime(time, pattern) { export function parseTime(time, pattern) {
@ -383,6 +384,7 @@ export function drawGridLines(polygon, grid = 10) {
} }
return gridLines return gridLines
} }
/** /**
* 将文件转为blob预览地址 * 将文件转为blob预览地址
* @param file * @param file
@ -403,6 +405,7 @@ export function fileToBlobURL(file) {
} }
}) })
} }
// 千分显示并保留两位小数 // 千分显示并保留两位小数
export function processDot(num, precision) { export function processDot(num, precision) {
return (+(Math.round(+(num + "e" + precision)) + "e" + -precision)).toFixed( return (+(Math.round(+(num + "e" + precision)) + "e" + -precision)).toFixed(
@ -414,6 +417,7 @@ export function formatNumber(num) {
const result = processDot(num, 2); const result = processDot(num, 2);
return result.replace(/\d(?=(\d{3})+\.)/g, "$&,"); return result.replace(/\d(?=(\d{3})+\.)/g, "$&,");
} }
/** /**
* 上传文件将对象转换为FormData * 上传文件将对象转换为FormData
* @param values * @param values
@ -442,3 +446,20 @@ export function getFormData(values, formData) {
} }
return formData return formData
} }
/**
* 调用浏览器下载
*/
export function downloadWithUrl(url, fileName, loading = ElLoading.service({lock: true, text: '正在下载文件····',})) {
//下载文件
const element = document.createElement('a')
element.setAttribute('href', url);
element.setAttribute('download', fileName);
// 触发点击
document.body.appendChild(element);
element.click();
loading.close()
URL.revokeObjectURL(element) // 释放内存
}

@ -89,7 +89,7 @@
/> />
</el-col> </el-col>
</el-row> </el-row>
<left-drawer v-model="showView" title="上传基因型数据" width="40%"> <left-drawer v-model="showView" title="查看基因型数据" width="40%">
<div> <div>
<title-divider title="基本信息"/> <title-divider title="基本信息"/>
<el-form :model="formData" ref="formRef" :rules="rules" label-width="90px"> <el-form :model="formData" ref="formRef" :rules="rules" label-width="90px">
@ -106,29 +106,26 @@
</el-form-item> </el-form-item>
<el-form-item label="物种图片" prop="thumbnailUrl"> <el-form-item label="物种图片" prop="thumbnailUrl">
<div class="avatar-uploader-image"> <div class="avatar-uploader-image">
<el-image :src="formData.thumbnailUrl" style="width: 130px;height: 130px"></el-image> <el-image preview-teleported :src="formData.thumbnailUrl" style="width: 130px;height: 130px" :preview-src-list="[formData.thumbnailUrl]"></el-image>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-tabs v-model="currentTabs"> <el-tabs v-model="currentTabs">
<el-tab-pane label="Genome" :name="1"> <el-tab-pane label="Genome" :name="1"/>
</el-tab-pane> <el-tab-pane label="Annotation" :name="2"/>
<el-tab-pane label="Annotation" :name="2"> <el-tab-pane label="Molecular maker" :name="3"/>
</el-tab-pane> <el-tab-pane label="Gene Expression Level (FPKM) Data" :name="4"/>
<el-tab-pane label="Molecular maker" :name="3">
</el-tab-pane>
<el-tab-pane label="Gene Expression Level (FPKM) Data" :name="4">
</el-tab-pane>
</el-tabs> </el-tabs>
<upload-geno v-model="formData.tFiles" :gene-file-type="currentTabs" is-view></upload-geno>
</div> </div>
<template #footer> <template #footer>
<el-button @click="showView = false">关闭</el-button> <el-button @click="showView = false">关闭</el-button>
</template> </template>
</left-drawer> </left-drawer>
<left-drawer v-model="showGenoForm" title="上传基因型数据" width="40%"> <left-drawer v-model="showGenoForm" title="上传基因型数据" width="40%" :allow-close="!submitLoading">
<div> <div>
<title-divider title="基本信息"/> <title-divider title="基本信息"/>
<el-form :model="formData" ref="formRef" :rules="rules"> <el-form :model="formData" ref="formRef" :rules="rules" v-loading="submitLoading" :element-loading-text="'文件上传中,请耐心等待,整个过程预计需要几分钟'">
<el-form-item label="物种名称" prop="speciesName"> <el-form-item label="物种名称" prop="speciesName">
<el-input placeholder="请输入物种名称" v-model="formData.speciesName"></el-input> <el-input placeholder="请输入物种名称" v-model="formData.speciesName"></el-input>
</el-form-item> </el-form-item>
@ -174,7 +171,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button type="primary" :loading="submitLoading" @click="saveGeno"></el-button> <el-button type="primary" :loading="submitLoading" @click="saveGeno"></el-button>
<el-button @click="showGenoForm = false">取消</el-button> <el-button @click="showGenoForm = false" v-if="!submitLoading"></el-button>
</template> </template>
</left-drawer> </left-drawer>
</div> </div>
@ -194,7 +191,6 @@ import {
selPhylumInfo selPhylumInfo
} from "@/api/basicData/genoManageApi.js"; } from "@/api/basicData/genoManageApi.js";
import {ElMessageBox} from "element-plus"; import {ElMessageBox} from "element-plus";
import EventBus from "@/utils/EventBus.js";
import {isArray} from "@/utils/validate.js"; import {isArray} from "@/utils/validate.js";
const router = useRouter(); const router = useRouter();

@ -1,14 +1,16 @@
<script setup> <script setup>
import {formatNumber, processDot} from "@/utils/ruoyi.js"; import {downloadWithUrl, formatNumber, processDot} from "@/utils/ruoyi.js";
import FileUploader from "@/components/fileUploader/index.vue"; import FileUploader from "@/components/fileUploader/index.vue";
import EventBus from "@/utils/EventBus.js";
import {isArray} from "@/utils/validate.js"; import {isArray} from "@/utils/validate.js";
import { saveAs } from 'file-saver'
import {ElLoading} from "element-plus";
const props = defineProps({ const props = defineProps({
// 1=Gnome 2=Annotation 3=Molecular maker 4=Gene Expression Level(FPKM) // 1=Gnome 2=Annotation 3=Molecular maker 4=Gene Expression Level(FPKM)
geneFileType: Number, geneFileType: Number,
formData:Object formData:Object,
}) })
const loading = ref(false)
const emit = defineEmits(['delFile','uploadSuccess']) const emit = defineEmits(['delFile','uploadSuccess'])
const modelValue = defineModel({type: Array}) const modelValue = defineModel({type: Array})
const formatFileSize = (fileSize)=>{ const formatFileSize = (fileSize)=>{
@ -23,6 +25,7 @@ const delFile = (item,index) => {
const uploadRef = ref(null) const uploadRef = ref(null)
const uploadFile = (data) => { const uploadFile = (data) => {
if (modelValue.value.length>0){ if (modelValue.value.length>0){
loading.value = true
uploadRef.value.startUpload({ uploadRef.value.startUpload({
// id // id
tableId:data.id, tableId:data.id,
@ -38,6 +41,7 @@ const uploadFile = (data) => {
} }
} }
const uploadSuccess = () => { const uploadSuccess = () => {
loading.value = false
emit('uploadSuccess') emit('uploadSuccess')
} }
defineExpose({ defineExpose({
@ -60,11 +64,16 @@ const beforeUpload = (options) => {
}) })
return false return false
} }
const downloadFile = (item) => {
let service = ElLoading.service({ text: "正在下载数据,请稍候", });
saveAs(item.url,item.fileName);
service.close()
}
</script> </script>
<template> <template>
<div> <div>
<file-uploader @upload-success="uploadSuccess" ref="uploadRef" v-model="modelValue" @beforeUpload="beforeUpload"/> <file-uploader v-if="!props.isView" @upload-success="uploadSuccess" ref="uploadRef" v-model="modelValue" @beforeUpload="beforeUpload"/>
<div v-for="(item, index) in showFileList" style="margin-top: 10px"> <div v-for="(item, index) in showFileList" style="margin-top: 10px">
<div class="file-list-item"> <div class="file-list-item">
<div class="file-list-title"> <div class="file-list-title">
@ -72,21 +81,41 @@ const beforeUpload = (options) => {
<svg-icon class-name="annex-icon" icon-class="annex"></svg-icon> {{ item.fileName }} <svg-icon class-name="annex-icon" icon-class="annex"></svg-icon> {{ item.fileName }}
</div> </div>
<div class="file-size"> <div class="file-size">
{{formatFileSize(item.fileSize)}} KB <i-close-one theme="outline" size="24" fill="#d73833" class="file-close-icon" @click="delFile(item,index)"/> {{formatFileSize(item.fileSize)}} KB
<i-close-one v-if="!props.isView && !loading" theme="outline" size="24" fill="#d73833" class="file-close-icon" @click="delFile(item,index)"/>
<i-download-one v-if="props.isView" theme="outline" size="24" fill="#939393" class="file-close-icon" @click="downloadFile(item,index)"/>
</div> </div>
</div> </div>
<div class="file-remark"> <div class="file-remark">
<el-input placeholder="请输入文件说明" v-model="item.fileMemo"></el-input> <el-input :placeholder="props.isView?'--':'请输入文件说明'" v-model="item.fileMemo" :readonly="props.isView"></el-input>
<el-progress <el-progress
v-if="item.startUpload" v-if="item.startUpload && !item.indeterminate"
striped striped
striped-flowx striped-flowx
:indeterminate="item.indeterminate" :indeterminate="item.indeterminate"
:percentage="item.percent" :percentage="item.percent"
/> />
<el-progress
v-if="item.indeterminate"
:format="()=>'计算MD5'"
indeterminate
:percentage="50"
/>
</div> </div>
</div> </div>
</div> </div>
<div v-if="showFileList.length === 0 && isView">
<el-result class="empty-file">
<template #icon>
<img src="@/assets/images/empty-image.png" height="94" width="199"/>
</template>
<template #extra>
<div>
暂无数据
</div>
</template>
</el-result>
</div>
</div> </div>
</template> </template>
@ -109,6 +138,7 @@ const beforeUpload = (options) => {
border-radius: 10px; border-radius: 10px;
} }
.file-list-item{ .file-list-item{
color: rgba(0,0,0,0.65);
margin: 10px 0; margin: 10px 0;
border-bottom: 1px solid #e6e6e6; border-bottom: 1px solid #e6e6e6;
.annex-icon{ .annex-icon{
@ -147,4 +177,9 @@ const beforeUpload = (options) => {
height: 48px; height: 48px;
width: 48px; width: 48px;
} }
.empty-file{
color: rgba(0,0,0,0.65);
font-size: 14px;
margin-top: 30px;
}
</style> </style>
Loading…
Cancel
Save