|
|
@@ -161,7 +161,7 @@
|
|
|
type="text"
|
|
|
size="small"
|
|
|
:disabled="isViewMode"
|
|
|
- @click="$emit('handle-data-download', scope.row)"
|
|
|
+ @click="handleDataDownload(scope.row)"
|
|
|
>
|
|
|
数据下载
|
|
|
</el-button>
|
|
|
@@ -169,7 +169,7 @@
|
|
|
type="text"
|
|
|
size="small"
|
|
|
:disabled="isViewMode"
|
|
|
- @click="$emit('handle-data-upload', scope.row)"
|
|
|
+ @click="handleDataUpload(scope.row)"
|
|
|
>
|
|
|
数据上传
|
|
|
</el-button>
|
|
|
@@ -199,6 +199,13 @@
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
+ <input
|
|
|
+ ref="dynamicUploadInput"
|
|
|
+ type="file"
|
|
|
+ accept=".xls,.xlsx"
|
|
|
+ style="display: none"
|
|
|
+ @change="handleDynamicUploadChange"
|
|
|
+ />
|
|
|
<el-pagination
|
|
|
background
|
|
|
layout="total, sizes, prev, pager, next"
|
|
|
@@ -221,6 +228,8 @@
|
|
|
getSingleRecordSurveyList,
|
|
|
getSurveyDetail,
|
|
|
getDynamicTableData,
|
|
|
+ downloadTemplate,
|
|
|
+ importData,
|
|
|
} from '@/api/audit/survey'
|
|
|
import { getListBySurveyTemplateIdAndVersion } from '@/api/costSurveyTemplateHeaders'
|
|
|
|
|
|
@@ -264,6 +273,11 @@
|
|
|
type: String,
|
|
|
default: '',
|
|
|
},
|
|
|
+ // 任务ID(用于上传)
|
|
|
+ taskId: {
|
|
|
+ type: [String, Number],
|
|
|
+ default: '',
|
|
|
+ },
|
|
|
// 监审期间(从立项信息中获取)
|
|
|
auditPeriod: {
|
|
|
type: [String, Array],
|
|
|
@@ -289,6 +303,8 @@
|
|
|
dynamicDialogKey: 0,
|
|
|
dynamicTableLoading: false,
|
|
|
fixedHeaders: null,
|
|
|
+ // 上传相关
|
|
|
+ pendingDynamicRow: null,
|
|
|
}
|
|
|
},
|
|
|
mounted() {
|
|
|
@@ -386,6 +402,140 @@
|
|
|
// 触发刷新事件
|
|
|
this.handleRefresh()
|
|
|
},
|
|
|
+ // 触发动态表数据上传
|
|
|
+ handleDataUpload(row) {
|
|
|
+ if (this.isViewMode) return
|
|
|
+ this.pendingDynamicRow = row || null
|
|
|
+ this.$nextTick(() => {
|
|
|
+ const input = this.$refs.dynamicUploadInput
|
|
|
+ if (input) {
|
|
|
+ input.value = ''
|
|
|
+ input.click()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 文件选择后上传
|
|
|
+ async handleDynamicUploadChange(e) {
|
|
|
+ const files = e && e.target && e.target.files
|
|
|
+ if (!files || !files.length || !this.pendingDynamicRow) return
|
|
|
+ const file = files[0]
|
|
|
+ const row = this.pendingDynamicRow
|
|
|
+ // 参数收集
|
|
|
+ const surveyTemplateId =
|
|
|
+ (row && (row.surveyTemplateId || row.templateId)) ||
|
|
|
+ this.surveyTemplateId ||
|
|
|
+ ''
|
|
|
+ const taskId = (row && row.taskId) || this.taskId || ''
|
|
|
+ const materialId = row && (row.materialId || row.materialID || row.id)
|
|
|
+ const periodRecordId =
|
|
|
+ row && (row.periodRecordId || row.uploadId || row.id)
|
|
|
+ if (!surveyTemplateId || !taskId) {
|
|
|
+ this.$message &&
|
|
|
+ this.$message.warning &&
|
|
|
+ this.$message.warning('缺少必要参数,无法上传')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', file)
|
|
|
+ formData.append('surveyTemplateId', surveyTemplateId)
|
|
|
+ formData.append('taskId', taskId)
|
|
|
+ if (materialId) formData.append('materialId', materialId)
|
|
|
+ if (periodRecordId) formData.append('periodRecordId', periodRecordId)
|
|
|
+
|
|
|
+ let loading
|
|
|
+ try {
|
|
|
+ loading = this.$loading({
|
|
|
+ lock: true,
|
|
|
+ text: '数据上传中...',
|
|
|
+ spinner: 'el-icon-loading',
|
|
|
+ background: 'rgba(0, 0, 0, 0.7)',
|
|
|
+ })
|
|
|
+ await importData(formData)
|
|
|
+ this.$message &&
|
|
|
+ this.$message.success &&
|
|
|
+ this.$message.success('数据上传成功')
|
|
|
+ // 上传成功后触发刷新
|
|
|
+ this.$emit('handle-dynamic-table-save', { row, tableData: {} })
|
|
|
+ this.handleRefresh()
|
|
|
+ } catch (err) {
|
|
|
+ console.error('数据上传失败:', err)
|
|
|
+ } finally {
|
|
|
+ if (loading && loading.close) loading.close()
|
|
|
+ this.pendingDynamicRow = null
|
|
|
+ if (this.$refs.dynamicUploadInput)
|
|
|
+ this.$refs.dynamicUploadInput.value = ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 动态表-数据下载
|
|
|
+ async handleDataDownload(row) {
|
|
|
+ try {
|
|
|
+ const loading = this.$loading({
|
|
|
+ lock: true,
|
|
|
+ text: '数据下载中...',
|
|
|
+ spinner: 'el-icon-loading',
|
|
|
+ background: 'rgba(0, 0, 0, 0.7)',
|
|
|
+ })
|
|
|
+ // 取 surveyTemplateId 与 versionId
|
|
|
+ const surveyTemplateId =
|
|
|
+ (row && (row.surveyTemplateId || row.templateId)) ||
|
|
|
+ this.surveyTemplateId ||
|
|
|
+ ''
|
|
|
+ const versionId =
|
|
|
+ (row && (row.versionId || row.version || row.templateVersionId)) ||
|
|
|
+ ''
|
|
|
+ // if (!surveyTemplateId || !versionId) {
|
|
|
+ // loading.close()
|
|
|
+ // this.$message &&
|
|
|
+ // this.$message.warning &&
|
|
|
+ // this.$message.warning('缺少模板或版本信息,无法下载')
|
|
|
+ // return
|
|
|
+ // }
|
|
|
+ const params = { surveyTemplateId, versionId }
|
|
|
+ const res = await downloadTemplate(params)
|
|
|
+ loading.close()
|
|
|
+ // 处理响应数据(可能是 axios 响应或直接 Blob)
|
|
|
+ const headers = (res && res.headers) || {}
|
|
|
+ const contentDisposition =
|
|
|
+ headers['content-disposition'] || headers['Content-Disposition']
|
|
|
+ let fileName =
|
|
|
+ this.extractFileNameFromHeader(contentDisposition) ||
|
|
|
+ `${row.name || '数据'}.xlsx`
|
|
|
+ if (!/\.[a-zA-Z0-9]+$/.test(fileName)) {
|
|
|
+ fileName += '.xlsx'
|
|
|
+ }
|
|
|
+ const blobData = (res && res.data) || res
|
|
|
+ const blob =
|
|
|
+ blobData instanceof Blob ? blobData : new Blob([blobData])
|
|
|
+ const url = window.URL.createObjectURL(blob)
|
|
|
+ const link = document.createElement('a')
|
|
|
+ link.style.display = 'none'
|
|
|
+ link.href = url
|
|
|
+ link.download = fileName
|
|
|
+ document.body.appendChild(link)
|
|
|
+ link.click()
|
|
|
+ document.body.removeChild(link)
|
|
|
+ window.URL.revokeObjectURL(url)
|
|
|
+ this.$message &&
|
|
|
+ this.$message.success &&
|
|
|
+ this.$message.success('开始下载文件')
|
|
|
+ } catch (e) {
|
|
|
+ console.error('数据下载失败: ', e)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ extractFileNameFromHeader(contentDisposition) {
|
|
|
+ if (!contentDisposition) return ''
|
|
|
+ const match = /filename[^;=\n]*=((['"])?.*?\2|[^;\n]*)/i.exec(
|
|
|
+ contentDisposition
|
|
|
+ )
|
|
|
+ if (match && match[1]) {
|
|
|
+ try {
|
|
|
+ return decodeURIComponent(match[1].replace(/['"]/g, ''))
|
|
|
+ } catch (e) {
|
|
|
+ return match[1].replace(/['"]/g, '')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ''
|
|
|
+ },
|
|
|
// 初始化动态表数据
|
|
|
async initDynamicTableData() {
|
|
|
try {
|