iZaiZaiA 2 years ago
parent
commit
5361c07f1b

+ 1 - 0
src/components/AppConfig/index.vue

@@ -13,6 +13,7 @@ function registerElTools () {
     window['$ElLoading'] = ElLoading;
     window['$ElMessageBox'] = ElMessageBox;
     window['$ElMessage'] = ElMessage;
+    window['$message'] = ElMessage;
     window['$ElNotification'] = ElNotification;
 }
 

+ 46 - 0
src/global/components/hc-tooltip/index.vue

@@ -0,0 +1,46 @@
+<template>
+    <el-tooltip :content="btn_Info['textInfo']" placement="top" :disabled="!isBubble || !btn_Info['textInfo']" v-if="btn_Info">
+        <slot></slot>
+    </el-tooltip>
+</template>
+
+<script setup>
+import {ref,watch,onMounted} from "vue";
+import {useAppStore} from "~src/store/index";
+const useAppState = useAppStore()
+
+//参数
+const props = defineProps({
+    keys: {
+        type: String,
+        default: ''
+    }
+})
+
+//变量
+const btn_Info = ref(false);
+const btn_key = ref(props.keys);
+const isBubble = ref(useAppState.getBubble);
+
+//监听
+watch(() => [
+    props.keys,
+    useAppState.getBubble,
+], ([keys, bubble]) => {
+    btn_key.value = keys
+    isBubble.value = bubble
+    btn_Info.value = getButtonsVal(keys)
+})
+
+//渲染完成
+onMounted(()=> {
+    if (props.keys) {
+        btn_Info.value = getButtonsVal(props.keys)
+    }
+})
+
+//获取气泡数据
+const getButtonsVal = (value) => {
+    return useAppState.getButtonsVal(value)
+}
+</script>

+ 2 - 0
src/global/components/index.js

@@ -2,6 +2,7 @@ import HcImg from './hc-img/index.vue'
 import HcIcon from './hc-icon/index.vue'
 import HcCard from './hc-card/index.vue'
 import HcPages from './hc-page/index.vue'
+import HcTooltip from './hc-tooltip/index.vue'
 import HcMenuSimple from './hc-menu-simple/index.vue'
 import HcDatePicker from './hc-date-picker/index.vue'
 import HcNewSwitch from './hc-new-switch/index.vue'
@@ -13,6 +14,7 @@ export const setupComponents = (App) => {
     App.component('HcIcon', HcIcon)
     App.component('HcCard', HcCard)
     App.component('HcPages', HcPages)
+    App.component('HcTooltip', HcTooltip)
     App.component('HcMenuSimple', HcMenuSimple)
     App.component('HcDatePicker', HcDatePicker)
     App.component('HcNewSwitch', HcNewSwitch)

+ 26 - 0
src/plugins/HTableForm.js

@@ -0,0 +1,26 @@
+import {createApp} from "vue/dist/vue.esm-bundler.js";
+import {ElInput,ElDatePicker,ElUpload,ElInputNumber,ElTimePicker,ElSelect,ElOption,ElRadioGroup,ElRadio,ElCheckbox,ElCheckboxGroup} from 'element-plus'
+
+const components = {ElInput, ElDatePicker, ElUpload, ElInputNumber, ElTimePicker, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckbox, ElCheckboxGroup}
+
+//表单渲染
+export const HTableForm = ({template, formData, appId, onRight}) => {
+    const app = createApp({
+        data() {
+            return {
+                formData,
+            }
+        },
+        template,
+        components,
+        methods: {
+            RightClick(a,b,c,d,e,f,event) {
+                event.preventDefault();
+                const KeyName = event?.target?.getAttribute('keyname') || ''
+                onRight(event, KeyName)
+            },
+            getInformation(a,b,c) {},
+        }
+    })
+    app.mount(appId)
+}

+ 21 - 0
src/styles/app/element.scss

@@ -20,6 +20,15 @@
     --el-button-hover-bg-color: var(--el-color-danger-light-8);
     --el-button-hover-border-color: transparent;
 }
+//绿色
+.el-button--success.is-link,
+.el-button--success.is-plain,
+.el-button--success.is-text {
+    --el-button-border-color: transparent;
+    --el-button-hover-text-color: var(--el-color-success);
+    --el-button-hover-bg-color: var(--el-color-success-light-8);
+    --el-button-hover-border-color: transparent;
+}
 .el-button + .el-button {
     margin-left: 20px;
 }
@@ -314,3 +323,15 @@
         margin-bottom: 20px;
     }
 }
+
+//上传文件列表
+.hc-upload-border {
+    .hc-upload-loading {
+        position: relative;
+    }
+    .el-upload-list {
+        border-top: 1px solid #f1f1f1;
+        margin-top: 24px;
+        padding-top: 24px;
+    }
+}

+ 123 - 0
src/views/data-fill/components/HcUpload.vue

@@ -0,0 +1,123 @@
+<template>
+    <el-upload class="hc-upload-border" drag :action="action" :headers="getTokenHeader()" :data="uploadData" :accept="accept" :file-list="fileListData" multiple :disabled="uploadDisabled"
+    :on-preview="uploadPreview" :before-remove="delUploadData" :on-success="uploadSuccess" :on-exceed="uploadExceed" :on-error="uploadError" :before-upload="beforeUpload" :on-progress="uploadPreview" :on-remove="uploadRemove">
+        <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>
+        </div>
+        <template #tip>
+            <div class="el-upload__tip" style="font-size: 14px;">允许格式:jpg/png/pdf/excel/word, 文件大小 小于 60MB</div>
+        </template>
+    </el-upload>
+</template>
+
+<script setup>
+import {ref,watch,onMounted} from "vue";
+import {getTokenHeader} from '~src/api/request/header';
+import wbsApi from "~api/data-fill/wbs"
+import {isSize} from "vue-utils-plus"
+const props = defineProps({
+    fileList: {
+        type: Array,
+        default: () => ([])
+    },
+    datas: {
+        type: Object,
+        default: () => ({})
+    },
+})
+
+//变量
+const uploadData = ref(props.datas)
+const fileListData = ref(props.fileList);
+const action = '/api/blade-manager/exceltab/add-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 uploadDisabled = ref(false)
+
+//监听
+watch(() => [
+    props.fileList,
+    props.datas,
+], ([fileList, datas]) => {
+    uploadData.value = datas
+    fileListData.value = fileList
+})
+
+//渲染完成
+onMounted(()=> {
+    beforeFileNum.value = 0
+    finishFileNum.value = 0
+    errorFileNum.value = 0
+})
+
+//事件
+const emit = defineEmits(['change'])
+
+//上传前
+const beforeFileNum = ref(0)
+const beforeUpload = async (file) => {
+    if (isSize(file?.size,30)) {
+        beforeFileNum.value ++;
+        return true;
+    } else {
+        window?.$ElMessage?.warning('文件大小, 不能过60M!');
+        return false;
+    }
+}
+
+//超出限制时
+const uploadExceed = () => {
+    window?.$ElMessage?.warning('请上传 jpg/png/pdf/excel/word 的文件,文件大小 不超过60M');
+}
+
+//上传中
+const uploadprogress = () => {
+    uploadDisabled.value = true
+}
+
+//上传完成
+const finishFileNum = ref(0)
+const uploadSuccess = () => {
+    finishFileNum.value ++;
+    if (beforeFileNum.value === finishFileNum.value) {
+        uploadDisabled.value = false
+        emit('change', {type: 'success'})
+    }
+}
+
+//上传失败
+const errorFileNum = ref(0)
+const uploadError = () => {
+    errorFileNum.value ++;
+    window?.$ElMessage?.error('上传失败');
+    const num = finishFileNum.value + errorFileNum.value;
+    if (beforeFileNum.value === num) {
+        uploadDisabled.value = false
+        emit('change', {type: 'success'})
+    }
+}
+
+//预览
+const uploadPreview = ({url}) => {
+    if (url) {
+        window.open(url, '_blank')
+    }
+}
+
+//删除文件
+const delUploadData = async ({id}) => {
+    const {data} = await wbsApi.removeBussFile({ids: id})
+    if(data && data.code === 200) {
+        window.$ElMessage?.success('删除成功');
+        return true
+    } else {
+        return false
+    }
+}
+
+const uploadRemove = () => {
+    if(fileListData.value.length <= 0) {
+        emit('change', {type: 'del'})
+    }
+}
+</script>

+ 262 - 258
src/views/data-fill/components/ListItem.vue

@@ -1,33 +1,33 @@
 <template>
     <div class="data-fill-list-box">
-        <el-collapse v-model="activeName" accordion>
+        <el-collapse v-model="ActiveKey" accordion @change="CollapseChange">
             <template v-for="(item,index) in listDatas" :key="item?.pkeyId">
-                <el-collapse-item :name="`item-${index}-${item?.pkeyId}`" :disabled="item?.isBussShow == 2" :id="`item-${index}-${item?.pkeyId}`">
+                <el-collapse-item :name="`item-${index}-${item?.pkeyId}`" :disabled="item['isBussShow'] === 2" :id="`item-${index}-${item?.pkeyId}`">
                     <template #title>
                         <div class="hc-collapse-item-header">
                             <div class="text-lg truncate item-title">{{item.deptName}}</div>
                             <div class="hc-extra-text-box">
-                                <el-tooltip :content="btn_del_table?.textInfo" placement="top" :disabled="!bubbleVal || !btn_del_table?.textInfo" v-if="btn_del_table && item?.isCopeTab === 2">
-                                    <el-button type="danger" plain :disabled="item?.isBussShow == 2" @click.stop="delClick(item,index)">删除本表</el-button>
-                                </el-tooltip>
-                                <el-tooltip :content="btn_copy_table?.textInfo" placement="top" :disabled="!bubbleVal || !btn_copy_table?.textInfo" v-if="btn_copy_table">
-                                    <el-button type="primary" plain :disabled="item?.isBussShow == 2" @click.stop="copyClick(item,index)">复制本表</el-button>
-                                </el-tooltip>
-                                <el-tooltip :content="btn_hide_table?.textInfo" placement="top" :disabled="!bubbleVal || !btn_hide_table?.textInfo" v-if="btn_hide_table">
+                                <HcTooltip keys="wbs_del_table" v-if="item['isCopeTab'] === 2">
+                                    <el-button type="danger" plain :disabled="item['isBussShow'] === 2" @click.stop="delClick(item,index)">删除本表</el-button>
+                                </HcTooltip>
+                                <HcTooltip keys="wbs_copy_table">
+                                    <el-button type="primary" plain :disabled="item['isBussShow'] === 2" @click.stop="copyClick(item,index)">复制本表</el-button>
+                                </HcTooltip>
+                                <HcTooltip keys="wbs_hide_table">
                                     <el-button type="primary" plain @click.stop="hideClick(item,index)">
-                                        <template v-if="item?.isBussShow == 1">隐藏本表</template>
+                                        <template v-if="item['isBussShow'] === 1">隐藏本表</template>
                                         <template v-else>显示本表</template>
                                     </el-button>
-                                </el-tooltip>
-                                <el-tooltip :content="btn_pre_table?.textInfo" placement="top" :disabled="!bubbleVal || !btn_pre_table?.textInfo" v-if="btn_pre_table">
-                                    <el-button type="primary" plain :disabled="item?.isBussShow == 2 || item?.isTabPdf === 1" @click.stop="previewClick(item,index)">预览</el-button>
-                                </el-tooltip>
-                                <el-tooltip :content="btn_up_table?.textInfo" placement="top" :disabled="!bubbleVal || !btn_up_table?.textInfo" v-if="btn_up_table">
-                                    <el-button :type="item?.tabFileType === 2?'success':'primary'" plain :disabled="item?.isBussShow == 2" @click.stop="uploadClick(item,index)">
-                                        <template v-if="item?.tabFileType === 2">已上传</template>
+                                </HcTooltip>
+                                <HcTooltip keys="wbs_preview_table">
+                                    <el-button type="primary" plain :disabled="item['isBussShow'] === 2 || item['isTabPdf'] === 1" @click.stop="previewClick(item,index)">预览</el-button>
+                                </HcTooltip>
+                                <HcTooltip keys="wbs_upload_table">
+                                    <el-button :type="item['tabFileType'] === 2?'success':'primary'" plain :disabled="item['isBussShow'] === 2" @click.stop="uploadClick(item,index)">
+                                        <template v-if="item['tabFileType'] === 2">已上传</template>
                                         <template v-else>上传</template>
                                     </el-button>
-                                </el-tooltip>
+                                </HcTooltip>
                             </div>
                         </div>
                     </template>
@@ -50,23 +50,23 @@
                             <div class="text-gray-400 tip-item">2、系统支持键盘中,shift + tab键向上一个填报框切换,tab向下一个填报框切换。暂不支持上下按键切换输入框</div>
                             <div class="table-tip-foot">
                                 <div class="tip-left-btn">
-                                    <el-tooltip :content="btn_impo_table?.textInfo" placement="top" :disabled="!bubbleVal || !btn_impo_table?.textInfo" v-if="btn_impo_table">
+                                    <HcTooltip keys="wbs_import_table">
                                         <div class="text-gray-400 dow-text">
                                             <HcIcon name="publish" ui="text-lg"/>
                                             <span class="ml-1">导入列表数据</span>
                                         </div>
-                                    </el-tooltip>
-                                    <el-tooltip :content="btn_down_table?.textInfo" placement="top" :disabled="!bubbleVal || !btn_down_table?.textInfo" v-if="btn_down_table">
+                                    </HcTooltip>
+                                    <HcTooltip keys="wbs_download_table">
                                         <div class="text-main dow-text">
                                             <HcIcon name="file_download" ui="text-lg"/>
                                             <span class="ml-1">下载导入模板</span>
                                         </div>
-                                    </el-tooltip>
+                                    </HcTooltip>
                                 </div>
                                 <div class="tip-right-btn">
-                                    <el-tooltip :content="btn_save_table?.textInfo" placement="top" :disabled="!bubbleVal || !btn_save_table?.textInfo" v-if="btn_save_table">
+                                    <HcTooltip keys="wbs_save_table">
                                         <el-button type="primary" hc-btn size="large" @click="tableFormSaveClick(item,index)">保存</el-button>
-                                    </el-tooltip>
+                                    </HcTooltip>
                                 </div>
                             </div>
                         </div>
@@ -75,19 +75,24 @@
             </template>
         </el-collapse>
     </div>
+    <!--鼠标右键菜单-->
+    <n-dropdown placement="bottom" trigger="manual" :x="tableFormMenuX" :y="tableFormMenuY" size="huge" :options="tableFormMenu" :show="tableFormMenuShow" @clickoutside="onClickoutside" @select="handleMenuSelect"/>
+    <!--上传文件-->
+    <el-dialog v-model="uploadModal" title="上传文件" width="38rem" custom-class="hc-modal-border">
+        <HcUpload :fileList="fileListData" :datas="uploadData" @change='uploadChange'/>
+    </el-dialog>
 </template>
 
 <script setup>
-import {ref,watch,nextTick} from "vue";
-import {createApp} from "vue/dist/vue.esm-bundler.js";
-import {useAppStore} from "~src/store/index";
+import {ref,watch,nextTick,onMounted} from "vue";
 import notableform from '~src/assets/view/notableform.svg';
+import {HTableForm} from "~src/plugins/HTableForm"
+import {isString, getObjNullValue, getArrValue} from "vue-utils-plus"
 import wbsApi from "~api/data-fill/wbs"
-import {isString} from "vue-utils-plus"
-import {ElInput,ElDatePicker} from 'element-plus'
+import HcUpload from "./HcUpload.vue"
+import {NDropdown} from 'naive-ui';
 
 //初始
-const useAppState = useAppStore()
 const props = defineProps({
     datas: {
         type: Array,
@@ -107,8 +112,6 @@ const props = defineProps({
     },
 })
 
-//按钮气泡开关
-const bubbleVal = ref(useAppState.getBubble);
 const projectId = ref(props.projectId)
 const contractId = ref(props.contractId)
 const listDatas = ref(props.datas)
@@ -119,128 +122,254 @@ watch(() => [
     props.datas,
     props.projectId,
     props.contractId,
-    useAppState.getBubble,
     props.classify,
-], ([datas, pid, cid, Bubble,classifyVal]) => {
+], ([datas, pid, cid,classifyVal]) => {
     listDatas.value = datas
-    bubbleVal.value = Bubble
     projectId.value = pid
     contractId.value = cid
     classify.value = classifyVal
-    //setFormDataNum(datas)
+    setFormDataNum(datas)
 })
 
-//获取气泡数据
-const getButtonsVal = (value) => {
-    return useAppState.getButtonsVal(value)
-}
-
-const btn_copy_table = ref(getButtonsVal('wbs_copy_table')) //复制本表
-const btn_hide_table = ref(getButtonsVal('wbs_hide_table')) //隐藏本表
-const btn_pre_table = ref(getButtonsVal('wbs_preview_table')) //预览本表
-const btn_up_table = ref(getButtonsVal('wbs_upload_table')) //上传
-const btn_del_table = ref(getButtonsVal('wbs_del_table')) //删除
-
-const btn_down_table = ref(getButtonsVal('wbs_download_table')) //下载导入模板
-const btn_impo_table = ref(getButtonsVal('wbs_import_table')) //导入列表数据
-const btn_save_table = ref(getButtonsVal('wbs_save_table'))//保存本表
-
-//事件
-const emit = defineEmits(['uploadTap','itemTap','copyTap','hideTap','previewTap','offsetTop'])
-
+//渲染完成
 nextTick(() => {
-    //setFormDataNum(props.datas)
+    setFormDataNum(props.datas)
 })
 
-const activeName = ref('')
+//获取表单初始数据
+const getFormDataInit = (pkeyId) => {
+    return {
+        projectId: projectId.value,
+        contractId: contractId.value,
+        classify: classify.value,
+        pkeyId: pkeyId + '',
+    }
+}
 
+//设置表单对象的数量
+const formData = ref([])
+const setFormDataNum = (datas) => {
+    let newArr = [];
+    for (let i = 0; i < datas.length; i++) {
+        newArr.push(getFormDataInit(datas[i].pkeyId + ''))
+    }
+    formData.value = newArr
+}
 
 //展开事件
-const updateExpandedNames = (name) => {
-    const keys = name.length > 0 ? name[0]:'';
-    const names = name.length > 0 ? name[0].split('-'): []
+const ActiveKey = ref('')
+const CollapseChange = (name) => {
+    ActiveKey.value = name
+    const names = name ? name.split('-') : []
     if (names.length > 0) {
-        getOffsetTop(keys)
+        getOffsetTop(name)
         const index = names[1]
         const item = listDatas.value[index]
         if (!item.isTableFormRender) {
+            //渲染表单
             getExcelHtml(item,index)
+            //获取已填写的数据
+            const pkeyId = item.pkeyId || ''
+            getBussDataInfo(pkeyId + '', index)
         }
     } else {
-        emit('offsetTop', {offsetTop: 0, dom: null})
+        getOffsetTop()
     }
 }
 
 //获取模板标签数据
-const getExcelHtml = (item,index) => {
-    if (item.pkeyId !== 0) {
-        wbsApi.getExcelHtml({
-            pkeyId: item.pkeyId + ''
-        }).then(({data}) => {
-            const res = isString(data.data)?data.data:''
-            if (res) {
-                item.isTableForm = true
-                HTableForm(res, item, index)
-            } else {
-                item.isTableForm = false
-                window?.$message?.warning('清表内容是空的')
-            }
-        }).catch(() => {
+const getExcelHtml = async (item,index) => {
+    const pkeyId = item.pkeyId || ''
+    if (pkeyId) {
+        const { data } = await wbsApi.getExcelHtml({pkeyId: pkeyId + ''})
+        const resData = isString(data?.data) ? data?.data : ''
+        if (resData) {
+            item.isTableForm = true
+            //渲染表单
+            HTableForm({
+                template: resData,
+                formData: formData.value[index],
+                appId: `#table-form-${pkeyId}`,
+                onRight: (event, KeyName) => {
+                    onRightClick(event, KeyName, index)
+                }
+            })
+            item.isTableFormRender = true
+        } else {
             item.isTableForm = false
-        })
+            window?.$Elmessage?.warning('暂无表单')
+        }
     } else {
         item.isTableForm = false
-        window?.$message?.warning('pkeyId为空')
+        window?.$Elmessage?.warning('pkeyId为空')
     }
 }
 
-//渲染模板标签
-const formData = ref([])
+//获取已填写的数据
+const getBussDataInfo = async (pkeyId, index) => {
+    const { data } = await wbsApi.getBussDataInfo({pkeyId: pkeyId})
+    const resData = getObjNullValue(data?.data)
+    if (resData) {
+        //有数据,关联数据
+        const InitObj = getFormDataInit(pkeyId)
+        formData.value[index] = { ...InitObj, ...resData }
+    } else {
+        formData.value[index] = getFormDataInit(pkeyId)
+    }
+}
 
-//设置表单对象的数量
-const setFormDataNum = (datas) => {
-    if(datas.length > 0) {
-        datas.forEach(item => {
-            formData.value.push({
-                projectId: projectId.value,
-                contractId: contractId.value
-            })
-        })
+//单个保存
+const tableFormSaveClick = async (item,index) => {
+    const res = await saveExcelBussData(item,index)
+    if (res) {
+        await getBussPdfInfo(item)
+        renewData()
     }
 }
 
-//渲染表格表单
-const HTableForm = (templateData,item,index) => {
-    const app = createApp({
-        data() {
-            return {
-                formData: formData.value[index],
+//保存表单数据
+const saveExcelBussData = async (item, index, showTip = true) => {
+    const { data } = await wbsApi.saveExcelBussData({
+        pkeyId: item.pkeyId + '',
+        classify: classify.value,
+        ...formData.value[index]
+    })
+    if(data && data.code === 200) {
+        if(showTip) {
+            window?.$Elmessage?.success('保存成功')
+        }
+        return true
+    } else {
+        if(showTip) {
+            window?.$Elmessage?.warning(data.msg || '保存失败')
+        }
+        return false
+    }
+}
+
+//预览PDF
+const getBussPdfInfo = async (item, showTip = true) => {
+    const { data } = await wbsApi.getBussPdfInfo({
+        pkeyId: item.pkeyId + ''
+    })
+    if(data && data.code === 200) {
+        const url = data?.data || ''
+        if (url) {
+            window.open(url, '_blank')
+        } else {
+            if(showTip) {
+                window?.$Elmessage?.warning('PDF错误')
             }
-        },
-        template: templateData,
-        components: {ElInput,ElDatePicker},
-        methods: {
-            RightClick(a,b,c,d,e,f,event) {
-                event.preventDefault();
-                const key = event?.target?.getAttribute('keyname') || ''
-                onRightClick(event,key,index)
-            },
-            getInformation(a,b,c) {
-
-            },
         }
+    } else {
+        if(showTip) {
+            window?.$Elmessage?.warning('暂无PDF')
+        }
+    }
+}
+
+//删除本表
+const delClick = async (item) => {
+    const { data } = await wbsApi.removeBussTabInfo({
+        pkeyid: item.pkeyId + '',
+        classify: classify.value,
     })
-    app.mount(`#table-form-${item.pkeyId}`)
-    item.isTableFormRender = true
+    if(data && data.code === 200) {
+        window?.$Elmessage?.warning('操作成功')
+        renewData()
+    } else {
+        window?.$Elmessage?.warning('操作失败')
+    }
 }
 
-//树的菜单相关变量
-const tableFormMenuShow = ref(false)
+//复制本表
+const copyClick = async (item,index) => {
+    const res = await saveExcelBussData(item,index,false)
+    if (res) {
+        const { data } = await wbsApi.copeBussTab({pkeyId: item.pkeyId + ''})
+        if(data && data.code === 200) {
+            window?.$Elmessage?.success('操作成功')
+            renewData()
+        } else {
+            window?.$Elmessage?.warning('操作失败')
+        }
+    } else {
+        window?.$Elmessage?.warning('复制本表操作失败')
+    }
+}
+
+//隐藏本表
+const hideClick = async (item) => {
+    const isBussShow = item?.isBussShow === 2 ? 1 : 2 //状态(1显示 2隐藏)
+    const { data } = await wbsApi.showBussTab({
+        pkeyId: item.pkeyId + '',
+        status: isBussShow
+    })
+    if(data && data.code === 200) {
+        window?.$Elmessage?.success('操作成功')
+        renewData()
+    } else {
+        window?.$Elmessage?.warning('操作失败')
+    }
+}
+
+//预览
+const previewClick = async (item,index) => {
+    const res = await saveExcelBussData(item, index, false)
+    if (res) {
+        await getBussPdfInfo(item)
+        renewData()
+    } else {
+        window?.$Elmessage?.warning('操作失败')
+    }
+}
+
+//上传变量
+const uploadModal = ref(false)
+const fileListData = ref([]);
+const uploadData = ref({})
+
+//上传被点击
+const uploadClick = (item) => {
+    uploadModal.value = true
+    uploadData.value = getFormDataInit(item.pkeyId + '')
+    //获取文件列表
+    getBussFileList(item.pkeyId + '')
+}
+
+//获取文件列表
+const getBussFileList = async (pkeyId) => {
+    const { data } = await wbsApi.getBussFileList({
+        pkeyid: pkeyId
+    })
+    if(data && data.code === 200) {
+        fileListData.value = getArrValue(data?.data)
+    } else {
+        fileListData.value = []
+    }
+}
+
+//上传文件
+const uploadChange = async ({type}) => {
+    console.log(type)
+    if(type === 'success') {
+        uploadModal.value = false
+        renewData()
+    } else if (type === 'del') {
+        renewData()
+    }
+}
+
+
+
+
+//相关变量
 const tableFormItemNode = ref({})
+const tableFormMenuShow = ref(false)
 const tableFormMenuX = ref(0);
 const tableFormMenuY = ref(0);
 
-//树的菜单数据
+//菜单数据
 const tableFormMenu = ref([
     {label: '插入设计值/频率', key: "IDVF"},
     {label: '插入特殊字符', key: "special"},
@@ -248,28 +377,30 @@ const tableFormMenu = ref([
 ])
 
 //鼠标右键事件
-const onRightClick = (event,key,index) => {
+const onRightClick = (event, KeyName, index) => {
     //取光标位置
-    let specialDom = document.getElementById(key + "");
-    let startPos = specialDom?.selectionStart, endPos = specialDom?.selectionEnd;
+    const specialDom = document.getElementById(KeyName + "")
+    const startPos = specialDom?.selectionStart || 0
+    const endPos = specialDom?.selectionEnd || 0
     //存储临时信息
-    tableFormItemNode.value = {key, index, startPos, endPos}
-    //取坐标
-    nextTick().then(() => {
+    tableFormItemNode.value = {KeyName, index, startPos, endPos}
+    //取鼠标右键菜单的坐标
+    nextTick(() => {
         tableFormMenuShow.value = true;
         tableFormMenuX.value = event.clientX;
         tableFormMenuY.value = event.clientY;
-    });
+    })
 }
 
 //鼠标右键菜单被点击
+const IDVFModal = ref(false)
+const formIDVFRef = ref(null)
 const handleMenuSelect = (key) => {
-    //const item = tableFormItemNode.value;
     tableFormMenuShow.value = false;
     if (key === 'IDVF') {
         IDVFModal.value = true
     } else if (key === 'special') {
-        specialModalShow()
+        //specialModalShow()
     } else if (key === 'CTD') {
         CTDModal.value = true
     }
@@ -280,150 +411,23 @@ const onClickoutside = () => {
     tableFormMenuShow.value = false;
 }
 
-//单个保存
-const tableFormSaveClick = (item,index) => {
-    wbsApi.saveExcelBussData({
-        pkeyId: item.pkeyId,
-        classify: classify.value,
-        ...formData.value[index]
-    }).then(({data}) => {
-        if(data.code === 200) {
-            window?.$message?.success('保存成功')
-        } else {
-            window?.$message?.warning(data.msg || '保存失败')
-        }
-    })
-}
-
-//删除本表
-const delClick = (item,index) => {
-    wbsApi.removeBussTabInfo({
-        pkeyid: item.pkeyId,
-        classify: classify.value,
-    }).then(({data}) => {
-        if(data.code === 200) {
-            window?.$message?.success('操作成功')
-            emit('uploadData')
-            emit('delTap', {item,index})
-        } else {
-            window?.$message?.warning(data.msg || '操作失败')
-        }
-    })
-}
-
-//复制本表
-const copyClick = (item,index) => {
-    emit('copyTap', {item,index})
-}
-//隐藏本表
-const hideClick = (item,index) => {
-    emit('hideTap', {item,index})
-}
-//预览
-const previewClick = (item,index) => {
-    emit('previewTap', {item,index})
-}
-//上传被点击
-const uploadClick = (item,index) => {
-    emit('uploadTap', {item,index})
-}
-
-//上传被点击
-const getOffsetTop = (key) => {
-    const dom = document.getElementById(key)
-    emit('offsetTop', dom.offsetTop)
-}
-
-//插入设计值/频率
-const IDVFModal = ref(false)
-const formIDVFRef = ref(null)
-const formIDVFModel = ref({
-    designValue: '', frequency: ''
-})
-const formIDVFRules = {
-    designValue: {
-        required: true,
-        trigger: ["blur", "input"],
-        message: "请输入设计值"
-    },
-    frequency: {
-        required: true,
-        trigger: ["blur", "input"],
-        message: "请输入频率"
-    }
-}
-
-//插入特殊字符
-const specialModal = ref(false)
-const specialCharacters = ref([
-    '&#57344;', "&#57345;", "&#57346;", "&#57347;", '&#8804;', '&#8805;', '&#8451;',
-    '&#9312;', '&#9313;', '&#9314;', '&#9315;', '&#9316;', '&#9317;', '&#9318;', '&#9319;', '&#9320;', '&#9321;', '&#9322;', '&#9323;',
-    '&#9324;', '&#9325;', '&#9326;', '&#9327;', '&#9328;', '&#9329;', '&#9330;', '&#9331;',
-    "&#8544;", "&#8545;", "&#8546;", "&#8547;", "&#8548;", "&#8549;", "&#8550;", "&#8551;", "&#8552;", "&#8553;", "&#8554;", "&#8555;","K̅"
-])
-const specialRef = ref(null)
-const specialValue = ref('')
-const specialModalShow = () => {
-    specialValue.value = ''
-    specialModal.value = true
-    nextTick(() => {
-        specialRef.value?.focus();
-    })
-}
-const specialClick = (event) => {
-    inputInsertValue("specialId", event.target.innerText)
-}
-//输入框插入内容
-const inputInsertValue = (Id,val) => {
-    let specialDom = document.getElementById(Id + "").getElementsByTagName('input')[0];
-    let startPos = specialDom?.selectionStart, endPos = specialDom?.selectionEnd;
-    if (startPos || startPos === 0) {
-        let specialVal = specialValue.value;
-        specialValue.value = specialVal.substring(0, startPos) + val + specialVal.substring(endPos, specialVal.length)
-        specialDom?.focus();
-        //设置光标位置
-        let posVal = startPos + val.length;
-        nextTick(() => {
-            specialDom?.setSelectionRange(posVal,posVal)
-        })
-    } else {
-        specialValue.value += val;
-        specialDom?.focus();
-    }
-}
+//事件
+const emit = defineEmits(['renew','offsetTop'])
 
-//插入内容
-const inputPosInsert = (dom,startPos,endPos,special,value) => {
-    let val = value || '', specialVal = special || ''
-    console.log(startPos,endPos)
-    if (startPos || startPos === 0) {
-        val = val.substring(0, startPos) + specialVal + val.substring(endPos, val.length)
-        dom?.focus();
-        //设置光标位置
-        let posVal = startPos + specialVal.length;
-        nextTick(() => {
-            dom?.setSelectionRange(posVal,posVal)
-        })
+//被点击
+const getOffsetTop = (key = '') => {
+    if (key) {
+        const dom = document.getElementById(key)
+        emit('offsetTop', dom.offsetTop)
     } else {
-        val += specialVal;
-        dom?.focus();
+        emit('offsetTop', 0)
     }
-    return val
 }
 
-//确认插入
-const specialNodeClick = () => {
-    const item = tableFormItemNode.value;
-    const form = formData.value[item.index]
-    let keyDom = document.getElementById(item.key);
-    const res = inputPosInsert(keyDom,item.startPos,item.endPos,specialValue.value,form[item.key])
-    formData.value[item.index][item.key] = res
-    specialModal.value = false
+//通知数据更新
+const renewData = () => {
+    emit('renew')
 }
-
-//关联试验数据
-const CTDModal = ref(false)
-
 </script>
 
 <style lang="scss" scoped>

+ 0 - 839
src/views/data-fill/components/ListItem_bak.vue

@@ -1,839 +0,0 @@
-<template>
-    <div class="data-fill-list-box">
-        <n-collapse accordion :expanded-names="expandedNames" @update:expanded-names="updateExpandedNames">
-            <template v-for="(item,index) in listDatas" :key="item?.pkeyId">
-                <n-collapse-item display-directive="show" :id="`item-${index}-${item?.pkeyId}`" :name="`item-${index}-${item?.pkeyId}`">
-                    <template #header>
-                        <div class="text-lg truncate item-title">{{item.name}}</div>
-                    </template>
-                    <template #header-extra>
-                        <div class="flex items-center hc-extra-text-box">
-                            <n-popover trigger="hover" :disabled="!bubbleVal || !btn_del_table?.textInfo" v-if="btn_del_table && item?.isCopeTab === 2">
-                                <template #trigger>
-                                    <div class="mr-8 text-main extra-text-item" @click.stop="delClick(item,index)">
-                                        <i class="hcicon-a-Frame3"/>
-                                        <span class="ml-1">删除本表</span>
-                                    </div>
-                                </template>
-                                <span>{{btn_del_table?.textInfo}}</span>
-                            </n-popover>
-                            <n-popover trigger="hover" :disabled="!bubbleVal || !btn_copy_table?.textInfo" v-if="btn_copy_table">
-                                <template #trigger>
-                                    <div class="text-gray-400 extra-text-item" v-if="item?.isBussShow == 2" @click.stop>
-                                        <i class="hcicon-a-Frame3"/>
-                                        <span class="ml-1">复制本表</span>
-                                    </div>
-                                    <div class="text-main extra-text-item" v-else @click.stop="copyClick(item,index)">
-                                        <i class="hcicon-a-Frame3"/>
-                                        <span class="ml-1">复制本表</span>
-                                    </div>
-                                </template>
-                                <span>{{btn_copy_table?.textInfo}}</span>
-                            </n-popover>
-                            <n-popover trigger="hover" :disabled="!bubbleVal || !btn_hide_table?.textInfo" v-if="btn_hide_table">
-                                <template #trigger>
-                                    <div class="ml-8 text-main extra-text-item" @click.stop="hideClick(item,index)">
-                                        <template v-if="item?.isBussShow == 1">
-                                            <i class="hcicon-a-Frame4"/>
-                                            <span class="ml-1">隐藏本表</span>
-                                        </template>
-                                        <template v-else>
-                                            <i class="hcicon-zhengkaiyanjing4"/>
-                                            <span class="ml-1">显示本表</span>
-                                        </template>
-                                    </div>
-                                </template>
-                                <span>{{btn_hide_table?.textInfo}}</span>
-                            </n-popover>
-                            <n-popover trigger="hover" :disabled="!bubbleVal || !btn_pre_table?.textInfo" v-if="btn_pre_table">
-                                <template #trigger>
-                                    <div class="ml-8 text-gray-400 extra-text-item" v-if="item?.isBussShow == 2 || item?.isTabPdf === 1" @click.stop>
-                                        <i class="hcicon-Frame"/>
-                                        <span class="ml-1">预览</span>
-                                    </div>
-                                    <div class="ml-8 text-main extra-text-item" v-else @click.stop="previewClick(item,index)">
-                                        <i class="hcicon-Frame"/>
-                                        <span class="ml-1">预览</span>
-                                    </div>
-                                </template>
-                                <span>{{btn_pre_table?.textInfo}}</span>
-                            </n-popover>
-                            <n-popover trigger="hover" :disabled="!bubbleVal || !btn_up_table?.textInfo" v-if="btn_up_table">
-                                <template #trigger>
-                                    <div class="ml-8 text-gray-400 extra-text-item" v-if="item?.isBussShow == 2" @click.stop>
-                                        <i class="hcicon-shangchuan"/>
-                                        <span class="ml-1">上传</span>
-                                    </div>
-                                    <div class="ml-8 extra-text-item" :class="item?.tabFileType === 2?'text-green':'text-main'" v-else @click.stop="uploadClick(item,index)">
-                                        <i class="hcicon-shangchuan"/>
-                                        <span class="ml-1">{{item?.tabFileType === 2?'已上传':'上传' }}</span>
-                                    </div>
-                                </template>
-                                <span>{{btn_up_table?.textInfo}}</span>
-                            </n-popover>
-                        </div>
-                    </template>
-                    <div class="data-fill-list-item-content">
-                        <div class="data-fill-table-form-box">
-                            <div :id="`table-form-${item?.pkeyId}`"></div>
-                            <div class="hc-no-table-form" v-if="item?.isTableForm === false">
-                                <div class="table-form-no">
-                                    <img :src="notableform" alt=""/>
-                                    <div class="desc">暂无表单数据</div>
-                                </div>
-                            </div>
-                        </div>
-                        <div class="data-fill-table-tip-box">
-                            <div class="text-orange tip-title">
-                                <i class="_icon-info-o"/>
-                                <span class="ml-1">提示</span>
-                            </div>
-                            <div class="text-gray-400 tip-item">1、灰色框代表可通过系统识别计算,公式自动引用,可通过公式计算少量数据,(表头数据及简单),也可只填写白色框数据</div>
-                            <div class="text-gray-400 tip-item">2、系统支持键盘中,shift + tab键向上一个填报框切换,tab向下一个填报框切换。暂不支持上下按键切换输入框</div>
-                            <div class="table-tip-foot">
-                                <div class="tip-left-btn">
-                                    <n-popover trigger="hover" :disabled="!bubbleVal || !btn_impo_table?.textInfo" v-if="btn_impo_table">
-                                        <template #trigger>
-                                            <div class="text-gray-400 dow-text">
-                                                <i class="hcicon-Frame1"/>
-                                                <span class="ml-1">导入列表数据</span>
-                                            </div>
-                                        </template>
-                                        <span>{{btn_impo_table?.textInfo}}</span>
-                                    </n-popover>
-                                    <n-popover trigger="hover" :disabled="!bubbleVal || !btn_down_table?.textInfo" v-if="btn_down_table">
-                                        <template #trigger>
-                                            <div class="text-main dow-text">
-                                                <i class="hcicon-a-Frame11"/>
-                                                <span class="ml-1">下载导入模板</span>
-                                            </div>
-                                        </template>
-                                        <span>{{btn_down_table?.textInfo}}</span>
-                                    </n-popover>
-                                </div>
-                                <div class="tip-right-btn">
-                                    <n-popover trigger="hover" :disabled="!bubbleVal || !btn_save_table?.textInfo" v-if="btn_save_table">
-                                        <template #trigger>
-                                            <n-button type="primary" strong secondary size="large" @click="tableFormSaveClick(item,index)">保存</n-button>
-                                        </template>
-                                        <span>{{btn_save_table?.textInfo}}</span>
-                                    </n-popover>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </n-collapse-item>
-            </template>
-        </n-collapse>
-    </div>
-    <!--鼠标右键菜单-->
-    <n-dropdown placement="bottom" inverted trigger="manual" :x="tableFormMenuX" :y="tableFormMenuY" size="huge" :options="tableFormMenu" :show="tableFormMenuShow" @clickoutside="onClickoutside" @select="handleMenuSelect"/>
-    <!--插入设计值/频率-->
-    <n-modal v-model:show="IDVFModal" class="hc-custom-card" title="插入设计值/频率" preset="card" style="width: 600px;" :segmented="{content: 'soft', footer: 'soft'}">
-        <div class="text-base mb-6 ml-16 pl-1">填写完设计值和频率,系统自动计算实测值</div>
-        <n-form ref="formIDVFRef" :model="formIDVFModel" :rules="formIDVFRules" label-placement="left" label-width="auto" size="large">
-            <n-form-item label="设计值" path="designValue">
-                <n-input v-model:value="formIDVFModel.designValue" placeholder="请输入设计值"/>
-            </n-form-item>
-            <n-form-item label="频率" path="frequency">
-                <n-input v-model:value="formIDVFModel.frequency" placeholder="请输入频率"/>
-            </n-form-item>
-        </n-form>
-        <template #footer>
-            <div class="text-center">
-                <n-button @click="IDVFModal = false">取消</n-button>
-                <n-button type="primary" class="ml-6">确认插入</n-button>
-            </div>
-        </template>
-    </n-modal>
-    <!--插入特殊字符-->
-    <n-modal v-model:show="specialModal" class="hc-custom-card" title="插入特殊字符" preset="card" style="width: 600px;" :segmented="{content: 'soft', footer: 'soft'}">
-        <n-input ref="specialRef" id="specialId" class="font-EUDC mb-6" v-model:value="specialValue" size="large" placeholder="请选择特殊字符代码" clearable autofocus/>
-        <n-grid :x-gap="10" :y-gap="10" :cols="8">
-            <n-grid-item v-for="item in specialCharacters" :key="item">
-                <div class="special-box" @click="specialClick">
-                    <span class="font-EUDC" :title="`字符代码(C):${item !== 'K̅'?item.slice(2,7):'K̅'}`" v-html="item"/>
-                </div>
-            </n-grid-item>
-        </n-grid>
-        <template #footer>
-            <div class="text-center">
-                <n-button @click="specialModal = false">取消</n-button>
-                <n-button type="primary" class="ml-6" @click="specialNodeClick">确认插入</n-button>
-            </div>
-        </template>
-    </n-modal>
-    <!--关联试验数据-->
-    <n-modal v-model:show="CTDModal" class="hc-custom-card" title="关联试验数据" preset="card" style="width: 850px;" :segmented="{content: 'soft', footer: 'soft'}">
-        123456
-        <template #footer>
-            <div class="text-center">
-                <n-button @click="CTDModal = false">取消</n-button>
-                <n-button type="primary" class="ml-6">确认插入</n-button>
-            </div>
-        </template>
-    </n-modal>
-    <!--上传文件-->
-    <n-modal v-model:show="uploadModal" class="hc-custom-card w-606" title="上传文件" preset="card" :segmented="{content: 'soft', footer: 'soft'}">
-        <n-upload v-model:file-list="fileListData" :action="action" :headers="getTokenHeader()" :data="addData" :accept="accept" multiple @before-upload="beforeUpload" @finish="uploadFinish" @change="UploadChange" @remove="delUploadData"  @update:file-list="fileListUpdate">
-            <n-button type="primary">选择文件并上传</n-button>
-        </n-upload>
-    </n-modal>
-</template>
-
-<script setup>
-import {ref,watch,nextTick} from "vue";
-import {useAppStore} from "~src/store/index";
-import wbsApi from "~api/data-fill/wbs"
-import {ElInput,ElDatePicker} from 'element-plus'
-import {createApp} from "vue/dist/vue.esm-bundler.js";
-import {isString,isObject} from "~src/utils/lib/isApp";
-import notableform from '~src/assets/view/notableform.svg';
-import {isObjNull} from "../../utils/lib/isApp";
-import {getTokenHeader} from '~src/api/request/header';
-
-//初始
-const useAppState = useAppStore()
-const props = defineProps({
-    datas: {
-        type: Array,
-        default: () => ([])
-    },
-    projectId: {
-        type: [String,Number],
-        default: ''
-    },
-    contractId: {
-        type: [String,Number],
-        default: ''
-    },
-    classify: {
-        type: [String,Number],
-        default: ''
-    },
-})
-
-//按钮气泡开关
-const bubbleVal = ref(useAppState.getBubble);
-const projectId = ref(props.projectId)
-const contractId = ref(props.contractId)
-const listDatas = ref(props.datas)
-const classify = ref(props.classify)
-const expandedNames = ref(null)
-
-//监听
-watch(() => [
-    props.datas,
-    props.projectId,
-    props.contractId,
-    useAppState.getBubble,
-    props.classify,
-], ([datas, pid, cid, Bubble,classifyVal]) => {
-    listDatas.value = datas
-    bubbleVal.value = Bubble
-    projectId.value = pid
-    contractId.value = cid
-    classify.value = classifyVal
-    expandedNames.value = null
-    setFormDataNum(datas)
-})
-
-//获取气泡数据
-const getButtonsVal = (value) => {
-    return useAppState.getButtonsVal(value)
-}
-
-const btn_copy_table = ref(getButtonsVal('wbs_copy_table')) //复制本表
-const btn_hide_table = ref(getButtonsVal('wbs_hide_table')) //隐藏本表
-const btn_pre_table = ref(getButtonsVal('wbs_preview_table')) //预览本表
-const btn_up_table = ref(getButtonsVal('wbs_upload_table')) //上传
-const btn_del_table = ref(getButtonsVal('wbs_del_table')) //删除
-
-const btn_down_table = ref(getButtonsVal('wbs_download_table')) //下载导入模板
-const btn_impo_table = ref(getButtonsVal('wbs_import_table')) //导入列表数据
-const btn_save_table = ref(getButtonsVal('wbs_save_table'))//保存本表
-
-//事件
-const emit = defineEmits(['uploadData','uploadTap','saveTap','itemTap','copyTap','hideTap','previewTap','offsetTop', 'delTap'])
-
-nextTick(() => {
-    setFormDataNum(props.datas)
-})
-
-//渲染模板标签
-const formData = ref([])
-
-//展开事件
-const updateExpandedNames = async (name) => {
-    expandedNames.value = name
-    const keys = name.length > 0 ? name[0]:'';
-    const names = name.length > 0 ? name[0].split('-'): []
-    if (names.length > 0) {
-        getOffsetTop(keys)
-        const index = names[1]
-        const item = listDatas.value[index]
-        if (!item.isTableFormRender) {
-            getExcelHtml(item,index)
-        }
-        //获取已填写的数据
-        const {data: valData} = await wbsApi.getBussDataInfo({pkeyId: item.pkeyId + ''})
-        const valRes = isObject(valData.data) ? valData.data : {}
-        if (!isObjNull(valRes)) {
-            //有数据,关联数据
-            formData.value[index] = {
-                projectId: projectId.value,
-                contractId: contractId.value,
-                pkeyId: item.pkeyId + '',
-                classify: classify.value,
-                ...valRes
-            }
-        } else {
-            formData.value[index] = {
-                projectId: projectId.value,
-                contractId: contractId.value,
-                pkeyId: item.pkeyId + '',
-                classify: classify.value
-            }
-        }
-    } else {
-        emit('offsetTop', {offsetTop: 0, dom: null})
-    }
-}
-
-//获取模板标签数据
-const getExcelHtml = (item,index) => {
-    if (item.pkeyId !== 0) {
-        wbsApi.getExcelHtml({
-            pkeyId: item.pkeyId + ''
-        }).then(({data}) => {
-            const res = isString(data.data)?data.data:''
-            if (res) {
-                item.isTableForm = true
-                HTableForm(res, item, index)
-            } else {
-                item.isTableForm = false
-                window?.$message?.warning(res.msg || '暂无表单')
-            }
-        }).catch(() => {
-            item.isTableForm = false
-        })
-    } else {
-        item.isTableForm = false
-        window?.$message?.warning('pkeyId为空')
-    }
-}
-
-//设置表单对象的数量
-const setFormDataNum = (datas) => {
-    let newArr = [];
-    for (let i = 0; i < datas.length; i++) {
-        newArr.push({
-            projectId: projectId.value,
-            contractId: contractId.value,
-            pkeyId: datas[i].pkeyId + '',
-            classify: classify.value
-        })
-    }
-    formData.value = newArr
-}
-
-//渲染表格表单
-const HTableForm = (templateData,item,index) => {
-    const app = createApp({
-        data() {
-            return {
-                formData: formData.value[index],
-            }
-        },
-        template: templateData,
-        components: {ElInput,ElDatePicker},
-        methods: {
-            RightClick(a,b,c,d,e,f,event) {
-                event.preventDefault();
-                const key = event?.target?.getAttribute('keyname') || ''
-                onRightClick(event,key,index)
-            },
-            getInformation(a,b,c) {
-
-            },
-        }
-    })
-    app.mount(`#table-form-${item.pkeyId}`)
-    item.isTableFormRender = true
-}
-
-//树的菜单相关变量
-const tableFormMenuShow = ref(false)
-const tableFormItemNode = ref({})
-const tableFormMenuX = ref(0);
-const tableFormMenuY = ref(0);
-
-//树的菜单数据
-const tableFormMenu = ref([
-    {label: '插入设计值/频率', key: "IDVF"},
-    {label: '插入特殊字符', key: "special"},
-    {label: '关联试验数据', key: "CTD"},
-])
-
-//鼠标右键事件
-const onRightClick = (event,key,index) => {
-    //取光标位置
-    let specialDom = document.getElementById(key + "");
-    let startPos = specialDom?.selectionStart, endPos = specialDom?.selectionEnd;
-    //存储临时信息
-    tableFormItemNode.value = {key, index, startPos, endPos}
-    //取坐标
-    nextTick().then(() => {
-        tableFormMenuShow.value = true;
-        tableFormMenuX.value = event.clientX;
-        tableFormMenuY.value = event.clientY;
-    });
-}
-
-//鼠标右键菜单被点击
-const handleMenuSelect = (key) => {
-    //const item = tableFormItemNode.value;
-    tableFormMenuShow.value = false;
-    if (key === 'IDVF') {
-        IDVFModal.value = true
-    } else if (key === 'special') {
-        specialModalShow()
-    } else if (key === 'CTD') {
-        CTDModal.value = true
-    }
-}
-
-const onClickoutside = () => {
-    tableFormItemNode.value = {};
-    tableFormMenuShow.value = false;
-}
-
-const saveExcelBussData = async (item,index) => {
-    const {data} = await wbsApi.saveExcelBussData({
-        pkeyId: item.pkeyId,
-        classify: classify.value,
-        ...formData.value[index]
-    })
-    if(data && data.code === 200) {
-        window?.$message?.success('保存成功')
-        return true
-    } else {
-        window?.$message?.warning(data.msg || '保存失败')
-        return false
-    }
-}
-
-//单个保存
-const tableFormSaveClick = async (item,index) => {
-    const res = await saveExcelBussData(item,index)
-    if (res) {
-        getBussPdfInfo(item,index)
-        emit('uploadData')
-        emit('saveTap', {item,index})
-    }
-}
-
-//删除本表
-const delClick = (item,index) => {
-    wbsApi.removeBussTabInfo({
-        pkeyid: item.pkeyId,
-        classify: classify.value,
-    }).then(({data}) => {
-        if(data.code === 200) {
-            window?.$message?.success('操作成功')
-            emit('uploadData')
-            emit('delTap', {item,index})
-        } else {
-            window?.$message?.warning(data.msg || '操作失败')
-        }
-    })
-}
-
-//复制本表
-const copyClick = async (item,index) => {
-    const res = await saveExcelBussData(item,index)
-    if (res) {
-        const {data} = await wbsApi.copeBussTab({pkeyId: item.pkeyId})
-        if(data && data.code === 200) {
-            window?.$message?.success('操作成功')
-            emit('uploadData')
-            emit('copyTap', {item,index})
-        } else {
-            window?.$message?.warning(data.msg || '操作失败')
-        }
-    } else {
-        window?.$message?.warning('复制本表操作失败')
-    }
-}
-
-//隐藏本表
-const hideClick = (item,index) => {
-    //状态(1显示 2隐藏)
-    const isBussShow = item?.isBussShow == 2 ? 1 : 2
-    //发起请求
-    wbsApi.showBussTab({
-        pkeyId: item.pkeyId,
-        status: isBussShow
-    }).then(({data}) => {
-        if(data.code === 200) {
-            window?.$message?.success('操作成功')
-            emit('uploadData')
-            emit('hideTap', {item,index})
-        } else {
-            window?.$message?.warning(data.msg || '操作失败')
-        }
-    })
-}
-
-const getBussPdfInfo = (item,index) => {
-    wbsApi.getBussPdfInfo({
-        pkeyId: item.pkeyId
-    }).then(({data}) => {
-        if(data.code === 200 && data?.data) {
-            window.open(data?.data,'_blank')
-            emit('previewTap', {item,index})
-        } else {
-            window.$message?.warning('暂无PDF')
-        }
-    })
-}
-
-//预览
-const previewClick = async (item,index) => {
-    const res = await saveExcelBussData(item,index)
-    if (res) {
-        getBussPdfInfo(item,index)
-    } else {
-        window?.$message?.warning('操作失败')
-    }
-}
-
-//上传被点击
-const uploadModal = ref(false)
-const addData = ref({})
-const uploadClick = (item) => {
-    addData.value = {
-        projectId: projectId.value,
-        contractId: contractId.value,
-        classify: classify.value,
-        pkeyId: item.pkeyId
-    }
-    uploadModal.value = true
-    //获取文件列表
-    wbsApi.getBussFileList({
-        pkeyid: item.pkeyId
-    }).then(({data}) => {
-        if(data.code === 200) {
-            fileListData.value = isObjNull(data?.data) ? [] : data?.data
-        } else {
-            fileListData.value = []
-        }
-    }).catch(() => {
-        fileListData.value = []
-    })
-}
-//上传组件参数
-const action = '/api/blade-manager/exceltab/add-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([]);
-//上传前
-const uploadLoading = ref(false)
-const beforeUpload = async ({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 {
-        uploadLoading.value = true
-        return true;
-    }
-}
-//上传完成
-const uploadFinish = ({file,event}) => {
-    uploadLoading.value = false
-    let res = JSON.parse(event?.target?.response);
-    if (res.code === 200) {
-        window.$message?.success('上传成功');
-        uploadModal.value = false
-        emit('uploadData')
-        emit('uploadTap')
-    } else {
-        window.$message?.error('上传失败');
-    }
-}
-
-//列表改变
-const UploadChange = (data) => {
-    fileListData.value = data.fileList;
-}
-const fileListUpdate = (data) => {
-    fileListData.value = data
-}
-//删除
-const delUploadData = async ({file}) => {
-    const {data} = await wbsApi.removeBussFile({ids: file?.id})
-    if(data && data.code === 200) {
-        window.$message?.success('删除成功');
-        emit('uploadData')
-        return true
-    } else {
-        return false
-    }
-}
-
-//被点击
-const getOffsetTop = (key) => {
-    const dom = document.getElementById(key)
-    emit('offsetTop', dom.offsetTop)
-}
-
-//插入设计值/频率
-const IDVFModal = ref(false)
-const formIDVFRef = ref(null)
-const formIDVFModel = ref({
-    designValue: '', frequency: ''
-})
-const formIDVFRules = {
-    designValue: {
-        required: true,
-        trigger: ["blur", "input"],
-        message: "请输入设计值"
-    },
-    frequency: {
-        required: true,
-        trigger: ["blur", "input"],
-        message: "请输入频率"
-    }
-}
-
-//插入特殊字符
-const specialModal = ref(false)
-const specialCharacters = ref([
-    '&#57344;', "&#57345;", "&#57346;", "&#57347;", '&#8804;', '&#8805;', '&#8451;',
-    '&#9312;', '&#9313;', '&#9314;', '&#9315;', '&#9316;', '&#9317;', '&#9318;', '&#9319;', '&#9320;', '&#9321;', '&#9322;', '&#9323;',
-    '&#9324;', '&#9325;', '&#9326;', '&#9327;', '&#9328;', '&#9329;', '&#9330;', '&#9331;',
-    "&#8544;", "&#8545;", "&#8546;", "&#8547;", "&#8548;", "&#8549;", "&#8550;", "&#8551;", "&#8552;", "&#8553;", "&#8554;", "&#8555;","K̅"
-])
-const specialRef = ref(null)
-const specialValue = ref('')
-const specialModalShow = () => {
-    specialValue.value = ''
-    specialModal.value = true
-    nextTick(() => {
-        specialRef.value?.focus();
-    })
-}
-const specialClick = (event) => {
-    inputInsertValue("specialId", event.target.innerText)
-}
-//输入框插入内容
-const inputInsertValue = (Id,val) => {
-    let specialDom = document.getElementById(Id + "").getElementsByTagName('input')[0];
-    let startPos = specialDom?.selectionStart, endPos = specialDom?.selectionEnd;
-    if (startPos || startPos === 0) {
-        let specialVal = specialValue.value;
-        specialValue.value = specialVal.substring(0, startPos) + val + specialVal.substring(endPos, specialVal.length)
-        specialDom?.focus();
-        //设置光标位置
-        let posVal = startPos + val.length;
-        nextTick(() => {
-            specialDom?.setSelectionRange(posVal,posVal)
-        })
-    } else {
-        specialValue.value += val;
-        specialDom?.focus();
-    }
-}
-
-//插入内容
-const inputPosInsert = (dom, startPos = 0, endPos = 0, special, value) => {
-    let val = value || '', specialVal = special || ''
-    console.log(startPos,endPos)
-    if(startPos === 0 && endPos === 0) {
-        val = specialVal;
-        dom?.focus();
-    } else if (startPos !== 0 && endPos !== 0) {
-        val = val.substring(0, startPos) + specialVal + val.substring(endPos, val.length)
-        dom?.focus();
-        //设置光标位置
-        let posVal = startPos + specialVal.length;
-        nextTick(() => {
-            dom?.setSelectionRange(posVal,posVal)
-        })
-    } else {
-        val += specialVal;
-        dom?.focus();
-    }
-    return val
-}
-
-//确认插入
-const specialNodeClick = () => {
-    const item = tableFormItemNode.value;
-    const form = formData.value[item.index]
-    let keyDom = document.getElementById(item.key);
-    const res = inputPosInsert(keyDom,item.startPos,item.endPos,specialValue.value,form[item.key])
-    console.log(res)
-    formData.value[item.index][item.key] = res
-    specialModal.value = false
-}
-
-//关联试验数据
-const CTDModal = ref(false)
-
-//获取表单数据
-const getFormData = () => {
-    console.log(formData.value)
-    return formData.value
-}
-
-// 暴露出去
-defineExpose({
-    getFormData
-})
-</script>
-
-<style lang="scss" scoped>
-@import "../../styles/EUDC/index";
-
-.data-fill-list-box {
-    position: relative;
-    .item-title {
-        position: relative;
-        padding-left: 10px;
-        user-select: none;
-    }
-    .hc-extra-text-box .extra-text-item {
-        font-size: 16px;
-        user-select: none;
-    }
-    .data-fill-list-item-content {
-        position: relative;
-        display: flex;
-        .data-fill-table-form-box {
-            position: relative;
-            padding: 24px 20px;
-            height: calc(100vh - 380px);
-            overflow: auto;
-            flex: 1;
-            .hc-no-table-form {
-                position: relative;
-                height: 100%;
-                display: flex;
-                justify-content: center;
-                align-items: center;
-                .table-form-no {
-                    position: relative;
-                    img {
-                        width: 350px;
-                    }
-                    .desc {
-                        text-align: center;
-                        font-size: 20px;
-                        color: #aaa;
-                    }
-                }
-            }
-        }
-        .data-fill-table-tip-box {
-            width: 240px;
-            position: relative;
-            border-left: 1px solid #e4e4e4;
-            padding: 20px 15px 80px;
-            .tip-title {
-                font-size: 16px;
-                margin-bottom: 10px;
-            }
-            .tip-item {
-                margin-bottom: 20px;
-            }
-            .table-tip-foot {
-                position: absolute;
-                bottom: 15px;
-                right: 0;
-                left: 0;
-                display: flex;
-                align-items: center;
-                padding: 0 15px;
-                .tip-left-btn {
-                    flex: 1;
-                    .dow-text {
-                        cursor: pointer;
-                    }
-                }
-            }
-        }
-    }
-}
-.special-box {
-    position: relative;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    border: 1px solid #eee;
-    border-radius: 3px;
-    height: 60px;
-    cursor: default;
-    user-select: none;
-    transition: color .3s, background-color .3s;
-    &:hover {
-        color: var(--hc-primary);
-        background-color: var(--hc-primary-light-1);
-    }
-    .font-EUDC {
-        font-size: 30px;
-        cursor: default;
-    }
-}
-</style>
-
-<style lang="scss">
-.data-fill-list-box {
-    .n-collapse .n-collapse-item {
-        border: 1px solid #ddd;
-        border-radius: 3px;
-        margin: 0 0 15px;
-        background-color: white;
-        .n-collapse-item__header {
-            padding: 0;
-            transition: color .3s var(--n-bezier), background-color .3s;
-            border-radius: 3px 3px 0 0;
-            .n-collapse-item__header-main {
-                padding: 15px 20px;
-            }
-            .n-collapse-item__header-extra {
-                padding-right: 20px;
-            }
-            &.n-collapse-item__header--active {
-                background-color: #F9F9F9;
-                border-bottom: 1px solid #ddd;
-            }
-        }
-        .n-collapse-item__content-wrapper .n-collapse-item__content-inner {
-            padding-top: 0;
-        }
-    }
-}
-//设置表单样式
-.data-fill-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>

+ 7 - 6
src/views/data-fill/wbs.vue

@@ -74,8 +74,8 @@
                     </template>
 
                     <!--清表列表-->
-                    <el-scrollbar>
-                        <ListItem ref="ListItemRef" :datas="ListItemDatas" :projectId="projectId" :contractId="contractId" :classify="authBtnTabKey" @offsetTop="ListItemOffsetTop" @uploadData="getTableDataAll"/>
+                    <el-scrollbar ref="ListItemScrollRef">
+                        <ListItem ref="ListItemRef" :datas="ListItemDatas" :projectId="projectId" :contractId="contractId" :classify="authBtnTabKey" @offsetTop="ListItemOffsetTop" @renew="getTableDataAll"/>
                     </el-scrollbar>
 
                     <!--底部按钮区域-->
@@ -902,15 +902,16 @@ const drawingsClose = (res) => {
     drawingsShow.value = res
 }
 
-//被展开
+//设置滚动条位置
+const ListItemScrollRef = ref(null)
 const ListItemOffsetTop = (offsetTop) => {
     if (offsetTop > 0) {
         const type = wbsTypeTabKey.value || 'map'
         setTimeout(() => {
             if (type === 'map') {
-                document.getElementById('hc-drawer-list-item').scrollTop = offsetTop
+                //document.getElementById('hc-drawer-list-item').scrollTop = offsetTop
             } else if (type === 'tree') {
-                document.getElementById('hc-card-list-item').scrollTop = offsetTop
+                ListItemScrollRef.value?.setScrollTop(offsetTop)
             }
         }, 200)
     }
@@ -934,7 +935,7 @@ const NodeStatus = ref('1')
 const queryNodeStatus = async () => {
     const info = nodeDataInfo.value;
     const {data} = await wbsApi.queryNodeStatus({
-        primaryKeyId:  info?.primaryKeyId || '',
+        primaryKeyId: info['contractIdRelation'] ? info['id'] : info['primaryKeyId'],
         classify: authBtnTabKey.value
     })
     //1 未填报,2待上报,3已上报