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.
kev/Drawer/drawer-htmlroot/components/HorizontalDrawParam.vue

502 lines
19 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>
<div class="draw-container">
<div class="oper">
<el-button type="primary" :icon="DocumentCopy" @click="ApplyParameter"></el-button>
</div>
<!-- 右侧参数栏 -->
<el-form :model="currentProject.projectParameter" style="max-width: 300px">
<el-form-item style="margin-bottom: 0px;margin-left: 5px;">
<el-col :span="5">
<el-checkbox label="井轨迹" v-model="currentProject.projectParameter.DrawTrack" />
</el-col>
<el-col :offset="1" :span="7">
<el-checkbox label="关节点" v-model="currentProject.projectParameter.DrawPoint" />
</el-col>
<el-col :offset="1" :span="10">
<el-form-item :label="currentProject.projectParameter.DrawGradient ? '曲线' : '柱子'"
:onClick="ApplyParameter">
<el-switch v-model="currentProject.projectParameter.DrawGradient" />
</el-form-item>
</el-col>
</el-form-item>
<el-form-item style="margin-bottom: 0px;margin-left: 5px;">
<el-col :span="5">
<el-checkbox label="分段" v-model="currentProject.projectParameter.DrawStage" />
</el-col>
<el-col :offset="1" :span="10">
<el-form-item label="名称大小">
<el-input-number :min="minValue" :max="maxValue"
v-model="currentProject.projectParameter.StageTextSize" size="small" :controls="false"
:tips="true" />
</el-form-item>
</el-col>
<el-col :offset="1" :span="7">
<el-form-item label="宽度">
<el-input-number :min="minValue" :max="maxValue"
v-model="currentProject.projectParameter.StageWidth" size="small" :controls="false" />
</el-form-item>
</el-col>
</el-form-item>
<el-form-item style="margin-bottom: 0px;margin-left: 5px;">
<el-col :span="5">
<el-checkbox label="参数值" v-model="currentProject.projectParameter.DrawParamText" />
</el-col>
<el-col :offset="1" :span="10">
<el-form-item label="文字大小">
<el-input-number :min="minValue" :max="maxValue"
v-model="currentProject.projectParameter.ParamTextSize" size="small" :controls="false" />
</el-form-item>
</el-col>
</el-form-item>
<el-form-item style="margin-bottom: 0px;margin-left: 5px;">
<el-col :span="11">
<el-form-item :label="(currentProject.projectParameter.DrawGradient
? '曲线'
: '柱子') + '高度'
">
<el-input-number :min="minValue" :max="maxValue"
v-model="currentProject.projectParameter.ColumnHeighFactor" size="small"
style="width: 60px;" :controls="false" />
</el-form-item>
</el-col>
<el-col :span="11" :offset="1">
<el-form-item :label="(currentProject.projectParameter.DrawGradient
? '曲线'
: '柱子') + '宽度'
" v-if="!currentProject.projectParameter.DrawGradient">
<el-input-number :min="minValue" :max="maxValue"
v-model="currentProject.projectParameter.PillarWidth" size="small" style="width: 60px"
:controls="false" v-if="!currentProject.projectParameter.DrawGradient" />
</el-form-item>
</el-col>
</el-form-item>
<!-- <el-form-item>
</el-form-item> -->
</el-form>
<el-tabs v-model="activeTab" :stretch="true">
<el-tab-pane name="fractureParam" label="压裂参数" ref="fractureParamTab">
<el-table ref="fractureParamTableRef" row-key="PillarName" :data="fractureParamDatas"
@selection-change="handleFranctureSelection" style="padding: 0;margin: 0;">
<el-table-column type="selection" width="40px"></el-table-column>
<el-table-column prop="PillarName" label="名称" width="*" show-overflow-tooltip>
<template #default="scope">
<div :style="{ padding: '0' }">{{ scope.row.PillarName }}</div>
</template>
</el-table-column>
<el-table-column Align="center" v-if="false" prop="PillarWidth" label="宽度" width="50px">
<template #default="scope">
<div :style="{ padding: '0' }">
<el-input-number style="width: 50px" :min="minValue" :max="maxValue"
v-model="scope.row.PillarWidth" size="small" :controls="false">
</el-input-number>
</div>
</template>
</el-table-column>
<el-table-column prop="Position" label="位置" width="55">
<template #default="scope">
<div :style="{ padding: '0' }">
<el-radio-group v-model="scope.row.Position">
<el-radio :value="true" size="small">左</el-radio>
<el-radio :value="false" size="small">右</el-radio>
</el-radio-group>
</div>
</template>
</el-table-column>
<el-table-column prop="StandValue" label="最小值" width="70">
<template #default="scope">
<div :style="{ padding: '0' }">
<el-input-number style="width: 50px" :min="minValue" :max="maxValue"
v-model="scope.row.StandValue" size="small" :controls="false">
</el-input-number>
</div>
</template>
</el-table-column>
<el-table-column prop="ColumnHeighFactor" v-if="false" label="高度" width="100">
<template #default="scope">
<el-input-number style="width: 60px" :min="minValue" :max="maxValue"
v-model="scope.row.ColumnHeighFactor" size="small" :controls="false">
</el-input-number>
</template>
</el-table-column>
<el-table-column prop="ColorValue" label="颜色" width="55">
<template #default="scope">
<div :style="{ padding: '0' }">
<el-color-picker v-model="scope.row.ColorValue" color-format="hex" />
</div>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane name="wellDeflectionData" label="井斜数据" ref="wellDeflectionDataTab">
<el-table ref="wellDeflectionDataTableRef" row-key="PillarName" :data="wellDeflectionDatas"
@selection-change="handleWellDeflectionDataSelection">
<el-table-column type="selection" width="40"></el-table-column>
<el-table-column prop="PillarName" label="名称" width="*" show-overflow-tooltip>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane name="fracturingSectiondata" label="压裂段数据" ref="fracturingSectionDataTab">
<el-table ref="fracturingSectionDataTableRef" row-key="PillarName" :data="fracturingSectionDatas"
@selection-change="handleFracturingSectionDataSelection">
<el-table-column type="selection" width="40"></el-table-column>
<el-table-column prop="PillarName" label="名称" width="*" show-overflow-tooltip>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<LoadingDialog v-model="loading" ref="loadingRef" :timeout="150000" message="正在应用参数……" @timeout="onTimeout" />
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeMount } from 'vue';
import { DocumentCopy } from "@element-plus/icons-vue";
import { emitter } from "~/utils/eventBus";
import { fetchAllWell } from '~/services/projectService'
import { fetchCalcHoriWellFracturCoord, updateParameter } from '~/services/horizontalWellService'
const { $toastMessage } = useNuxtApp();
import { STORAGE_KEYS } from "~/utils/storageKeys"
import { EMIT_COMMAND } from '~/utils/commandTypes';
// 当前页图件token的 key
const currentTokenKey = STORAGE_KEYS.HORIZONTAL_WELL_TOKEN;
const loading = ref(false);
const loadingRef = ref(null);
/** 默认项目参数 */
const defaultProjectParameter = reactive({
/** 井轨迹 */
DrawTrack: true,
/** 关节点 */
DrawPoint: true,
/** 显示方式(柱子,曲线) */
DrawGradient: false,
/** 分段 */
DrawStage: true,
/** 参数值 */
DrawParamText: true,
/** 名称大小 */
StageTextSize: 10,
/** 文字大小 */
ParamTextSize: 5,
/** 分段宽度 */
StageWidth: 20,
/** 高度 */
ColumnHeighFactor: 10,
/** 宽度 */
PillarWidth: 10,
});
const currentProject = reactive({
ID: 0,
DrawId: "",
LayerName: "",
LayerAlias: "",
DrawerFileName: "",
/** 绘制参数配置 */
projectParameter: { ...defaultProjectParameter },
});
const minValue = 1;
const maxValue = 500;
// 压裂参数
const activeTab = ref("fractureParam");
const fractureParamTab = ref(null);
const fractureParamTableRef = ref(null);
const fractureParamSelected = ref([]);
const fractureParamDatas = ref([]);
// 井斜数据
const wellDeflectionDataTab = ref(null);
const wellDeflectionDataTableRef = ref(null);
const wellDeflectionDataSelected = ref([]);
const wellDeflectionDatas = ref([]);
// 压裂段数据
const fracturingSectionDataTab = ref(null);
const fracturingSectionDataTableRef = ref(null);
const fracturingSectionDataSelected = ref([]);
const fracturingSectionDatas = ref([]);
const onTimeout = (() => {
$toastMessage.error("应用参数计算超时……");
})
const ApplyParameter = async () => {
if (currentProject.ID === undefined || currentProject.ID === 0) {
$toastMessage.warning("请选择一个项目!");
return;
}
try {
loading.value = true;
let config = currentProject.projectParameter;
let pillarParams = Array.from(
new Set(
fractureParamSelected.value.map(
(p) =>
`${p.PillarName}@${config.PillarWidth ?? 10}@${p.Position}@${p.StandValue ?? 0
}@${config.ColumnHeighFactor ?? 10}@${p.ColorValue}`
)
)
);
let displayPillarArray = [];
for (const param of fractureParamSelected.value) {
if (displayPillarArray.indexOf(param.PillarName) === -1) {
displayPillarArray.push(param.PillarName);
}
}
let displayWellArray = [];
for (const param of wellDeflectionDataSelected.value) {
if (displayWellArray.indexOf(param.PillarName) === -1) {
displayWellArray.push(param.PillarName);
}
}
config.PillarParams = pillarParams.join("|");
config.DisplayWells = displayWellArray.join(",");
config.DisplayPillars = displayPillarArray.join(",");
config.DrawId = localStorage.getItem(currentTokenKey) || generateGUID();
config.ClientID = config.DrawId;
const response = await updateParameter(config);
if (response) {
emitter.emit(EMIT_COMMAND.EVT_TYPE, { type: EMIT_COMMAND.VIEW_ALL, cmdID: currentTokenKey, data: JSON.stringify({ drawerToken: config.DrawId }) });
} else {
$toastMessage.error(`应用参数失败!`);
}
} catch (error) {
console.error(`应用参数错误:${error}`);
$toastMessage.error(`应用参数错误:${error}`);
} finally {
loadingRef.value.close();
}
};
const handleFranctureSelection = (selection) => {
fractureParamSelected.value = selection;
};
const handleWellDeflectionDataSelection = (selection) => {
wellDeflectionDataSelected.value = selection;
};
const handleFracturingSectionDataSelection = (selection) => {
fracturingSectionDataSelected.value = selection;
};
const updateParameters = async () => {
if (currentProject.projectParameter != null) {
const strParameter = currentProject.projectParameter.PillarParams;
await fetchParameters(strParameter);
if (currentProject.projectParameter.DisplayPillars) {
let displayPillars = currentProject.projectParameter.DisplayPillars
.split(",")
.filter((item) => item !== "");
fractureParamDatas.value.forEach((row) => {
if (
displayPillars.indexOf(row.PillarName) > -1 &&
fractureParamSelected.value.indexOf(row) === -1
) {
// fractureParamSelected.value.push(row);
fractureParamTableRef.value.toggleRowSelection(row);
}
});
}
if (currentProject.projectParameter.DisplayWells) {
let displayWells = currentProject.projectParameter.DisplayWells
.split(",")
.filter((item) => item !== "");
await fetchAllWellParam(2);// 参数1井斜2压裂段
fracturingSectionDatas.value.forEach((row) => {
if (
displayWells.indexOf(row.PillarName) > -1 &&
fracturingSectionDataSelected.value.indexOf(row) === -1
) {
// fracturingSectionDataSelected.value.push(row);
fracturingSectionDataTableRef.value.toggleRowSelection(row);
}
});
await fetchAllWellParam(1);
wellDeflectionDatas.value.forEach((row) => {
if (
displayWells.indexOf(row.PillarName) > -1 &&
wellDeflectionDataSelected.value.indexOf(row) === -1
) {
// fracturingSectionDataSelected.value.push(row);
wellDeflectionDataTableRef.value.toggleRowSelection(row);
}
});
}
} else {
await fetchParameters();
// await fetchAllWellParam(2);
// await fetchAllWellParam(1);
}
};
/** 获取压裂参数 */
const fetchParameters = async (strParameter) => {
fractureParamDatas.value = [];
if (strParameter) {
// 加载参数配置
const para = strParameter
.split("|")
.map((pair) => pair.split("@"))
.filter((parts) => parts.length === 6)
.map((parts) => ({
PillarName: parts[0],
PillarWidth: parseInt(parts[1]),
Position: (parts[2] + "").toLowerCase() === "true",
StandValue: parseFloat(parts[3]),
ColumnHeighFactor: parseInt(parts[4]),
ColorValue: parts[5],
}));
para.forEach((item) => {
fractureParamDatas.value.push(item);
});
return;
}
let records = await fetchCalcHoriWellFracturCoord();
if (records.length === 0) {
return;
}
let paramNames = [];
for (const item of records) {
if (paramNames.indexOf(item) == -1) {
paramNames.push(item);
}
}
for (const name of paramNames) {
fractureParamDatas.value.push({
PillarName: name,
PillarWidth: 10,
Position: true,
StandValue: 0,
ColumnHeighFactor: 10,
ColorValue: getRandomHexColor(),
});
}
};
const getRandomHexColor = () => {
// 生成随机的红色、绿色和蓝色分量
const r = Math.floor(Math.random() * 256); // 0 到 255
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
// 将十进制颜色分量转换为十六进制并拼接成颜色代码
const hexColor = `#${r.toString(16).padStart(2, "0")}${g
.toString(16)
.padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
return hexColor;
};
/** 获取井斜/压裂段数据 */
const fetchAllWellParam = async (wtype, strParameter) => {
if (strParameter) {
// 加载参数配置
const para = strParameter
.map((parts) => ({
PillarName: parts[0]
}));
switch (wtype) {
case 2:
fracturingSectionDatas.value = [];
break;
case 1:
wellDeflectionDatas.value = [];
break;
}
para.forEach((item) => {
switch (wtype) {
case 2:
fracturingSectionDatas.value.push(item);
break;
case 1:
wellDeflectionDatas.value.push(item);
break;
}
});
return;
}
let records = await fetchAllWell(wtype);
if (records.length === 0) {
return;
}
let paramNames = [];
for (const item of records) {
if (paramNames.indexOf(item) == -1) {
paramNames.push(item);
}
}
for (const name of paramNames) {
const data = {
PillarName: name
};
switch (wtype) {
case 2:
fracturingSectionDatas.value.push(data);
break;
case 1:
wellDeflectionDatas.value.push(data);
break;
}
}
};
onMounted(async () => {
listenProjectParam();
await updateParameters();
await fetchAllWellParam(2);
await fetchAllWellParam(1);
});
const listenProjectParam = (() => {
emitter.on(EMIT_COMMAND.PROJECT_PARAM, async (data) => {
currentProject.ID = data.ID;
Object.assign(currentProject.projectParameter, data.projectParameter);
await updateParameters();
});
});
onUnmounted(() => {
emitter.off(EMIT_COMMAND.PROJECT_PARAM);
});
</script>
<style scoped>
.draw-container {
background: #fff;
width: 100%;
height: calc(100vh - 62px);
overflow: auto;
}
.oper {
width: 100%;
height: 40px;
margin: 0;
padding-left: 10px;
padding-top: 10px;
}
:deep(.el-input-number .el-input__inner) {
padding-left: 0 !important;
padding-right: 0 !important;
}
</style>