You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

648 lines
18 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<client-only>
<el-container class="container">
<el-aside width="280px" style="height: 100%;border: 1px solid #ddd;margin: 0;padding: 0;">
<!-- 左侧树形控件 -->
<div style="height: 100%">
<el-tree ref="treeRef" :data="treeData" :props="defaultProps" @node-click="handleNodeClick"
:default-expanded-keys="[1, 2, 3, 4, 5]" node-key="id" :highlight-current="true" />
</div>
</el-aside>
<el-main class="content">
<el-row>
<!-- 右侧顶部搜索区域 -->
<el-col :span="24" style="display: flex; align-items: center;padding: 5px;">
<!-- 当点击子节点时才显示按钮 -->
<el-button v-if="showButton" type="primary" style="margin-right: 10px" @click="openDialog">导入</el-button>
<!-- 隐藏的文件选择框,限制为只允许选择 Excel 文件 -->
<input type="file" ref="fileInput" @change="handleFileChange" v-show="false"
accept=".kev,.dfd,.pcg,.gdbx,.jpg,.xls,.xlsx,.kev,.txt" />
<!-- 添加的输入框 -->
<el-input v-if="showButton" v-model="searchKey" clearable placeholder="请输入搜索内容"
style="margin-left: 10px; width: 200px"></el-input>
<el-button v-if="showButton" type="success" style="margin-left: 20px" @click="handleSearch">搜索</el-button>
<el-button v-if="delButton" type="danger" style="margin-left: 20px" @click="delEventData">删除</el-button>
</el-col>
</el-row>
<el-row>
<!-- 右侧下面表格控件 -->
<el-col :span="24" class="table-area" style="margin-top: 5px">
<el-table :data="tableData" stripe style="height:100%;padding-bottom: 50px;" border>
<!-- 动态渲染表头 -->
<el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.label"
:width="column.width" :fixed="column.fixed">
<template v-if="column.prop === '查看'" #default="scope">
<el-container style="width: 100%; max-width: 1600px; margin-right: 5px">
<!-- <el-button type="text" @click="drawView(scope.row)">查看</el-button> -->
<el-link type="success" @click="drawView(scope.row)" target="_blank">浏览</el-link>&NonBreakingSpace;
<el-link type="danger" @click="deleteFile(scope.row)" target="_blank">删除</el-link>&NonBreakingSpace;
<el-link type="info" @click="downloadFile(scope.row)" target="_blank">下载</el-link>&NonBreakingSpace;
</el-container>
</template>
<template v-else-if="column.prop === 'OutDataFile'" #default="scope">
<el-link type="info" @click="downloadOutDataFile(scope.row)" target="_blank">{{
scope.row.OutDataFile
}}</el-link>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<el-pagination v-if="dataId" background layout="prev, pager, next" :total="dataTotal"
@current-change="pageChange" :default-page-size="50"
style="height: 30px; margin-top: 10px; margin-bottom: 10px" class="page-container" />
<!-- 弹出框 -->
<el-dialog title="导入数据" v-model="dialogVisible" width="30%" :close-on-click-modal="false">
<div v-if="importOption === '本地文件'" style="margin-top: 20px">
<el-button type="primary" @click="triggerFileSelect">选择文件</el-button>
<!-- 文件名回显 -->
<span v-if="fileName" style="margin-left: 10px; color: #333">已选择文件:{{ fileName }}</span>
</div>
<div style="
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
min-height: 200px;
">
<div v-if="fileContent" style="white-space: pre-wrap; word-wrap: break-word">
{{ fileContent }}
</div>
</div>
<template v-slot:footer>
<span class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="handleImport">保存</el-button>
</span>
</template>
</el-dialog>
<!-- 弹出框openEnergyDialog -->
<el-dialog title="能量值计算" v-model="dialogEnergyVisible" width="30%" :close-on-click-modal="false">
<div>请输入能量计算条件
<el-row class="row-gap">
<el-col :span="4">
区块
</el-col>
<el-col :span="20">
<el-input type="text" clearable v-model="energyCalcModel.energyProjectName"></el-input>
</el-col>
</el-row>
<el-row class="row-gap">
<el-col :span="4">
井名
</el-col>
<el-col :span="20">
<el-input type="text" clearable v-model="energyCalcModel.energyWellName"></el-input>
</el-col>
</el-row>
<el-row class="row-gap">
<el-col :span="4">
公式
</el-col>
<el-col :span="20">
<el-input type="text" clearable v-model="energyCalcModel.energyTextVal"></el-input>
</el-col>
</el-row>
</div>
<template v-slot:footer>
<span class="dialog-footer">
<el-button @click="closeEnergyDialog"></el-button>
<el-button type="primary" @click="handleEnergySave"></el-button>
</span>
</template>
</el-dialog>
</el-main>
</el-container>
<LoadingDialog v-model="loading" ref="loadingRef" :timeout="10000" message="正在加载数据……" @timeout="onTimeout" />
</client-only>
</template>
<script setup>
definePageMeta({
requiresAuth: true
});
import { getColumns, getDatas, uploadData, energyCalc, deleteData, deleteEventData, downloadDataFile } from '~/services/dataManageService';
import { checkEmpty } from "@/utils/objHelper";
import { ElMessageBox } from 'element-plus';
import { useRoute } from "vue-router";
// 消息提示(自动隐藏)
const { $toastMessage } = useNuxtApp();
const loading = ref(false);
const loadingRef = ref(null);
const route = useRoute();
const treeData = [
{
id: 1,
label: "井位数据",
children: [
{ id: 2, label: "井基础" },
{ id: 3, label: "井斜" },
{ id: 4, label: "测井曲线" },
],
},
{
id: 2,
label: "地质工程数据",
children: [
{ id: 6, label: "井段参数" },
{ id: 7, label: "井段坐标" },
],
},
{
id: 3,
label: "地质成果图件",
children: [
{ id: 9, label: "地质图件" },
{ id: 10, label: "水平井图件" },
{ id: 11, label: "地质参数图件" },
{ id: 12, label: "微地震井位图件" },
],
},
{
id: 4,
label: "微地震云数据",
children: [
{ id: 14, label: "事件点数据" },
{ id: 15, label: "预处理成果" },
{ id: 16, label: "网格化成果" },
],
},
{
id: 5,
label: "智能布井",
children: [
{ id: 13, label: "断裂分布图" },
{ id: 18, label: "智能布井成果" },
],
},
];
const energyCalcModel = {
energyProjectName: "ZU202",
energyWellName: "ZU203H2-2",
energyTextVal: "10000+1.5*震级",
};
const mapIds = [9, 10, 11, 12, 13, 15, 16, 18];
// 树形配置(节点唯一标识、标签、子节点字段)
const defaultProps = {
children: "children",
label: "label",
};
const searchKey = ref('');
const tableData = ref(null);
// 控制按钮显示
const showButton = ref(false);
// 删除
const delButton = ref(false);
// 动态表头数据
const columns = ref([]);
const dataId = ref(0);
const dataTotal = ref(0);
// 控制弹出框显示
const dialogVisible = ref(false);
const dialogEnergyVisible = ref(false);
// 导入方式
const importOption = ref("本地文件");
const fileContent = ref("");
const fileName = ref("");
const selectedFile = ref(null);
const fileInput = ref(null);
const fetchColumns = async (id) => {
const result = await getColumns(id);
var cols = result.columns;
cols.forEach((ele) => {
if (ele.label == "序号") {
ele.fixed = "left";
}
if (ele.label == "JH") {
ele.fixed = "left";
}
});
if (mapIds.includes(id)) {
cols.push({ prop: "查看", label: "操作" });
}
columns.value = cols;
await getData(id, 1);
};
const getData = async (id, page) => {
try {
const ui = {
name: searchKey.value,
id: id,
page: page,
};
const data = await getDatas(ui);
console.log("Data", data);
var v_data = data.tableData.tableData;
if (mapIds.includes(id) && v_data) {
v_data.forEach((ele) => {
ele.查看 = "查看";
});
}
tableData.value = v_data;
dataTotal.value = data.tableData.total;
} catch (error) {
console.error("加载表格数据失败:", error);
}
};
const pageChange = async (page) => {
try {
await getData(dataId.value, page);
} finally {
closeLoading();
}
};
const handleNodeClick = async (data) => {
try {
loading.value = true;
dataId.value = data.id;
await fetchColumns(data.id);
showButton.value = !data.children;
delButton.value = data.id == 14;
} catch (error) {
console.error("加载数据错误:", error);
}
finally {
closeLoading();
}
};
const handleSearch = async () => {
await getData(dataId.value, 1);
};
const handleFileChange = (event) => {
const file = event.target.files[0];
if (file) {
// 检查是否是 Excel 文件
const fileExtension = file.name.split(".").pop().toLowerCase();
if (
fileExtension === "kev" ||
fileExtension === "dfd" ||
fileExtension === "gdbx" ||
fileExtension === "pcg" ||
fileExtension === "xls" ||
fileExtension === "xlsx" ||
fileExtension === "txt" ||
fileExtension === "jpg"
) {
fileName.value = file.name; // 设置文件名
selectedFile.value = file;
} else {
$toastMessage.warning("请选择一个有效的[Excel, GDBX, DFD, PCG, KEV, TXT]格式文件!");
return;
}
}
};
const openDialog = () => {
switch (dataId.value) {
case 15:
// 打开弹出框
dialogVisible.value = false;
$toastMessage.info("该记录由后台生成,不支持导入!");
break;
case 16:
dialogVisible.value = false;
$toastMessage.info("该记录由后台生成,不支持导入!");
break;
case 18:
dialogVisible.value = false;
$toastMessage.info("该记录由后台生成,不支持导入!");
break;
default:
dialogVisible.value = true;
break;
}
};
const closeDialog = () => {
fileName.value = "";
dialogVisible.value = false;
};
const closeEnergyDialog = () => {
dialogEnergyVisible.value = false;
};
const delEventData = async () => {
if (checkEmpty(searchKey.value)) {
$toastMessage.error("请输入需要删除的井名!");
return;
}
ElMessageBox.confirm(`您确定要删除${searchKey.value}数据吗?`, "删除确认", {
confirmButtonText: "确认删除",
cancelButtonText: "取消",
type: "warning",
draggable: true,
})
.then(async () => {
let res = 0;
switch (dataId.value) {
case 14:
res = await deleteEventData(searchKey.value);
break;
default:
$toastMessage.error("不支持该操作!");
break;
}
if (res == 0) {
$toastMessage.error("删除失败");
} else {
$toastMessage.success("删除成功");
// 重新加载表格数据
await getData(dataId.value, 1);
}
})
.catch(() => {
});
};
const handleImport = async () => {
fileName.value = "";
// 执行导入操作
if (!selectedFile.value) {
$toastMessage.warning("请先选择一个文件");
return;
}
const formData = new FormData();
formData.append("File", selectedFile.value);
formData.append("DataId", dataId.value);
try {
await uploadData(formData);
$toastMessage.success("文件上传成功");
await getData(dataId.value, 1);
// 处理成功后的操作
} catch (error) {
console.error("文件上传失败:", error);
$toastMessage.error("文件上传失败:{0}", error.message);
// 错误处理
} finally {
selectedFile.value = null; // 清空选中的文件
dialogVisible.value = false;
}
};
const triggerFileSelect = () => {
// 触发隐藏的文件选择框
fileInput.value.click();
};
const handleEnergySave = async () => {
// 能力值计算存储接口
const energyCalcObj = {
ProjectName: energyCalcModel.energyProjectName,
WellName: energyCalcModel.energyWellName,
CalcMethod: energyCalcModel.energyTextVal,
};
let response = await energyCalc(energyCalcObj);
if (response.status !== 200) {
$toastMessage.error("能量值计算存储失败!");
} else {
$toastMessage.success("能力值计算存储成功!");
dialogEnergyVisible.value = false;
// 重新加载表格数据
await getData(dataId.value, 1);
}
};
const drawView = (row) => {
if (dataId.value === "" || dataId.value === null) {
$toastMessage.error("Id不能为空!");
return;
}
let targetUrl = "";
let id = "";
let nodeId = "";
const url = new URL('/drawview', window.location.origin);
switch (dataId.value) {
case 9:
id = row.MapID;
nodeId = dataId.value;
break;
case 10:
id = row.MapID;
nodeId = dataId.value;
break;
case 11:
id = row.MapID;
nodeId = dataId.value;
break;
case 12:
id = row.MapID;
nodeId = dataId.value;
break;
case 13:
id = row.MapID;
nodeId = dataId.value;
break;
case 15:
id = row.Id;
nodeId = dataId.value;
break;
case 16:
id = row.Id;
nodeId = dataId.value;
break;
case 18:
id = row.Id;
nodeId = dataId.value;
break;
default:
$toastMessage.error("不支持该操作!");
break;
}
if (checkEmpty(nodeId)) {
return;
}
url.searchParams.set("nodeId", nodeId);
url.searchParams.set("id", id);
window.open(url.toString(), '_blank');
};
/**
* 下载输出数据文件
* @param {*} row
*/
const downloadOutDataFile = (row) => {
let fileName = row.OutDataFile;
if (!fileName) {
$toastMessage.error("没有可下载的文件");
return;
}
downloadFileInfo(fileName);
};
/**
* 下载文件
* @param {*} row
*/
const downloadFile = (row) => {
// 根据不同的数据类型构建下载URL
let fileName = "";
switch (dataId.value) {
case 9: // 地质图件
case 10: // 水平井图件
case 11: // 地质参数图件
case 12: // 微地震井位图件
case 13: // 断裂分布图
// downloadUrl = `/api/File/Download?fileId=${row.MapName}`;
fileName = `${row.MapName}`;
break;
case 15: // 预处理成果
case 16: // 网格化成果
fileName = `${row.OutGraphicFile}`;
break;
case 18: // 智能布井成果
fileName = `${row.OutGraphicFile}`;
//downloadUrl = `/api/File/Download?fileId=${row.Id}`;
break;
default:
$toastMessage.error("不支持下载该类型文件");
return;
}
downloadFileInfo(fileName);
};
/**
* 删除文件
* @param {*} row
*/
const deleteFile = (row) => {
ElMessageBox.confirm("您确定要删除数据吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
let res = 0;
switch (dataId.value) {
case 9:
case 13:
res = await deleteDataFile(dataId.value, row.MapID);
break;
case 10:
case 11:
case 12:
break;
case 15:
case 16:
case 18:
res = await deleteDataFile(dataId.value, row.Id);
break;
default:
$toastMessage.error("不支持该操作!");
break;
}
if (res == 0) {
$toastMessage.error("删除失败");
} else {
$toastMessage.success("删除成功");
// await this.fetchColumns(this.dataId); // 重新加载表格数据
await getData(dataId.value, 1);
}
})
.catch(() => {
$toastMessage.info("已取消删除");
});
};
const deleteDataFile = async (dataId, id) => {
try {
const response = await deleteData(dataId, id); // 假设 deleteData 是你的 API 方法
if (response.Code != 1) {
throw new Error("删除失败");
}
return 1; // 返回 1 表示删除成功
} catch (error) {
console.error("删除失败:", error);
return 0; // 返回 0 表示删除失败
}
};
/**
* 删除事件点数据
* @param {string} WellName
*/
const delMicroSeisEventData = async (WellName) => {
try {
const response = await deleteEventData(WellName); // 假设 deleteData 是你的 API 方法
if (response.status !== 200) {
$toastMessage.error("删除失败!");
} else {
$toastMessage.success("删除成功!");
}
return 1; // 返回 1 表示删除成功
} catch (error) {
$toastMessage.error(`删除失败,${error}`);
return 0; // 返回 0 表示删除失败
}
};
const downloadFileInfo = async (fileName) => {
try {
const blob = await downloadDataFile(fileName); // 下载文件的 API 方法
if (!blob) throw new Error("下载失败");
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
} catch (error) {
console.error("下载错误:", error);
}
};
const onTimeout = () => {
$toastMessage.error("加载数据失败!请稍后重试……");
}
// 关闭加载窗口
const closeLoading = () => {
if (loadingRef.value) {
loadingRef.value.close();
} else {
loading.value = false;
}
}
</script>
<style scoped>
.content {
width: 100%;
height: 100%;
overflow-y: auto;
margin: 0;
padding: 0;
}
.el-table th {
font-weight: 900;
}
.row-gap {
margin-bottom: 10px;
/* 设置的间距值 */
}
.table-area {
padding: 0;
}
</style>