el-tabs + 导入简单的excel文件

在vue-element-admin中导入excel的基础上,利用el-tabs + el-table显示所有sheet表格数据。只能显示简单的数据格式,不能显示合并的单元格。先记一下;留着自己之后看。

component组件


<template>
  <div>
    <input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick">
    <el-button :loading="loading" style="margin-left:16px;" size="mini" type="primary" @click="handleUpload">
      导入文件
    </el-button>
  </div>
</template>

<script>
import XLSX from 'xlsx'

export default {
  props: {
    beforeUpload: Function, // eslint-disable-line
    onSuccess: Function// eslint-disable-line
  },
  data() {
    return {
      loading: false,
      editableTabs: []
    }
  },
  methods: {
    handleDrop(e) {
      e.stopPropagation()
      e.preventDefault()
      if (this.loading) return
      const files = e.dataTransfer.files
      if (files.length !== 1) {
        this.$message.error('Only support uploading one file!')
<template> <div> <h1 class="title">考勤记录汇总</h1> <el-tabs v-model="activeName" type="card"> <el-tab-pane label="table" name="table"> <el-form :inline="true" :model="form" ref="topform"> <el-form-item prop="Month" label="Month:"> <el-select v-model="form.Month" placeholder="请选择" style="width:170px" clearable > <el-option v-for="item in monthOptions" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-form-item> <el-form-item prop="Department" label="部门:"> <el-select v-model="form.Department" multiple placeholder="请选择" style="width:170px" collapse-tags collapse-tags-tooltip allow-create filterable > <el-option v-for="item in DepartmentOptions" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-form-item> <el-form-item prop="Division" label="科室"> <el-select v-model="form.Division" multiple placeholder="请选择" style="width:170px" collapse-tags collapse-tags-tooltip allow-create filterable > <el-option v-for="item in DivisionOptions" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-form-item> <el-form-item prop="Group" label="组别:"> <el-select v-model="form.Group" multiple placeholder="请选择" style="width:170px" collapse-tags collapse-tags-tooltip allow-create filterable > <el-option v-for="item in GroupOptions" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-form-item> <el-button type="primary" @click="getHistory('topform')"> 查询 </el-button> <el-form-item style="margin-left: 10px;"> <el-upload :on-success="uploadSuccess" :on-error="uploadError" action="http://10.6.2.130:90/new/js/attendance/uploadattendance.php" ref="upload" multiple > <el-button type="primary">导入</el-button> </el-upload> <!-- <el-button type="primary" @click="importResume">上传简历</el-button> --> </el-form-item> <el-button type="primary" @click="exportToExcel">导出</el-button> </el-form> <div class="alarm-data-table"> <el-table :data="DataTable" style="width: 100%;" border stripe :header-cell-style="{ background: '#004c99', color: '#ffffff' }" ref="ymstable" :height="tableHeight" @sort-change="handleSortChange" > <el-table-column v-for="column in tableColumns" :key="column.prop" :prop="column.prop" :label="column.label" :sortable="column.sortable || true" :width="column.width || null" /> </el-table> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="pageSizes" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" > </el-pagination> </div> </el-tab-pane> </el-tabs> </div> </template> 对导入功能进行修改,将上传的文件传到ftp,不在用调用php
最新发布
11-21
<script setup> import {computed, ref, nextTick, watch} from 'vue' import { useI18n } from 'vue-i18n' import * as XLSX from 'xlsx/xlsx.mjs' import { useAppStore } from '@/stores/app.js' import { useThemeStore } from '@/stores/theme.js' import { useWellStore } from '@/stores/well.js' import Card from '@/components/layout/Card.vue' import WellTrajectory from '@/components/BoetWidgets/3d/WellTrajectory.vue' import ImportDialog from './import-dialog/ImportDialog.vue' import InterpolateDialog from './interpolate-dialog/InterpolateDialog.vue' import TrackPrediction from './track-prediction/TrackPrediction.vue' import WaitDrillTrackDesignDialog from './wait-drill-track-design-dialog/WaitDrillTrackDesignDialog.vue' import HitTargetPredictionDialog from './hit-target-prediction-dialog/HitTargetPredictionDialog.vue' import EditDialog from './edit-dialog/EditDialog.vue' import {deepClone, exportExcel, formatTimeString, formatDecimal} from '@/common/util.js' import BaseFrame from '@/components/layout/BaseFrame.vue' import {Plus, Check, Close, Delete, Download, DataLine, Aim, EditPen, Share, Upload} from '@element-plus/icons-vue' import {ElLoading, ElMessage} from 'element-plus' import {getDrilledTracks, deleteDrilledTrack, getDrilledTrackDatas, saveDrilledTrackData, deleteDrilledTrackData} from '@/api/modules/drilled-track.js' const { t } = useI18n() const appStore = useAppStore() const themeStore = useThemeStore() const wellStore = useWellStore() const well = computed(()=>{ return wellStore.getWell() }) const rowIndex = ref(null) // 表格行 const selectRow = ref(null) // 选中的行 const importDialogVisible = ref(false) const interpolateDialogVisible = ref(false) const waitDrillTrackDesignDialogVisible = ref(false) const hitTargetPredictionDialogVisible = ref(false) const isAdd = ref(true) const editDialogVisible = ref(false) const tableRef = ref(null) const drilledTracks = ref([]) const importSource = ref('file') // 新增:默认是文件导入 // 实钻轨迹 const handleGetDrilledTracks = ()=>{ const params = { wellId: well.value.wellId, wellBoreId: well.value.wellBoreId } getDrilledTracks(params).then(res=>{ if (res) { drilledTracks.value = res // 使用 nextTick 确保表格已经渲染 nextTick(()=>{ // 确保表格引用存在且有数据 if (tableRef.value && drilledTracks.value.length) { const firstRow = drilledTracks.value[0] // 默认选中第一行 tableRef.value.setCurrentRow(firstRow) } }) } }) } // 点击行时,设置当前行 const currentRow = ref(null) const handleCurrentChange = (val)=>{ currentRow.value = val handleGetDrilledTrackDatas() } const drilledTrackDatas = ref([]) const drilledTrackGraphTempDatas = ref([]) // 实钻轨迹数据 const handleGetDrilledTrackDatas = ()=>{ const params = { wellId: well.value.wellId, wellBoreId: well.value.wellBoreId, drilledTrackId: currentRow.value.id } getDrilledTrackDatas(params).then(res=>{ drilledTrackDatas.value = res drilledTrackGraphTempDatas.value = res }) } // 删除待钻轨迹 const handleDeleteDrilledTrack = (idx, row)=>{ const params = { wellId: row.wellId, drilledTrackId: row.id } deleteDrilledTrack(params).then(()=>{ drilledTracks.value.splice(idx, 1) if (drilledTracks.value.length) { const firstRow = drilledTracks.value[0] // 默认选中第一行 tableRef.value.setCurrentRow(firstRow) } else { drilledTrackDatas.value = [] } }) } // 新增 const handleAdd = (idx)=>{ // rowIndex.value = idx + 1 // drilledTrackDatas.value.splice(idx + 1, 0, {md: null, inc: null, azi: null}) const newIndex = idx + 1 drilledTrackDatas.value.splice(newIndex, 0, {md: null, inc: null, azi: null}) // 设置新行编辑状态 editingRows.value.push(newIndex) selectRows.value[newIndex] = deepClone(drilledTrackDatas.value[newIndex]) } // 编辑 const handleUpdate = (idx)=>{ if (!editingRows.value.includes(idx)) { editingRows.value.push(idx) selectRows.value[idx] = deepClone(drilledTrackDatas.value[idx]) } } // 取消编辑 const handleCancel = (idx, row)=>{ if (!row.id) { // 新增行取消 drilledTrackDatas.value.splice(idx, 1) } // 从编辑状态中移除 const indexInEditing = editingRows.value.indexOf(idx) if (indexInEditing !== -1) { editingRows.value.splice(indexInEditing, 1) delete selectRows.value[idx] } } // 保存数据 const handleComplete = async(idx)=>{ const row = drilledTrackDatas.value[idx] // 获取相邻行的值(考虑编辑状态) const prevRow = idx > 0 ? drilledTrackDatas.value[idx - 1] : null const nextRow = idx < drilledTrackDatas.value.length - 1 ? drilledTrackDatas.value[idx + 1] : null // 两个深度之间的间隔不能小于这个值 const eps = 1e-8 // 验证测深值必须大于上一行 if (prevRow && prevRow.md !== null && row.md - prevRow.md <= eps) { ElMessage.warning('测深必须大于上一个值') return false } // 验证测深值必须小于下一行 if (nextRow && nextRow.md !== null && row.md - nextRow.md >= eps) { ElMessage.warning('测深必须小于下一个值') return false } const nonEmptyNewRows = drilledTrackDatas.value .slice(idx + 1) // 获取当前行之后的行 .filter(r=>!r.id && // 新增行(没有ID) editingRows.value.includes(drilledTrackDatas.value.indexOf(r)) && // 处于编辑状态 (r.md !== null || r.inc !== null || r.azi !== null) // 至少有一个字段非空 ) .map(r=>({ ...r })) // 深拷贝 // console.log(nonEmptyNewRows) const postData = { id: row.id, wellId: well.value.wellId, wellBoreId: well.value.wellBoreId, drilledTrackId: currentRow.value.id, md: row.md, inc: row.inc, azi: row.azi } try { await saveDrilledTrackData(postData) // 从编辑状态中移除 const indexInEditing = editingRows.value.indexOf(idx) // console.log(indexInEditing) if (indexInEditing !== -1) { editingRows.value.splice(indexInEditing, 1) delete selectRows.value[idx] } // 重新加载数据 await handleGetDrilledTrackDatas() // +++ 新增:重新添加非空的新行并恢复编辑状态 +++ nonEmptyNewRows.forEach(newRow=>{ console.log(nonEmptyNewRows) const newIndex = drilledTrackDatas.value.length - 1 console.log(newIndex) console.log(drilledTrackDatas) drilledTrackDatas.value.push(newRow) console.log(newRow) editingRows.value.push(newIndex) console.log(editingRows.value.push(newIndex)) selectRows.value[newIndex] = deepClone(newRow) console.log(selectRows) }) } catch (error) { console.error('保存失败:', error) ElMessage.error('保存失败') } } // 删除轨迹数据 const handleDeleteDrilledTrackData = (row)=>{ const params = { wellId: well.value.wellId, drilledTrackDataId: row.id } deleteDrilledTrackData(params).then(()=>{ handleGetDrilledTrackDatas() }) } // 3D轨迹配置 const drilledTrackGraphConfig = ref({ skin: { blackTheme: themeStore.isDark}, showLegend: false, showScaleSelector: false, showTubeSizeSlider: true, tubeSize: 0 }) // 图形数据 const drilledTrackGraphDatas = computed(()=>{ if (!drilledTrackGraphTempDatas.value) { return null } // 过滤新录入的数据 const filterData = drilledTrackGraphTempDatas.value.filter(t=>t.id) const data = filterData.map(({ ns: x, ew: y, ...rest })=>({ x, y, ...rest })) return [ { 'code': 0, 'isDrilled': true, 'data': data, 'name': '实钻轨迹', 'isShow': true } ] }) const excelData = ref([]) const excelFile = ref(null) const loading = ref(null) // 导入轨迹数据 const handleImportDrilledTrackData = (ev)=>{ // 获取文件后缀 const ext = ev.name.substring(ev.name.lastIndexOf('.')) if (ext !== '.xls' && ext !== '.xlsx') { ElMessage.warning('请选择EXCEL文件') return false } excelData.value = [] excelFile.value = ev.raw if (!excelFile.value) { ElMessage.warning('文件打开失败') return false } else { loading.value = ElLoading.service({ lock: true, text: '文件解析中,请稍候...', background: 'rgba(0, 0, 0, 0.7)' }) // 读取文件 setTimeout(readExcelFile, 100) } } // 文件读取并解析 const readExcelFile = ()=>{ const reader = new FileReader() reader.readAsBinaryString(excelFile.value)// 以二进制的方式读取 reader.onload = ev=>{ const fileData = ev.target.result const workBook = XLSX.read(fileData, {type: 'binary'})// 解析二进制格式数据 workBook.SheetNames.forEach((sheetName, index)=>{ const item = { sheetName: sheetName } const workSheet = workBook.Sheets[workBook.SheetNames[index]]// 获取第一个Sheet item.rows = XLSX.utils.sheet_to_json(workSheet, {range: -1, defval: null})// 指定-1行为列头,空单元格赋值 null // 获取json数据key if (item.rows && item.rows.length > 0) { item.keys = [] const keys = Object.keys(item.rows[0]) keys.forEach((key, index)=>{ item.keys.push({ idx: index, key: key, label: '' }) }) } excelData.value.push(item) }) importDialogVisible.value = true loading.value.close() } } const handleImport = (source)=>{ if (source === 'file') { // 模拟点击隐藏的 input 或 el-upload 打开系统文件夹 document.querySelector('#hiddenFileInput').click() } else if (source === 'clipboard') { importSource.value = 'clipboard' importDialogVisible.value = true } } const handleImportReload = ()=>{ handleGetDrilledTrackDatas() importDialogVisible.value = false } // 导出轨迹数据 const handleExportDrilledTrackData = ()=>{ // 过滤数据,只取一部分属性的数据 const partData = drilledTrackDatas.value.map(({md, inc, azi, tvd, nsOffset, ewOffset, horiOffset, projOffset, dogleg})=>({ md, inc, azi, tvd, nsOffset, ewOffset, horiOffset, projOffset, dogleg })) // 值数组 const valueArray = partData.map(obj=>Object.values(obj)) const headerArray = ['测深', '井斜', '方位', '垂深', '南北位移', '东西位移', '水平位移', '投影位移', '狗腿度'] const sheetName = '实钻轨迹' const fileName = '实钻轨迹.xlsx' exportExcel(sheetName, headerArray, formatDecimal(valueArray), fileName, 15) } // 监听well变化 watch(()=>well, (newVal)=>{ if (Object.keys(newVal.value).length !== 0) { handleGetDrilledTracks() } }, {deep: true, immediate: true}) const editingRows = ref([]) const selectRows = ref({}) // 修改:处理测深输入事件 const handleMdInput = (index)=>{ const row = drilledTrackDatas.value[index] // 检查条件:当前是最后一行、正在编辑、测深有值、是新增行(无ID) if ( index === drilledTrackDatas.value.length - 1 && editingRows.value.includes(index) && row.md !== null && row.md !== '' && !row.id ) { // 在下方添加新行 drilledTrackDatas.value.push({md: null, inc: null, azi: null}) const newIndex = drilledTrackDatas.value.length - 1 // 设置新行进入编辑状态 editingRows.value.push(newIndex) selectRows.value[newIndex] = deepClone(drilledTrackDatas.value[newIndex]) } } </script> <template> <BaseFrame> <!-- 左侧内容区 --> <div class="col-span-8 flex flex-1 flex-col gap-2"> <!-- 轨迹列表 --> <Card> <template #header> <div class="flex justify-between pl-0 pr-0"> <div class="flex items-center gap-2"> <span class="text-slate-600 dark:text-slate-50 text-[14px]"><strong>【{{ well.wellId ? `${well.wellCode} | ${well.wellBoreName}` : '暂未选井' }}】</strong></span> </div> <div class="flex items-center"> <el-button :icon="Plus" size="small" class="mr-3" @click="editDialogVisible=true;isAdd=true;">{{ t('add') }}</el-button> <el-dropdown @command="importSource=>handleImport(importSource)"> <el-button :icon="Download" size="small">{{ t('import') }}</el-button> <template #dropdown> <el-dropdown-menu> <el-dropdown-item command="file">导入文件</el-dropdown-item> <el-dropdown-item command="clipboard">从剪切板导入</el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> <input id="hiddenFileInput" type="file" accept=".xlsx,.xls" style="display:none" @change="handleImportDrilledTrackData" > <el-button :icon="Upload" size="small" class="ml-3" :disabled="!currentRow" @click="handleExportDrilledTrackData"> {{ t('export') }} </el-button> <el-button :icon="EditPen" size="small" :disabled="!currentRow" @click="interpolateDialogVisible=true"> {{ t('interpolate') }} </el-button> <el-button :icon="Share" size="small" :disabled="!currentRow" @click="appStore.toggleTrackPredictionDrawer()"> {{ t('plan') }} </el-button> <el-button :icon="Share" size="small" :disabled="!currentRow" @click="waitDrillTrackDesignDialogVisible=true"> 待钻设计 </el-button> <el-button :icon="Aim" size="small" :disabled="!currentRow" @click="hitTargetPredictionDialogVisible=true"> {{ t('targetEntry') }} </el-button> <el-button :icon="DataLine" size="small"> {{ t('trend') }} </el-button> </div> </div> </template> <template #default> <div class="h-[14vh]"> <el-table ref="tableRef" :data="drilledTracks" highlight-current-row height="100%" size="small" border stripe style="width: 100%;" @current-change="handleCurrentChange"> <el-table-column type="index" :label="t('order')" width="50" align="center" fixed /> <el-table-column prop="name" :label="t('name')" min-width="80" header-align="center" /> <el-table-column prop="createTime" align="center" :label="t('date')" width="120"> <template #default="{ row }"> <span>{{ formatTimeString(row.createTime, 'YYYY-MM-DD') }}</span> </template> </el-table-column> <el-table-column fixed="right" align="center" :label="t('operate')" width="100"> <template #default="{$index,row}"> <el-button link type="success" size="small" @click.stop="editDialogVisible=true;isAdd=false;"> {{ t('revise') }} </el-button> <el-popconfirm width="200" class="box-item" :title="`确认删除实钻轨迹?`" placement="bottom" confirm-button-text="确认" cancel-button-text="取消" @confirm="handleDeleteDrilledTrack($index,row)" > <template #reference> <el-button link type="danger" size="small" @click.stop> {{ t('delete') }} </el-button> </template> </el-popconfirm> </template> </el-table-column> </el-table> </div> </template> </Card> <!--/ 轨迹列表 --> <!-- 详细数据 --> <Card class="px-2" style="height:calc(100vh - 14rem)"> <div class="h-[98%] overflow-y-auto mt-2"> <el-table size="small" border stripe :data="formatDecimal(drilledTrackDatas)" height="100%" style="width: 100%" > <el-table-column :label="t('operate')" width="90" align="center" fixed="left"> <template #default="{$index,row}"> <template v-if="editingRows.includes($index)"> <div class="flex gap-1 *:!ml-0"> <el-button size="small" type="warning" plain :icon="Close" @click="handleCancel($index, row)" /> <el-button size="small" plain type="success" :icon="Check" @click="handleComplete($index)" /> </div> </template> <template v-else> <div class="flex gap-1 *:!ml-0"> <el-button size="small" class="ml-1" plain :icon="Plus" @click="handleAdd($index)" /> <el-popconfirm width="200" class="box-item" :title="`确认删除本条轨迹数据?`" placement="bottom" confirm-button-text="确认" cancel-button-text="取消" @confirm="handleDeleteDrilledTrackData(row)" > <template #reference> <el-button plain size="small" :icon="Delete" @click.stop /> </template> </el-popconfirm> </div> </template> </template> </el-table-column> <el-table-column label="测深" prop="depth" header-align="center" min-width="80" fixed="left"> <template #header> <div>{{ t('Md') }}</div> <div class="unit-size">(m)</div> </template> <template #default="{$index,row}"> <template v-if="editingRows.includes($index)"> <el-input ref="input" v-model="drilledTrackDatas[$index].md" v-format-input size="small" placeholder="请输入测深" @input="handleMdInput($index)" /> </template> <span v-else @dblclick="handleUpdate($index)">{{ row.md }}</span> </template> </el-table-column> <el-table-column label="井斜" prop="inc" header-align="center" min-width="80" fixed="left"> <template #header> <div>{{ t('inclination') }}</div> <div class="unit-size">(°)</div> </template> <template #default="{$index,row}"> <template v-if="editingRows.includes($index)"> <el-input v-model="drilledTrackDatas[$index].inc" v-format-input size="small" placeholder="请输入井斜" /> </template> <span v-else @dblclick="handleUpdate($index)">{{ row.inc }}</span> </template> </el-table-column> <el-table-column label="方位" prop="azi" header-align="center" min-width="80" fixed="left"> <template #header> <div>{{ t('azimuth') }}</div> <div class="unit-size">(°)</div> </template> <template #default="{$index,row}"> <template v-if="editingRows.includes($index)"> <el-input v-model="drilledTrackDatas[$index].azi" v-format-input size="small" placeholder="请输入方位" /> </template> <span v-else @dblclick="handleUpdate($index)">{{ row.azi }}</span> </template> </el-table-column> <el-table-column label="垂深" prop="tvd" header-align="center" min-width="80" > <template #header> <div>{{ t('Tvd') }}</div> <div class="unit-size">(m)</div> </template> </el-table-column> <el-table-column label="段长" prop="sectionLength" header-align="center" min-width="80" > <template #header> <div>{{ t('courseLength') }}</div> <div class="unit-size">(m)</div> </template> </el-table-column> <el-table-column label="南北位移" prop="nsOffset" header-align="center" min-width="80" > <template #header> <div>{{ t('NsOffset') }}</div> <div class="unit-size">(m)</div> </template> </el-table-column> <el-table-column label="东西位移" prop="ewOffset" header-align="center" min-width="80" > <template #header> <div>{{ t('EwOffset') }}</div> <div class="unit-size">(m)</div> </template> </el-table-column> <el-table-column label="水平位移" prop="horiOffset" header-align="center" min-width="80" > <template #header> <div>{{ t('closure') }}</div> <div class="unit-size">(m)</div> </template> </el-table-column> <el-table-column label="投影位移" prop="projOffset" header-align="center" min-width="80" > <template #header> <div>{{ t('Verticaldistance') }}</div> <div class="unit-size">(m)</div> </template> </el-table-column> <el-table-column label="闭合方位" prop="closeAzi" header-align="center" min-width="80" > <template #header> <div>{{ t('closureAz') }}</div> <div class="unit-size">(°)</div> </template> </el-table-column> <el-table-column label="狗腿度" prop="dogleg" header-align="center" min-width="80" > <template #header> <div>{{ t('dogleg') }}</div> <div class="unit-size">(°/30m)</div> </template> </el-table-column> <el-table-column label="工具面" prop="toolface" header-align="center" min-width="80" > <template #header> <div>{{ t('toolface') }}</div> <div class="unit-size">(°)</div> </template> </el-table-column> <el-table-column label="井斜变化率" prop="incChangeRate" header-align="center" min-width="80" > <template #header> <div>{{ t('incChangeRate') }}</div> <div class="unit-size">(°/30m)</div> </template> </el-table-column> <el-table-column label="方位变化率" prop="aziChangeRate" header-align="center" min-width="80" > <template #header> <div>{{ t('aziChangeRate') }}</div> <div class="unit-size">(°/30m)</div> </template> </el-table-column> </el-table> </div> </Card> <!--/ 详细数据 --> </div> <!-- 右侧2D/3D区域 --> <div class="col-span-4 flex flex-col"> <Card class="flex-1"> <WellTrajectory v-if="drilledTrackGraphDatas" id="divTubeElement" v-model:config="drilledTrackGraphConfig" :show-well-name="false" :show-full-screen-btn="true" :show-animation="false" is-auto-play.sync="true" :data="drilledTrackGraphDatas" /> </Card> </div> <!-- 新增/修改 对话框 --> <edit-dialog v-if="editDialogVisible" :row-data="isAdd?null:currentRow" @reload="handleImportReload" @close="editDialogVisible=false" /> <!-- 导入数据 --> <import-dialog v-if="importDialogVisible" v-model:import-source="importSource" :drilled-track-id="currentRow.id" :excel-data="excelData" @reload="handleGetDrilledTrackDatas" @close="importDialogVisible=false" /> <!-- 插值计算 --> <interpolate-dialog v-if="interpolateDialogVisible" :drilled-track-id="currentRow.id" @close="interpolateDialogVisible=false" /> <!-- 轨迹预测抽屉 --> <el-drawer v-model="appStore.trackPredictionDrawerVisible" title="轨迹预测" :with-header="true" size="100%" direction="ltr" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true" > <track-prediction :last-drilled-track-data="drilledTrackDatas[drilledTrackDatas.length-1]" /> </el-drawer> <!-- 待钻设计 --> <wait-drill-track-design-dialog v-if="waitDrillTrackDesignDialogVisible" :last-drilled-track-data="drilledTrackDatas[drilledTrackDatas.length-1]" @close="waitDrillTrackDesignDialogVisible=false" /> <!-- 中靶预测 --> <hit-target-prediction-dialog v-if="hitTargetPredictionDialogVisible" :drilled-track-id="currentRow.id" @close="hitTargetPredictionDialogVisible=false" /> </BaseFrame> </template> <style lang="scss" scoped> .tab-content { @apply p-2 absolute left-0 top-0 w-full h-full overflow-auto; } .border-card { :deep(.el-tabs__nav-scroll) { @apply flex; .el-tabs__nav { @apply flex-1; .el-tabs__item { @apply flex-1; } } } &.no-border { @apply border-none; } } :deep(.el-drawer) { .el-drawer__header { @apply mb-1 } } </style> 修改本代码,要求保存上一行时,自动新增行内有内容时应该保留当前行并保留编辑状态
07-17
<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <head> <th:block th:include="include :: header('用户列表')" /> <th:block th:include="include :: layout-latest-css" /> <th:block th:include="include :: ztree-css" /> </head> <body class="gray-bg"> <div class="ui-layout-west"> <div class="box box-main"> <div class="box-header"> <div class="box-title"> <i class="fa icon-grid"></i> 组织机构 </div> <div class="box-tools pull-right"> <a type="button" class="btn btn-box-tool" href="#" onclick="dept()" title="管理部门"><i class="fa fa-edit"></i></a> <button type="button" class="btn btn-box-tool" id="btnExpand" title="展开" style="display: none;"> <i class="fa fa-chevron-up"></i> </button> <button type="button" class="btn btn-box-tool" id="btnCollapse" title="折叠"> <i class="fa fa-chevron-down"></i> </button> <button type="button" class="btn btn-box-tool" id="btnRefresh" title="刷新部门"> <i class="fa fa-refresh"></i> </button> </div> </div> <div class="ui-layout-content"> <div id="tree" class="ztree"></div> </div> </div> </div> <div class="ui-layout-center"> <div class="container-div"> <div class="row"> <div class="ibox-content"> <form id="formId"> <input type="hidden" id="parentId" name="parentId"> </form> <ul class="nav nav-tabs"> <li class="active"><a data-toggle="tab" aria-expanded="true" onclick="querylocationList()">功能位置列表</a></li> <li><a data-toggle="tab" aria-expanded="false" onclick="location_equitment()">关联设备</a></li> <li><a data-toggle="tab" aria-expanded="false" onclick="location_history()">安装历史</a></li> </ul> </div> <div class="btn-group-sm" id="toolbar" role="group"> <a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:location:add"> <i class="fa fa-plus"></i> 添加 </a> <a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:location:edit"> <i class="fa fa-edit"></i> 修改 </a> <a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:location:remove"> <i class="fa fa-remove"></i> 删除 </a> <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:location:export"> <i class="fa fa-download"></i> 导出 </a> </div> <div class="col-sm-12 select-table table-striped"> <table id="bootstrap-table"></table> </div> </div> </div> </div> <th:block th:include="include :: footer" /> <th:block th:include="include :: layout-latest-js" /> <th:block th:include="include :: ztree-js" /> <script th:inline="javascript"> var addFlag = [[${@permission.hasPermi('system:location:add')}]]; var editFlag = [[${@permission.hasPermi('system:location:edit')}]]; var removeFlag = [[${@permission.hasPermi('system:location:remove')}]]; var prefix = ctx + "system/location"; $(function() { var panehHidden = false; if ($(this).width() < 769) { panehHidden = true; } $('body').layout({ initClosed: panehHidden, west__size: 185 }); querylocationList(); queryLocationTree(); }); var ButtonManager = { templates: { location: ` <a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:location:add"> <i class="fa fa-plus"></i> 添加 </a> <a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:location:edit"> <i class="fa fa-edit"></i> 修改 </a> <a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:location:remove"> <i class="fa fa-remove"></i> 删除 </a> <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:location:export"> <i class="fa fa-download"></i> 导出 </a> `, equit: ` <a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:base:add"> <i class="fa fa-plus"></i> 添加 </a> <a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:base:edit"> <i class="fa fa-edit"></i> 修改 </a> <a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:base:remove"> <i class="fa fa-remove"></i> 删除 </a> <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:base:export"> <i class="fa fa-download"></i> 导出 </a> `, history: ` <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:location:export"> <i class="fa fa-download"></i> 导出 </a> ` }, change: function(buttonType) { if (this.templates[buttonType]) { $('#toolbar').html(this.templates[buttonType]); return true; } return false; }, // 切换到安装位置按钮 toLocation: function() { return this.change('location'); }, // 切换到关联设备按钮 toEquit: function() { return this.change('equit'); }, // 切换到安装历史按钮 toHistory: function() { return this.change('history'); } }; function location_equitment(){ prefix = ctx + "system/base"; debugger; var options2 = { id:'bootstrap-table', url: prefix + "/list", createUrl: prefix + "/add", updateUrl: prefix + "/edit/{id}", removeUrl: prefix + "/remove", exportUrl: prefix + "/export", modalName: "设备基础信息", columns: [{ checkbox: true }, { field: 'devId', title: '设备ID', visible: false }, { field: 'devCode', title: '设备编码' }, { field: 'devName', title: '设备名称' }, { field: 'professionName', title: '专业名称' }, { field: 'devSpecksId', title: '设备型号' }, { field: 'measurementFlag', title: '计量标志' }, { field: 'maintenanceFlag', title: '养护标志' }, { field: 'devStatus', title: '设备状态' }, { field: 'statuDate', title: '当前状态日期' }, { field: 'userDevFlag', title: '是否用户设备' }, { field: 'factory', title: '生产厂家' }, { field: 'zclb', title: '管理分类' }, { title: '操作', align: 'center', formatter: function(value, row, index) { var actions = []; actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.devId + '\')"><i class="fa fa-edit"></i>编辑</a> '); actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.devId + '\')"><i class="fa fa-remove"></i>删除</a>'); return actions.join(''); } }] }; debugger; reinitializeTable(options2); //$.table.init(options2); ButtonManager.toEquit(); // 切换回新增按钮 $.table.search(); } function location_history(){ ButtonManager.toHistory(); } //销毁table function reinitializeTable(newOptions) { var tableId = 'bootstrap-table'; // 你的表格ID // 方法1:销毁后重新初始化 try { // 销毁现有表格 $('#' + tableId).bootstrapTable('destroy'); } catch (e) { console.log('表格销毁失败或表格不存在:', e); } // 清空表格容器(可选) $('#' + tableId).empty(); // 重新初始化 $.table.init(newOptions || options); } function querylocationList() { prefix = ctx + "system/location"; var options = { url: prefix + "/list", createUrl: prefix + "/add", updateUrl: prefix + "/edit/{id}", removeUrl: prefix + "/remove", exportUrl: prefix + "/export", modalName: "设备位置管理", columns: [{ checkbox: true }, { field: 'locationId', title: '部门主键seq_gk_equipment_type', visible: false }, { field: 'parentId', title: '上级功能位置编码' }, { field: 'locationName', title: '功能位置名称' }, { field: 'status', title: '使用标志' }, { field: 'repairdept', title: '维护计划部门' }, { title: '操作', align: 'center', formatter: function(value, row, index) { var actions = []; actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.locationId + '\')"><i class="fa fa-edit"></i>编辑</a> '); actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.locationId + '\')"><i class="fa fa-remove"></i>删除</a>'); return actions.join(''); } }] }; $.table.init(options); ButtonManager.toLocation(); } function queryHistoryList() { var options = { url: prefix + "/list", createUrl: prefix + "/add", updateUrl: prefix + "/edit/{id}", removeUrl: prefix + "/remove", exportUrl: prefix + "/export", modalName: "安装历史", columns: [{ checkbox: true }, { field: 'locationId', title: '部门主键seq_gk_equipment_type', visible: false }, { field: 'parentId', title: '父层级id' }, { field: 'locationName', title: '设备类型名称' }, { field: 'status', title: '设备类型状态' }, { field: 'repairdept', title: '维护部门' }, { title: '操作', align: 'center', formatter: function(value, row, index) { var actions = []; actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.locationId + '\')"><i class="fa fa-edit"></i>编辑</a> '); actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.locationId + '\')"><i class="fa fa-remove"></i>删除</a>'); return actions.join(''); } }] }; $.table.init(options); $.table.search(); } function queryLocationTree() { var url = ctx + "system/location/treeData"; var options = { url: url, expandLevel: 2, onClick : zOnClick }; $.tree.init(options); function zOnClick(event, treeId, treeNode) { $("#parentId").val(treeNode.id); $.table.search(); } } $('#btnExpand').click(function() { $._tree.expandAll(true); $(this).hide(); $('#btnCollapse').show(); }); $('#btnCollapse').click(function() { $._tree.expandAll(false); $(this).hide(); $('#btnExpand').show(); }); $('#btnRefresh').click(function() { queryLocationTree(); }); /* 用户管理-部门 */ function dept() { var url = ctx + "system/type"; $.modal.openTab("设备类型管理", url); } </script> </body> <!-- 导入区域 --> <script id="importTpl" type="text/template"> <form enctype="multipart/form-data" class="mt20 mb10"> <div class="col-xs-offset-1"> <input type="file" id="file" name="file"/> <div class="mt10 pt5"> <input type="checkbox" id="updateSupport" name="updateSupport" title="如果登录账户已经存在,更新这条数据。"> 是否更新已经存在的用户数据   <a onclick="$.table.importTemplate()" class="btn btn-default btn-xs"><i class="fa fa-file-excel-o"></i> 下载模板</a> </div> <font color="red" class="pull-left mt10"> 提示:仅允许导入“xls”或“xlsx”格式文件! </font> </div> </form> </script> </html>不同的tab页添加不同的查询条件
11-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值