iZaiZaiA vor 2 Jahren
Ursprung
Commit
cc07ce8f3f

+ 1 - 1
src/config/index.js

@@ -17,7 +17,7 @@ export default {
     statusWhiteList: [],    //http的status默认放行列表
     ossUrl: 'https://bladex-test-info.oss-cn-chengdu.aliyuncs.com', //oss地址
     smsPhone: '',  //测试接受短信验证码的手机号
-    dev_version: '202209191820',    //开发版本号
+    dev_version: '202209211120',    //开发版本号
     prod_host: 'http://47.110.251.215:8090',  //线上
     dev_host: 'http://192.168.4.6', //黄键楠
     //dev_host: 'http://192.168.3.13', //祝炜

+ 13 - 0
src/styles/other/first-item.scss

@@ -77,6 +77,19 @@
             background: #f1f5f8;
             border-radius: 10px;
             box-shadow: -2px 0px 10px 0px rgba(32,37,50,0.03), 0px 10px 21px 20px rgba(32,37,50,0.03);
+            .title {
+                position: relative;
+                margin-bottom: 14px;
+                font-size: 16px;
+                font-weight: 500;
+            }
+            .node-upload-box {
+                position: relative;
+            }
+            .hc-table-node-file-box {
+                position: relative;
+                height: calc(100% - 245px);
+            }
         }
     }
     .node-action {

+ 70 - 38
src/views/other/components/HcUpload.vue

@@ -1,7 +1,7 @@
 <template>
-    <el-upload class="hc-upload-border first-item-upload" drag :action="action" :headers="getTokenHeader()" :data="uploadData" :accept="accept" :file-list="fileListData" multiple :disabled="uploadDisabled"
-               :on-preview="uploadPreview" :on-success="uploadSuccess" :on-exceed="uploadExceed" :on-error="uploadError" :before-upload="beforeUpload"
-               :on-progress="uploadPreview">
+    <el-upload class="first-item-upload" ref="uploadRef" drag
+               :limit="1" :headers="getTokenHeader()" :action="action" :data="uploadData" :accept="accept" :file-list="fileListData" :disabled="uploadDisabled" :before-remove="uploadBeforeRemove"
+               :on-preview="uploadPreview" :on-success="uploadSuccess" :on-exceed="uploadExceed" :on-error="uploadError" :before-upload="beforeUpload" :on-progress="uploadprogress">
         <div class="hc-upload-loading" v-loading="uploadDisabled" element-loading-text="上传中...">
             <HcIcon name="backup" ui="text-5xl mt-4"/>
             <div class="el-upload__text">拖动文件到这里 或 <em>点击这里选择文件</em> 并上传</div>
@@ -13,9 +13,11 @@
 </template>
 
 <script setup>
-import {ref,watch,onMounted} from "vue";
-import {getTokenHeader} from '~src/api/request/header';
+import {ref,watch} from "vue";
 import {isSize} from "vue-utils-plus"
+import {genFileId} from "element-plus";
+import {getTokenHeader} from '~src/api/request/header';
+
 const props = defineProps({
     fileList: {
         type: Array,
@@ -28,11 +30,12 @@ const props = defineProps({
 })
 
 //变量
+const uploadRef = ref(null)
 const uploadData = ref(props.datas)
-const fileListData = ref(props.fileList);
-const action = '/api/blade-manager/first/add-first-buss-file';
-const accept = 'image/png,image/jpg,image/jpeg,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/pdf,.doc,.docx,application/msword';
+const fileListData = ref(props.fileList)
 const uploadDisabled = ref(false)
+const action = '/api/blade-manager/first/add-first-buss-file'
+const accept = 'image/png,image/jpg,image/jpeg,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/pdf,.doc,.docx,application/msword'
 
 //监听
 watch(() => [
@@ -43,21 +46,12 @@ watch(() => [
     fileListData.value = fileList
 })
 
-//渲染完成
-onMounted(()=> {
-    beforeFileNum.value = 0
-    finishFileNum.value = 0
-    errorFileNum.value = 0
-})
-
 //事件
-const emit = defineEmits(['finish'])
+const emit = defineEmits(['finish', 'progress', 'preview'])
 
 //上传前
-const beforeFileNum = ref(0)
 const beforeUpload = async (file) => {
     if (isSize(file?.size,60)) {
-        beforeFileNum.value ++;
         return true;
     } else {
         window?.$message?.warning('文件大小, 不能过60M!');
@@ -66,41 +60,79 @@ const beforeUpload = async (file) => {
 }
 
 //超出限制时
-const uploadExceed = () => {
-    window?.$message?.warning('请上传 jpg/png/pdf/excel/word 的文件,文件大小 不超过60M');
+const uploadExceed = (files) => {
+    uploadRef.value?.clearFiles()
+    const file = files[0]
+    file.uid = genFileId()
+    uploadRef.value?.handleStart(file)
 }
 
 //上传中
 const uploadprogress = () => {
     uploadDisabled.value = true
+    emit('progress', true)
 }
 
 //上传完成
-const finishFileNum = ref(0)
 const uploadSuccess = () => {
-    finishFileNum.value ++;
-    if (beforeFileNum.value === finishFileNum.value) {
-        uploadDisabled.value = false
-        emit('finish', {type: 'success'})
-    }
+    uploadDisabled.value = false
+    emit('finish', {type: 'success'})
+    emit('progress', false)
 }
 
 //上传失败
-const errorFileNum = ref(0)
 const uploadError = () => {
-    errorFileNum.value ++;
-    window?.$message?.error('上传失败');
-    const num = finishFileNum.value + errorFileNum.value;
-    if (beforeFileNum.value === num) {
-        uploadDisabled.value = false
-        emit('finish', {type: 'error'})
-    }
+    uploadDisabled.value = false
+    emit('finish', {type: 'error'})
+    emit('progress', false)
+}
+
+//移除文件
+const uploadBeforeRemove = () => {
+    return false
 }
 
 //预览
-const uploadPreview = ({url}) => {
-    if (url) {
-        window.open(url, '_blank')
-    }
+const uploadPreview = (files) => {
+    emit('preview', files)
 }
 </script>
+
+<style lang="scss">
+.first-item-upload {
+    position: relative;
+    .el-upload-list {
+        position: absolute;
+        margin: 0;
+        width: 100%;
+        bottom: 28px;
+        padding: 0 1px;
+        .el-upload-list__item {
+            background: var(--el-color-primary-light-9);
+            color: var(--el-color-primary);
+            border-radius: 0 0 4px 4px;
+            font-size: 14px;
+            margin-bottom: 0;
+            width: 100%;
+            .el-upload-list__item-info {
+                margin-left: 10px;
+                height: 30px;
+                .el-upload-list__item-name {
+                    color: inherit;
+                    font-size: inherit;
+                    .el-icon {
+                        color: inherit;
+                    }
+                }
+            }
+            .el-icon--close, .el-icon--close-tip {
+                display: none !important;
+            }
+        }
+    }
+    .el-upload__tip {
+        margin-left: 5px;
+    }
+}
+</style>
+

+ 0 - 426
src/views/other/components/first-item-form.vue

@@ -1,426 +0,0 @@
-<template>
-    <n-divider dashed title-placement="left">
-        <span class="text-hover" @click="goToBack()">首件工程</span>
-        <span class="ml-2">/</span>
-        <span class="ml-2">上报首件</span>
-    </n-divider>
-    <div class="hc-layout-box">
-        <div class="hc-layout-content-box">
-            <n-card class="hc-card-overflow-p-box" :segmented="{content: true}">
-                <div class="table-form-box">
-                    <div :id="`table-form-${contractId}`"></div>
-                </div>
-            </n-card>
-        </div>
-        <div class="hc-layout-card-box">
-            <n-card class="hc-card-overflow-p-box" :segmented="{content: true}">
-                <template #header>
-                    <div class="hc-card-header flex items-center">
-                        <div>上传总结报告:</div>
-                        <div class="ml-2">
-                            <n-upload :action="action" :headers="getTokenHeader()" :data="upData" :accept="accept" :disabled="!pkeyId"
-                                      :show-file-list="false" @before-upload="beforeUpload" @finish="uploadFinish">
-                                <n-button type="primary" class="px-4" :loading="uploadLoading">选择文件</n-button>
-                            </n-upload>
-                        </div>
-                        <div class="ml-5 text-purple" v-if="pkeyId">{{fileName}}</div>
-                        <div class="ml-5 text-purple" v-else>表单异常,暂时无法使用上传</div>
-                    </div>
-                </template>
-                <n-data-table :columns="tableColumns" :data="tableData" :row-key="row => row.id" :pagination="false" :single-line="false" striped/>
-                <template #action>
-                    <div class="text-center">
-                        <n-button class="px-5" @click="goToBack">取消</n-button>
-                        <n-button type="primary" class="px-5 ml-6" :disabled="!pkeyId" @click="saveBussData">保存</n-button>
-                        <n-button type="primary" strong secondary class="px-5 ml-6" :disabled="!pkeyId" @click="bussPdfInfo">预览</n-button>
-                        <n-button type="primary" strong secondary class="px-5 ml-6" :disabled="!pkeyId" @click="reportModalClick">上报</n-button>
-                    </div>
-                </template>
-            </n-card>
-        </div>
-    </div>
-    <!--上报审批-->
-    <HcReportModal  title="上报审批" url="informationWriteQuery/taskOne" :show="showReportModal" :projectId="projectId" :contractId="contractId"
-                    :taskName="reportTaskName" :ids="reportIds" :addition="reportAddition" @hide="showReportModal= false" @finish="showReportFinish"/>
-</template>
-
-<script setup>
-import {h, onMounted, ref, watch} from 'vue'
-import {createApp} from "vue/dist/vue.esm-bundler.js";
-import {getTokenHeader} from '~src/api/request/header';
-import HcReportModal from "~com/reportModal/index.vue"
-import firstItemApi from '~api/other/first-item';
-import {isObject,isObjNull} from "~src/utils/lib/isApp";
-import {ElButton,ElTooltip,ElInput,ElDatePicker,ElUpload,ElInputNumber,ElTimePicker,ElSelect,ElOption,ElRadioGroup,ElRadio,ElCheckbox,ElCheckboxGroup} from 'element-plus'
-
-//参数
-const props = defineProps({
-    rows: {
-        type: Array,
-        default: () => ([])
-    },
-    wbsId: {
-        type: [String,Number],
-        default: ''
-    },
-    relation: {
-        type: [String,Number],
-        default: ''
-    },
-    projectId: {
-        type: [String,Number],
-        default: ''
-    },
-    contractId: {
-        type: [String,Number],
-        default: ''
-    },
-})
-
-//初始变量
-const primaryKeyId = ref(props.wbsId)
-const relation = ref(props.relation)
-const projectId = ref(props.projectId)
-const contractId = ref(props.contractId)
-//监听
-watch(() => [
-    props.rows,
-    props.wbsId,
-    props.relation,
-    props.projectId,
-    props.contractId
-], ([rows,wid,rid,pid,cid]) => {
-    tableData.value = rows
-    primaryKeyId.value = wid
-    relation.value = rid
-    projectId.value = pid
-    contractId.value = cid
-    if (cid) getExcelHtmlData()
-})
-
-//渲染完成
-onMounted(() => {
-    if (contractId.value) {
-        getExcelHtmlData()
-    }
-})
-
-//表格表单渲染
-const pkeyId = ref(null)
-const tableFormData = ref({})
-const getExcelHtmlData = () => {
-    pkeyId.value = null
-    const cid = contractId.value
-    firstItemApi.getFirstExcelHtml({
-        contractId: cid
-    }).then(({data}) => {
-        const temp = data?.data?.data
-        if (!isObjNull(data.data) && temp) {
-            pkeyId.value = data?.data?.id ?? null
-            HTableForm(temp,tableFormData.value,cid)
-            //getBussDataInfo(data?.data?.id)
-        } else {
-            window?.$message?.warning(data.msg || '暂无表单')
-        }
-    })
-}
-
-//渲染表格表单
-const HTableForm = (templateData, tableForm, cid) => {
-    const app = createApp({
-        data() {
-            return {
-                getTokenHeader: getTokenHeader(),
-                formData: tableForm,
-                formUploadLoading: false,
-            }
-        },
-        template: templateData,
-        components: {ElButton,ElTooltip,ElInput,ElDatePicker,ElUpload,ElInputNumber,ElTimePicker,ElSelect,ElOption,ElRadioGroup,ElRadio,ElCheckbox,ElCheckboxGroup},
-        watch: {
-            tableForm: {
-                handler(obj) {
-                    this.formData = obj
-                },
-                deep: true
-            },
-            formData: {
-                handler(obj) {
-                    tableFormData.value = obj
-                },
-                deep: true
-            },
-        },
-        methods: {
-            RightClick(a,b,c,d,e,f,event) {
-                event.preventDefault();
-            },
-            getInformation() {},
-            datePickerChange(val,key) {
-                this.formData[key] = val
-            },
-            //上传进度
-            uploadprogress() {
-                this.formUploadLoading = true
-            },
-            //上传完成
-            formUploadSuccess(res,key) {
-                this.formUploadLoading = false
-                if (res.code === 200) {
-                    this.formData[key] = res.data?.link || ''
-                }
-            },
-            //上传失败
-            formUploadError() {
-                this.formUploadLoading = false
-            },
-            //格式错误
-            formUploadExceed() {
-                this.formUploadLoading = false
-            },
-            //删除上传的文件
-            delTableFormFile(key) {
-                this.formData[key] = ''
-            },
-        }
-    })
-    app.mount(`#table-form-${cid}`)
-}
-
-//获取表单数据
-const getBussDataInfo = async (pkeyId) => {
-    if (pkeyId) {
-        const { data } = await firstItemApi.getFirstBussDataInfo({pkeyId: pkeyId + ''})
-        const valRes = isObject(data?.data) ? data?.data : {}
-        if (!isObjNull(valRes)) {
-            const pickerKey = valRes['pickerKey'] || ''
-            const pickerKeys = pickerKey.split(',')
-            for (let i = 0; i < pickerKeys.length; i++) {
-                const val = valRes[pickerKeys[i]] || ''
-                if (val) {
-                    const data = val.replace(/'/g,'"');
-                    valRes[pickerKeys[i]] = JSON.parse(data)
-                } else {
-                    valRes[pickerKeys[i]] = []
-                }
-            }
-            //有数据,关联数据
-            tableFormData.value = valRes
-        } else {
-            tableFormData.value = {}
-        }
-    } else {
-        tableFormData.value = {}
-    }
-}
-
-//表格表头
-const tableData = ref(props.rows)
-const tableColumns = [
-    {title: '文件名称', key: 'name'},
-    {title: "操作", key: "actions", width: 80, align: 'center',
-        render(_, index) {
-            return h('span', {
-                class: 'text-red',
-                onClick: () => tableDelButton(index)
-            }, {
-                default: () => '删除'
-            })
-        }
-    }
-]
-
-//删除文件
-const tableDelButton = (index) => {
-    window?.$dialog?.warning({
-        title: "删除提醒",
-        content: "确定删除该文件吗?",
-        positiveText: "确定删除",
-        negativeText: "取消",
-        onPositiveClick: () => {
-            tableData.value.splice(index, 1)
-        }
-    });
-}
-
-//文件上传
-const fileName = ref('')
-const upData = ref({})
-const action = '/api/blade-manager/first/add-first-buss-file';
-const accept = 'image/png,image/jpg,image/jpeg,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/pdf,.doc,.docx,application/msword';
-
-//上传前
-const uploadLoading = ref(false)
-const beforeUpload = ({file}) => {
-    let maxTrillion = 60;
-    let fileSizeData = file?.file?.size
-    let maxSize = maxTrillion * 1024 * 1024
-    if (fileSizeData > maxSize) {
-        window.$message?.warning(`文件大小,不能过${maxTrillion}M!`);
-        return false;
-    } else {
-        fileName.value = file.name
-        upData.value = {pkeyId: pkeyId.value}
-        uploadLoading.value = true
-        return true;
-    }
-}
-//上传完成
-const uploadFinish = ({event}) => {
-    uploadLoading.value = false
-    let res = JSON.parse(event?.target?.response);
-    if (res.code === 200) {
-        window.$message?.success('上传成功');
-    } else {
-        window.$message?.error('上传失败');
-    }
-}
-
-//填报数据保存
-const saveBussData = async () => {
-    const res = await saveExcelBussData(pkeyId.value + '')
-    if (res) {
-        getBussPdfInfo(pkeyId.value + '')
-    }
-}
-
-//pdf预览
-const bussPdfInfo = () => {
-    getBussPdfInfo(pkeyId.value + '')
-}
-
-//保存请求
-const saveExcelBussData = async (pkeyId) => {
-    const {data} = await firstItemApi.saveBussData({
-        ...tableFormData.value,
-        projectId: projectId.value,
-        contractId: contractId.value,
-        firstNodeId: primaryKeyId.value,
-        pkeyId: pkeyId,
-        classify: '1',
-        isFirst: 1
-    })
-    if(data && data.code === 200) {
-        window?.$message?.success('保存成功')
-        return true
-    } else {
-        window?.$message?.warning(data.msg || '保存失败')
-        return false
-    }
-}
-
-//预览PDF请求
-const getBussPdfInfo = (pkeyId) => {
-    const liunkIds = tableData.value.map((obj) => {
-        return obj?.id;
-    }).join(",")
-    //发起请求
-    firstItemApi.getFirstBussPdfInfo({
-        pkeyId: pkeyId,
-        liunkIds: liunkIds
-    }).then(({data}) => {
-        if(data.code === 200 && data?.data) {
-            window.open(data?.data,'_blank')
-        } else {
-            window.$message?.warning('暂无PDF')
-        }
-    })
-}
-
-
-//事件
-const emit = defineEmits(['ToClose'])
-
-//批量上报
-const showReportModal = ref(false)
-const reportIds = ref('')
-const reportTaskName = ref('')
-const reportAddition = ref({})
-const reportModalClick = () => {
-    const rows = tableData.value
-    if (rows.length > 0) {
-        reportIds.value = rows.map((obj) => {
-            return obj?.id;
-        }).join(",")
-        reportTaskName.value = rows.length > 1?`${rows[0].name}等${rows.length}个文件`:rows[0].name
-        reportAddition.value = {
-            classify: 1,
-            isFirst: 1,
-            primaryKeyId: primaryKeyId.value,
-            contractIdRelation: relation.value ?? contractId.value,
-        }
-        showReportModal.value = true
-    } else {
-        window.$message?.warning('暂无相关数据')
-    }
-}
-
-//上报完成
-const showReportFinish = () => {
-    showReportModal.value = false
-}
-
-//关闭
-const goToBack = () => {
-    emit('ToClose')
-}
-</script>
-
-<style lang="scss" scoped>
-.hc-layout-box {
-    display: flex;
-    position: relative;
-    height: calc(100% - 60px);
-    .hc-layout-content-box {
-        flex: 2;
-        overflow: auto;
-        position: relative;
-        padding: 0 24px 15px 20px;
-        .table-form-box {
-            position: relative;
-            flex: 1;
-            overflow: auto;
-            height: 100%;
-            .hc-no-table-form {
-                position: relative;
-                height: 100%;
-                display: flex;
-                justify-content: center;
-                align-items: center;
-            }
-        }
-    }
-    .hc-layout-card-box {
-        flex: 1;
-        position: relative;
-        padding: 0 24px 15px 0;
-    }
-}
-.hc-card-header {
-    position: relative;
-    font-size: initial;
-    font-weight: initial;
-}
-</style>
-<style lang="scss">
-//设置表单样式
-.table-form-box {
-    td {
-        padding: 6px;
-        font-family: "EUDC", 宋体, v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
-        .el-input {
-            background-color: #ffffff !important;
-            border-radius: 3px;
-            .el-input__wrapper {
-                background-color: inherit;
-            }
-            .el-input__wrapper.is-focus, .el-input__wrapper:hover {
-                box-shadow: 0 0 0 1.5px var(--el-input-focus-border-color) inset;
-                background-color: #eddac4;
-            }
-            //公式 #dcdcdc
-            //焦点 #eddac4
-        }
-    }
-}
-</style>

+ 102 - 25
src/views/other/first-item.vue

@@ -83,6 +83,10 @@
                                     class="mx-1" effect="dark" v-if="item['waitingUserName']">{{item['waitingUserName']}}</el-tag>
                         </template>
                     </template>
+                    <template #taskStatusStr="{row}">
+                        <el-tag :type="`${row.status === 2 ? 'success' : row.status === 0 ? 'warning' : row.status === 1 ? 'danger' : 'info'}`"
+                                class="mx-1" effect="dark" v-if="row['taskStatusStr']">{{row['taskStatusStr']}}</el-tag>
+                    </template>
                 </HcTable>
                 <template #action>
                     <div class="lr-dialog-footer">
@@ -111,33 +115,39 @@
                 </div>
                 <div class="node-file">
                     <div class="title">上传总结报告</div>
-                    <div class="ml-2">
+                    <div class="node-upload-box" v-if="contractId && isTableForm">
                         <HcUpload :fileList="fileListData" :datas="uploadData" @finish='uploadChange'/>
                     </div>
+                    <div class="node-upload-box" v-else>
+                        <el-alert title="表单异常,暂时无法使用上传" type="warning" show-icon :closable="false"/>
+                    </div>
+                    <el-divider border-style="dashed" />
+                    <div class="title">文件附件</div>
+                    <div class="hc-table-node-file-box">
+                        <HcTable :column="tableFileColumn" :datas="tableFileData" :isIndex="false">
+                            <template #action="{row,index}">
+                                <el-button type="danger" plain size="small" @click="tableDelButton(index)">删除</el-button>
+                            </template>
+                        </HcTable>
+                    </div>
                 </div>
             </div>
             <div class="node-action">
-                <HcTooltip keys="wbs_save">
-                    <el-button type="primary" hc-btn>
-                        <HcIcon name="save"/>
-                        <span>保存</span>
-                    </el-button>
-                </HcTooltip>
-                <HcTooltip keys="wbs_report">
-                    <el-button hc-btn>
-                        <HcIcon name="send-plane-2"/>
-                        <span>上报</span>
-                    </el-button>
-                </HcTooltip>
-                <HcTooltip keys="wbs_preview">
-                    <el-button hc-btn>
-                        <HcIcon name="eye"/>
-                        <span>预览</span>
-                    </el-button>
-                </HcTooltip>
+                <el-button type="primary" hc-btn :disabled="!contractId || !isTableForm"  @click="saveBussData">
+                    <HcIcon name="save"/>
+                    <span>保存</span>
+                </el-button>
+                <el-button hc-btn :disabled="!contractId || !isTableForm" @click="bussPdfInfo">
+                    <HcIcon name="eye"/>
+                    <span>预览</span>
+                </el-button>
+                <el-button hc-btn :disabled="!contractId || !isTableForm" @click="reportModalClick">
+                    <HcIcon name="send-plane-2"/>
+                    <span>上报</span>
+                </el-button>
                 <el-button hc-btn @click="FirstReportDrawerClose">
                     <HcIcon name="close"/>
-                    <span>关闭</span>
+                    <span>返回</span>
                 </el-button>
             </div>
         </HcDrawer>
@@ -151,7 +161,7 @@ import {useRouter, useRoute} from 'vue-router'
 import WbsTree from "./components/WbsTree.vue"
 import HcUpload from "./components/HcUpload.vue"
 import {getStoreData, setStoreData} from '~src/utils/storage'
-import {getArrValue, isString, getObjValue, getObjNullValue} from "vue-utils-plus"
+import {getArrValue, isString, getObjValue, getObjNullValue,deepClone} from "vue-utils-plus"
 import HTableForm from "~src/plugins/HTableForm"
 import {getReportNumber} from "~api/other";
 import firstApi from '~api/other/first-item';
@@ -362,6 +372,7 @@ const tableRowName = (row) => {
 const isFirstReportDrawer = ref(false)
 const firstReportClick = () => {
     isFirstReportDrawer.value = true
+    tableFileData.value = deepClone(tableSelectionKeys.value)
     getFirstExcelHtml()
 }
 const FirstReportDrawerClose = () => {
@@ -437,13 +448,79 @@ const uploadData = ref({})
 
 //上传文件
 const uploadChange = async ({type}) => {
-    if(type === 'success') {
-        //renewData()
-    } else if (type === 'del') {
-        //renewData()
+    console.log(type)
+}
+
+//文件附件列表
+const tableFileColumn = ref([
+    {key:'name', name: '文件名称'},
+    {key:'action', name: '操作', width: 80, align: 'center'}
+]);
+const tableFileData = ref([]);
+const tableDelButton = (index) => {
+    window?.$messageBox?.alert('确定删除该文件吗?', '删除提醒', {
+        type: 'warning',
+        showCancelButton: true,
+        confirmButtonText: '确定删除',
+        cancelButtonText: '取消',
+        callback: (action) => {
+            if (action === 'confirm') {
+                tableFileData.value.splice(index, 1)
+            }
+        }
+    })
+}
+
+//填报数据保存
+const saveBussData = async () => {
+    const { id } = treeItem.value
+    const res = await saveExcelBussData(id + '')
+    if (res) {
+        await getBussPdfInfo(id + '')
     }
 }
 
+//保存请求
+const saveExcelBussData = async (pkeyId) => {
+    const { primaryKeyId } = treeItem.value
+    const { error, code } = await firstApi.saveBussData({
+        ...tableFormData.value,
+        projectId: projectId.value,
+        contractId: contractId.value,
+        firstNodeId: primaryKeyId,
+        pkeyId: pkeyId,
+        classify: '1',
+        isFirst: 1
+    }, false)
+    //判断状态
+    if (!error && code === 200) {
+        window.$message?.success('保存成功')
+        return true
+    } else {
+        window.$message?.error('保存失败')
+        return false
+    }
+}
+
+//pdf预览
+const bussPdfInfo = () => {
+    const { id } = treeItem.value
+    getBussPdfInfo(id + '')
+}
+
+//预览PDF请求
+const getBussPdfInfo = async (pkeyId) => {
+    const liunkIds = rowsToId(tableFileData.value)
+    const { error, code, data } = await firstApi.getFirstBussPdfInfo({
+        pkeyId: pkeyId,
+        liunkIds: liunkIds
+    })
+    //判断状态
+    const res = isString(data)? data ?? '': ''
+    if (!error && code === 200 && res) {
+        window.open(res,'_blank')
+    }
+}
 
 
 //上报审批