smart-bid-web/src/views/analysis/components/AnalysisForm.vue

415 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 小型弹窗用于完成删除保存等操作 -->
<el-dialog class="l-dialog" :class="[lDialog, { 'no-pointer-events': showUploadAnimation }]" :title="title" :visible.sync="dialogVisible" :showClose="true"
:closeOnClickModal="false" @close="handleClose" :append-to-body="true">
<div>
<!-- 全局上传动画 -->
<GlobalUploadAnimation v-if="showUploadAnimation" :text="animationText" subtext="正在处理文件,请稍候..." />
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="110px">
<el-form-item label="选择模板" prop="templateId">
<el-select v-model="form.templateId" placeholder="请选择模板" class="form-item"
@change="handleTemplateChange">
<el-option v-for="item in modelList" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item v-for="(item, index) in uploadType" :key="index" :label="item"
:prop="`fileList${index + 1}`">
<UploadFile :fileList="form[`fileList${index + 1}`]" @file-change="handleFileChange"
@del-file="handleDelFile" :type="`fileList${index + 1}`" :uploadType="defaultParams.uploadType"
:maxFileTips="defaultParams.maxFileTips" :fileUploadRule="defaultParams.fileUploadRule"
:limitUploadNum="defaultParams.limitUploadNum" />
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" class="confirm-btn" @click="submitForm('ruleForm')">确认</el-button>
<el-button class="cancel-btn" @click="handleClose">取消</el-button>
</span>
</el-dialog>
</template>
<script>
import _ from 'lodash'
import UploadFile from '@/views/common/UploadFile.vue'
import GlobalUploadAnimation from '@/views/common/GlobalUploadAnimation.vue'
import { getAnalysisTemplateSelectApi } from '@/api/common/select'
import { addDataAPI } from '@/api/analysis/analysis'
// 默认参数
const defaultParams = {
fileUploadRule: {
fileUploadType: 'bidding',
fields_json: '',
suffix: 'analysis_database',
},
uploadType: 'pdf、doc、docx',
maxFileTips: '500MB',
limitUploadNum: 1,
}
export default {
name: 'AnalysisForm',
components: {
UploadFile,
GlobalUploadAnimation
},
props: ['width', 'rowData', 'title'],
data() {
return {
lDialog: this.width > 500 ? 'w700' : 'w500',
dialogVisible: true,
defaultParams,
uploadType: [],
modelList: [],
showUploadAnimation: false,
animationText: '识别中',
uploadQueue: 0, // 上传队列计数器
form: {
templateId: null,
delFileList: [],
},
rules: {
templateId: [
{
required: true,
message: '请选择模板',
trigger: 'change',
},
],
},
}
},
watch: {
uploadType: {
handler(newVal, oldVal) {
if (newVal && newVal.length > 0) {
// 立即清除验证
this.$refs.ruleForm && this.$refs.ruleForm.clearValidate()
if (oldVal && oldVal.length > 0) {
oldVal.forEach((item, index) => {
this.$delete(this.form, `fileList${index + 1}`)
this.$delete(this.rules, `fileList${index + 1}`)
})
}
newVal.forEach((item, index) => {
this.$set(this.form, `fileList${index + 1}`, [])
this.$set(this.rules, `fileList${index + 1}`, [
{
required: true,
message: `请上传${item}`,
trigger: ['change'],
},
])
})
this.$nextTick(() => {
this.$refs.ruleForm &&
this.$refs.ruleForm.clearValidate()
})
}
},
immediate: true,
},
},
created() {
this.getAnalysisTemplateSelect()
},
methods: {
// 获取招标解析模板下拉选
async getAnalysisTemplateSelect() {
const res = await getAnalysisTemplateSelectApi()
if (res.code === 200) {
this.modelList = res.data
}
},
/* 模板变化选择对应的需要上传的文件 */
handleTemplateChange(val) {
const uploadType = this.modelList.find(
(item) => item.id === val,
).uploadType
this.uploadType = uploadType.split(',')
},
// 文件变化
handleFileChange(file, fileName) {
console.log(file)
this.form[fileName] = file
this.$refs.ruleForm && this.$refs.ruleForm.clearValidate([fileName])
},
// 文件删除时触发
handleDelFile(file) {
console.log(file)
const delPath =
file?.response?.fileRes?.filePath || file?.filePath || null
if (delPath) {
this.form.delFileList.push(delPath)
}
},
/*关闭弹窗 */
handleClose() {
this.dialogVisible = false
this.$emit('closeDialog')
},
/**确认弹窗 */
sureBtnClick() {
this.dialogVisible = false
this.$emit('closeDialog')
},
/**重置表单*/
reset() {
this.form = {
id: null,
pid: null,
templateId: null,
fileList: [],
delFileList: [],
remark: '',
}
this.resetForm('ruleForm')
},
handleReuslt(res) {
this.$modal.msgSuccess(res.msg)
this.reset()
this.$emit('handleQuery')
this.handleClose()
},
validate(formName) {
return new Promise((resolve, reject) => {
this.$refs[formName].validate((valid) => {
if (valid) {
resolve(this.form) // 校验成功返回表单数据
} else {
reject(new Error('数据未填写完整'))
}
})
})
},
/**验证 */
async submitForm(formName) {
try {
const data = await this.validate(formName)
// 所有校验通过,组装完整数据
let formData = {
...data,
allFiles: [
...data.fileList.map((file) =>
JSON.parse(JSON.stringify(file)),
),
],
delFiles: [...data.delFileList],
}
let allFiles = formData.allFiles
.map((file) => {
return file?.response?.fileRes
? {
...file.response.fileRes,
}
: null
})
.filter((item) => item !== null)
formData.files = allFiles
delete formData.fileList
delete formData.delFileList
delete formData.allFiles
// 显示遮罩层
this.loading = this.$loading({
lock: true,
text: '数据提交中,请稍候...',
background: 'rgba(0,0,0,0.5)',
target:
this.$el.querySelector('.el-dialog') || document.body,
})
console.log('所有表单校验通过,完整数据:', formData)
/* const res = await this.saveData(formData)
if (res.code === 200) {
this.handleReuslt(res)
} else {
this.$modal.msgError(res.msg)
} */
} catch (error) {
} finally {
if (this.loading) {
this.loading.close()
}
}
},
// 保存接口
async saveData(formData) {
return new Promise((resolve, reject) => {
if (this.isAdd === 'add') {
// 新增
addDataAPI(formData)
.then((res) => {
resolve(res)
})
.catch((error) => {
reject(error)
})
}
})
},
// 开始上传
handleStartUpload(data) {
this.animationText = data
this.uploadQueue++
this.showUploadAnimation = true
},
// 结束上传
handleEndUpload(data) {
if (this.uploadQueue > 0) {
this.uploadQueue--
}
// 如果队列为空,隐藏动画
if (this.uploadQueue === 0) {
this.showUploadAnimation = false
}
},
},
mounted() {
// 监听上传开始事件
this.$bus.$on('startUpload', this.handleStartUpload)
// 监听上传结束事件
this.$bus.$on('endUpload', this.handleEndUpload)
},
beforeDestroy() {
// 移除所有事件监听
this.$bus.$off('startUpload', this.handleStartUpload)
this.$bus.$off('endUpload', this.handleEndUpload)
// 重置状态
this.showUploadAnimation = false
this.uploadQueue = 0
this.animationText = '识别中'
},
}
</script>
<style lang="scss" scoped>
.w700 ::v-deep .el-dialog {
width: 700px;
font-family: Source Han Sans CN, Source Han Sans CN;
display: flex;
flex-direction: column;
max-height: 90vh;
margin: 5vh auto !important;
}
.w500 ::v-deep .el-dialog {
width: 500px;
font-family: Source Han Sans CN, Source Han Sans CN;
display: flex;
flex-direction: column;
max-height: 90vh;
margin: 5vh auto !important;
}
.w500 ::v-deep .el-dialog__header,
.w700 ::v-deep .el-dialog__header {
flex-shrink: 0;
.el-dialog__title {
font-size: 16px;
}
}
.w500 ::v-deep .el-dialog__body,
.w700 ::v-deep .el-dialog__body {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding: 20px;
min-height: 0;
// 自定义滚动条样式
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: transparent;
}
&::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.2);
border-radius: 3px;
&:hover {
background: rgba(0, 0, 0, 0.3);
}
}
}
.w500 ::v-deep .el-dialog__footer,
.w700 ::v-deep .el-dialog__footer {
flex-shrink: 0;
text-align: center;
}
// 当显示动画时,禁用弹窗点击
.w500 ::v-deep .el-dialog.no-pointer-events,
.w700 ::v-deep .el-dialog.no-pointer-events {
pointer-events: none;
// 子元素也继承禁用点击
* {
pointer-events: none;
}
}
.yxq .el-range-separator {
margin-right: 7px !important;
}
.el-date-editor--daterange.el-input__inner {
width: 260px;
}
.form-item {
width: 100%;
}
.select-style {
display: flex;
justify-content: space-between;
}
.confirm-btn {
width: 98px;
height: 36px;
background: #1f72ea;
box-shadow: 0px 4px 8px 0px rgba(51, 135, 255, 0.5);
border-radius: 4px 4px 4px 4px;
color: #fff;
border: none;
font-size: 14px;
transition: all 0.3s;
&:hover {
background: #4a8bff;
box-shadow: 0px 6px 12px 0px rgba(51, 135, 255, 0.6);
}
}
.cancel-btn {
width: 98px;
height: 36px;
background: #e5e5e5;
box-shadow: 0px 4px 8px 0px rgba(76, 76, 76, 0.2);
border-radius: 4px 4px 4px 4px;
color: #333;
border: none;
font-size: 14px;
transition: all 0.3s;
&:hover {
background: #d0d0d0;
box-shadow: 0px 6px 12px 0px rgba(76, 76, 76, 0.3);
}
}
</style>