feat: 添加导入研发费用明细表和模板下载功能

This commit is contained in:
dj
2025-04-14 15:43:48 +08:00
parent c6390a8117
commit 7579b77b2d
4 changed files with 187 additions and 12 deletions

View File

@@ -226,3 +226,15 @@ export const ledgerTemplateDownload = () => {
}
);
};
//费用明细模板下载
export const costTemplateDownload = () => {
return axios.get(
`${import.meta.env.VITE_BASE_URL}/workflow/mosr/rd/expense/download/template`,
{
responseType: 'blob',
headers: {
Authorization: getToken()
}
}
);
};

View File

@@ -0,0 +1,112 @@
<template>
<el-upload :file-list="[]"
:limit="maxSize"
with-credentials
:multiple="multiple"
:http-request="httpRequestHandle"
:data="uploadParams"
:auto-upload="true"
:show-file-list="false"
:before-upload="beforeUpload"
:before-remove="beforeRemove"
:on-remove="handleRemove"
>
<el-button color="#DED0B2" style="margin-right: 10px;" :disabled="disabled">导入</el-button>
</el-upload>
</template>
<script setup>
import {ElMessageBox, ElNotification} from "element-plus";
import {getToken} from '@/utils/auth'
import axios from "axios";
const props = defineProps({
value: {
type: Array,
default: () => {
return []
}
},
maxSize: {
type: Number,
default: 30
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
})
const baseURL = import.meta.env.VITE_BASE_URL
const uploadFileUrl = ref(baseURL + "/workflow/mosr/rd/expense/import")
const headers = reactive({
authorization: getToken()
})
// const loading = ref(false)
const uploadParams = ref({})
const emit = defineEmits(["input", "getFile", "delete"])
const beforeRemove = (file) => {
return ElMessageBox.confirm(`确认删除名称为${file.name}的文件吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => true)
}
const handleRemove = (file) => {
emit("delete", file.response.data.id)
}
const beforeUpload = () => {
// loading.value = true
return true
}
const httpRequestHandle = (param) => {
let file = param.file
axios.post(uploadFileUrl.value, {
file: file
}, {
headers: {
'Content-Type': 'multipart/form-data',
...headers
}
}).then(res => {
handleUploadSuccess(res)
}).catch(error => {
uploadError(error)
})
}
const handleUploadSuccess = (res) => {
let data = res.data
ElNotification({
title: '提示',
message: data.code === 1000 ? '上传成功' : '上传失败',
type: data.code === 1000 ? 'success' : 'error'
})
emit("success")
}
const uploadError = (error) => {
// loading.value = false
ElNotification({
title: '提示',
message: "上传失败,请稍后再试!",
type: 'error'
})
}
defineExpose({
handleRemove
})
</script>
<style lang="scss" scoped>
a {
font-size: 14px;
color: #2a99ff;
}
</style>

View File

@@ -1,5 +1,8 @@
<template>
<div class="fv-table-container">
<el-button v-if="tableConfig.export && tableConfig.export.open&&changeExportPosition" @click="exportTable" color="#DED0B2"
style="float: left;margin-right: 10px">导出
</el-button>
<!-- 表格头部按钮 -->
<div class="fv-table-btn" v-if="tableConfig.btns">
<div class="table-head-btn">
@@ -15,7 +18,7 @@
</el-button>
</div>
</div>
<el-button v-if="tableConfig.export && tableConfig.export.open" @click="exportTable" color="#DED0B2"
<el-button v-if="tableConfig.export && tableConfig.export.open&&!changeExportPosition" @click="exportTable" color="#DED0B2"
style="margin-bottom: 10px">导出
</el-button>
<!-- 列显示配置 -->
@@ -121,6 +124,11 @@ const props = defineProps({
type: Boolean,
default: true
},
//是否改变导出位置, 导出在btns前面
changeExportPosition: {
type: Boolean,
default: false
},
// 是否显示列配置
isSettingCol: {
type: Boolean,

View File

@@ -1,6 +1,9 @@
<template>
<fvSearchForm :searchConfig="searchConfig" @search="search" style="margin-left: 16px"></fvSearchForm>
<fvTable ref="tableIns" :tableConfig="tableConfig">
<div style="float: left">
<import-cost-excel @success="importTheExpenseLedger"/>
</div>
<fvTable ref="tableIns" class="tablte" :tableConfig="tableConfig" @headBtnClick="headBtnClick" :changeExportPosition="true">
<template #empty>
<el-empty description="暂无数据"/>
</template>
@@ -8,11 +11,10 @@
</template>
<script setup lang="jsx">
import fvSelect from '@/fvcomponents/fvSelect/index.vue'
import {toThousands} from '@/utils/changePrice.js'
import { getSubCompOpt } from '@/api/user/user.js';
import {reactive, ref} from "vue";
import {useRoute, useRouter} from "vue-router";
import {costTemplateDownload, exportExcel, ledgerTemplateDownload} from "../../../api/project-manage";
import ImportCostExcel from "@/components/ImportCostExcel.vue";
const router = useRouter()
const route = useRoute()
const searchConfig = ref([
@@ -160,24 +162,65 @@ const tableConfig = reactive({
],
api: '/workflow/mosr/payment/list',
params: {},
btns: [
{name: '模板下载', key: 'down', color: '#DED0B2'},
// {name: '导入', key: 'import', color: '#DED0B2'}
],
export:{
open :true,
fileName:`研发费用明细表.xlsx`
fileName:`研发费用明细表`
}
})
const search = (val) => {
tableConfig.params = {...val}
tableIns.value.refresh()
}
const init = async () => {
const res = await getSubCompOpt()
searchConfig.value.find(item=>item.prop == 'affiliatedCompanyIds').props.data = res.data
const headBtnClick = (key) => {
switch (key) {
case 'down':
handleImportTemplateDownload()
break;
case 'import':
handleAdd()
break;
}
}
const exportTable = () => {
const $e = tableIns.value.$el
let $table = $e.querySelector('.el-table__fixed')
if (!$table) {
$table = $e
}
exportExcel($table, (5 + (Object.keys(tableData.value[0]).length - 5) * 5), "四川省国有资产经营投资管理有限责任公司科技创新项目人工成本分摊明细表", 2)
}
//导入模板下载
const handleImportTemplateDownload=()=>{
costTemplateDownload().then(res => {
let link = document.createElement('a')
try {
let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'});
let _fileName = "研发费用明细表模板.xlsx"//文件名,中文无法解析的时候会显示 _(下划线),生产环境获取不到
link.style.display='none';
// 兼容不同浏览器的URL对象
const url = window.URL || window.webkitURL || window.moxURL;
link.href=url.createObjectURL(blob);
link.setAttribute('download', _fileName.substring(_fileName.lastIndexOf('_')+1))
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
url.revokeObjectURL(link.href);//销毁url对象
}catch (e) {
console.log('下载的文件出错',e)
}
})
}
const importTheExpenseLedger = () => {
tableIns.value.refresh()
}
// init()
</script>
<style scoped lang="scss">
:deep(.el-table__header) {
.is-leaf:first-child {
.cell {