Commit 1548c99c by zhaopanyu

zpy

parent 93f8a227
...@@ -624,6 +624,15 @@ export function getXsView(query) { ...@@ -624,6 +624,15 @@ export function getXsView(query) {
}); });
} }
// 井眼轨迹-斜深(系统接口)
export function getXsViews(query) {
return request({
url: "/system/jskd/jygjEw_xs",
method: "get",
params: query,
});
}
//井身结构图 //井身结构图
// export function jsjgImg (query) { // export function jsjgImg (query) {
// return request({ // return request({
...@@ -660,8 +669,6 @@ export function addKcax(query) { ...@@ -660,8 +669,6 @@ export function addKcax(query) {
}); });
} }
//多井钻头曲线图 //多井钻头曲线图
export function getDjztqxt(query) { export function getDjztqxt(query) {
return request({ return request({
......
...@@ -4,30 +4,28 @@ ...@@ -4,30 +4,28 @@
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search"> <el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
<el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" /> <el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
</el-tooltip> </el-tooltip>
<el-tooltip class="item" effect="dark" content="刷新" placement="top"> <el-tooltip class="item" effect="dark" content="刷新" placement="top" v-if="showRefresh">
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" /> <el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
</el-tooltip> </el-tooltip>
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns"> <el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/> <el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'" />
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'"> <el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px"
v-if="showColumnsType == 'checkbox'" :append-to-body="true">
<el-button size="mini" circle icon="el-icon-menu" /> <el-button size="mini" circle icon="el-icon-menu" />
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown" class="columns-dropdown">
<template v-for="item in columns"> <el-scrollbar wrap-class="columns-scroll-wrap" view-class="columns-scroll-view">
<el-dropdown-item :key="item.key"> <template v-for="(item, idx) in columns">
<el-checkbox :checked="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" /> <el-dropdown-item :key="item.key != null ? item.key : idx">
<el-checkbox :checked="item.visible" @change="checkboxChange($event, idx)" :label="item.label" />
</el-dropdown-item> </el-dropdown-item>
</template> </template>
</el-scrollbar>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</el-tooltip> </el-tooltip>
</el-row> </el-row>
<el-dialog :title="title" :visible.sync="open" append-to-body> <el-dialog :title="title" :visible.sync="open" append-to-body>
<el-transfer <el-transfer :titles="['显示', '隐藏']" v-model="value" :data="columns" @change="dataChange"></el-transfer>
:titles="['显示', '隐藏']"
v-model="value"
:data="columns"
@change="dataChange"
></el-transfer>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
...@@ -54,6 +52,11 @@ export default { ...@@ -54,6 +52,11 @@ export default {
columns: { columns: {
type: Array, type: Array,
}, },
/* 是否显示刷新按钮 */
showRefresh: {
type: Boolean,
default: true,
},
/* 是否显示检索图标 */ /* 是否显示检索图标 */
search: { search: {
type: Boolean, type: Boolean,
...@@ -109,9 +112,9 @@ export default { ...@@ -109,9 +112,9 @@ export default {
showColumn() { showColumn() {
this.open = true; this.open = true;
}, },
// 勾选 // 勾选 -> 抛事件给父组件,由父组件修改 columns
checkboxChange(event, label) { checkboxChange(visible, index) {
this.columns.filter(item => item.label == label)[0].visible = event; this.$emit('columns-change', { index, visible });
} }
}, },
}; };
...@@ -123,7 +126,36 @@ export default { ...@@ -123,7 +126,36 @@ export default {
display: block; display: block;
margin-left: 0px; margin-left: 0px;
} }
::v-deep .el-transfer__button:first-child { ::v-deep .el-transfer__button:first-child {
margin-bottom: 10px; margin-bottom: 10px;
} }
</style> </style>
<style>
/* 让列显隐下拉可滚动,支持两列展示,并追加到 body 防止裁剪 */
.columns-dropdown {
padding: 6px 0;
min-width: 420px;
}
.columns-scroll-wrap {
max-height: 60vh;
}
.columns-scroll-view {
padding-right: 6px;
column-count: 2;
column-gap: 16px;
column-fill: auto;
}
.columns-scroll-view .el-dropdown-item {
break-inside: avoid;
-webkit-column-break-inside: avoid;
}
.columns-scroll-view .el-dropdown-menu__item {
white-space: nowrap;
}
</style>
...@@ -377,7 +377,7 @@ export const dynamicRoutes = [ ...@@ -377,7 +377,7 @@ export const dynamicRoutes = [
permissions: ["efficiencyAnalysis:djxx:list"], permissions: ["efficiencyAnalysis:djxx:list"],
children: [ children: [
{ {
path: "index/:jh/:famc/:qk/:jhs", path: "index",
component: () => import("@/views/efficiencyAnalysis/djxx/detail"), component: () => import("@/views/efficiencyAnalysis/djxx/detail"),
name: "DjxxDetail", name: "DjxxDetail",
meta: { meta: {
......
<template> <template>
<div class="drilling-chart-container"> <div class="drilling-chart-container">
<div id="drillingEfficiencyChartdj" class="chart"></div> <div id="drillingEfficiencyChartdj" class="chart"></div>
<!-- 最优值显示区域 - 图表内部左上角 -->
<div class="optimal-values">
<div class="optimal-item">
<span class="label">机速最优:</span>
<span class="value">{{ (chartData && chartData.optimalValues && chartData.optimalValues.jszy) || '--'
}}</span>
</div>
<div class="optimal-item">
<span class="label">进尺最优:</span>
<span class="value">{{ (chartData && chartData.optimalValues && chartData.optimalValues.jczy) || '--'
}}</span>
</div>
<div class="optimal-item">
<span class="label">综合最优:</span>
<span class="value">{{ (chartData && chartData.optimalValues && chartData.optimalValues.zhzy) || '--'
}}</span>
</div>
</div>
</div> </div>
</template> </template>
...@@ -31,10 +49,14 @@ export default { ...@@ -31,10 +49,14 @@ export default {
}; };
}, },
mounted() { mounted() {
this.getList(); // 不在挂载时自动请求数据,等待父组件触发 loadData()
this.$once('hook:beforeDestroy', this.cleanup); this.$once('hook:beforeDestroy', this.cleanup);
}, },
methods: { methods: {
// 供父组件调用
loadData() {
this.getList();
},
getList() { getList() {
const params = { const params = {
zbid: this.id, zbid: this.id,
...@@ -255,10 +277,108 @@ export default { ...@@ -255,10 +277,108 @@ export default {
.drilling-chart-container { .drilling-chart-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
/* padding: 20px; */ position: relative;
padding: 20px;
box-sizing: border-box; box-sizing: border-box;
} }
.optimal-values {
position: absolute;
top: 20px;
left: 20px;
z-index: 10;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 250, 252, 0.95) 100%);
border: 1px solid rgba(64, 158, 255, 0.15);
border-radius: 6px;
padding: 6px 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.6);
backdrop-filter: blur(8px);
min-width: 140px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.optimal-values:hover {
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12), 0 3px 8px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.8);
transform: translateY(-2px);
border-color: rgba(64, 158, 255, 0.25);
}
.optimal-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 4px;
font-size: 11px;
padding: 2px 6px;
border-radius: 4px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
}
.optimal-item:last-child {
margin-bottom: 0;
}
.optimal-item:hover {
background: linear-gradient(135deg, rgba(64, 158, 255, 0.08) 0%, rgba(103, 194, 58, 0.08) 100%);
transform: translateX(2px);
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
}
.optimal-item::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 0;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
border-radius: 2px;
transition: height 0.2s ease;
}
.optimal-item:hover::before {
height: 60%;
}
.optimal-item .label {
color: #5a5e66;
font-weight: 500;
margin-right: 8px;
font-size: 11px;
letter-spacing: 0.2px;
opacity: 0.9;
}
.optimal-item .value {
color: #2c3e50;
font-weight: 700;
font-size: 11px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
position: relative;
}
.optimal-item .value::after {
content: '';
position: absolute;
bottom: -1px;
left: 0;
width: 100%;
height: 1px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
opacity: 0;
transition: opacity 0.2s ease;
}
.optimal-item:hover .value::after {
opacity: 0.3;
}
.chart { .chart {
width: 100%; width: 100%;
height: calc(100vh - 220px); height: calc(100vh - 220px);
......
...@@ -737,10 +737,10 @@ export default { ...@@ -737,10 +737,10 @@ export default {
handler(newJh) { handler(newJh) {
if (newJh) { if (newJh) {
this.queryParams.jh = newJh; this.queryParams.jh = newJh;
this.getList(); // 不自动请求,等待父级主动调用 loadData()
} }
}, },
immediate: true immediate: false
}, },
selectedRow: { selectedRow: {
handler(val) { handler(val) {
......
...@@ -40,6 +40,11 @@ export default { ...@@ -40,6 +40,11 @@ export default {
resizeObserver: null, resizeObserver: null,
loading: false, loading: false,
debounceTimer: null, debounceTimer: null,
lastStackedAreas: null,
lastChartConfig: null,
lastXAxisLabels: null,
lastDepthIntervals: null,
currentGraphicElements: [],
}; };
}, },
computed: { computed: {
...@@ -89,14 +94,13 @@ export default { ...@@ -89,14 +94,13 @@ export default {
watch: { watch: {
jh: { jh: {
handler(newVal) { handler(newVal) {
if (newVal) { // 不自动刷新,等待父级触发 loadData
this.refreshChart();
}
}, },
immediate: true immediate: false
} }
}, },
mounted() { mounted() {
// 初始化空图表,不拉数据;等待父组件触发 loadData
this.initChart(); this.initChart();
this.setupEventListeners(); this.setupEventListeners();
}, },
...@@ -241,6 +245,10 @@ export default { ...@@ -241,6 +245,10 @@ export default {
throw error; throw error;
} }
}, },
// 供父组件在切换到本tab时调用
async loadData() {
await this.initChart();
},
// 处理窗口大小变化 // 处理窗口大小变化
handleResize() { handleResize() {
...@@ -265,6 +273,12 @@ export default { ...@@ -265,6 +273,12 @@ export default {
this.setChartDimensions(chartDom); this.setChartDimensions(chartDom);
} }
this.myChart.resize(); this.myChart.resize();
if (this.lastStackedAreas && this.lastChartConfig && this.lastXAxisLabels) {
this.drawStratumLabels(this.lastStackedAreas, this.lastChartConfig, this.lastXAxisLabels);
}
if (this.lastDepthIntervals && this.lastXAxisLabels && this.lastChartConfig) {
this.drawJhSeparators(this.lastDepthIntervals, this.lastXAxisLabels, this.lastChartConfig);
}
} }
}, },
...@@ -296,6 +310,12 @@ export default { ...@@ -296,6 +310,12 @@ export default {
// 确保图表完全渲染后再resize // 确保图表完全渲染后再resize
this.$nextTick(() => { this.$nextTick(() => {
this.myChart.resize(); this.myChart.resize();
this.lastStackedAreas = wellData.stackedAreas;
this.lastChartConfig = mockData.chartConfig;
this.lastXAxisLabels = xAxisLabels;
this.drawStratumLabels(this.lastStackedAreas, this.lastChartConfig, this.lastXAxisLabels);
this.lastDepthIntervals = wellData.depthIntervals || [];
this.drawJhSeparators(this.lastDepthIntervals, this.lastXAxisLabels, this.lastChartConfig);
}); });
} catch (error) { } catch (error) {
...@@ -327,8 +347,8 @@ export default { ...@@ -327,8 +347,8 @@ export default {
grid: { grid: {
top: 10, top: 10,
left: "4%", left: "4%",
right: "3%", right: "4%",
bottom: "6%", bottom: "10%",
containLabel: true, containLabel: true,
show: false, show: false,
}, },
...@@ -559,15 +579,19 @@ export default { ...@@ -559,15 +579,19 @@ export default {
barWidth: "6%", barWidth: "6%",
label: { label: {
show: true, show: true,
position: (params) => params.data <= 200 ? "top" : "inside", position: 'insideTop',
color: '#fff', color: '#fff',
fontSize: 11, fontSize: 11,
fontWeight: 600, fontWeight: 600,
backgroundColor: "rgba(0,0,0,0.1)", backgroundColor: 'rgba(0,0,0,0.1)',
padding: [2, 3], padding: [2, 3],
borderRadius: 4, borderRadius: 4,
borderColor: 'rgba(255,255,255,0.3)', borderColor: 'rgba(255,255,255,0.3)',
borderWidth: 1, borderWidth: 1,
formatter: (params) => {
const di = wellData.depthIntervals[params.dataIndex];
return di && di.ztcc !== undefined ? di.ztcc : params.data;
}
}, },
itemStyle: { itemStyle: {
color: { color: {
...@@ -605,6 +629,37 @@ export default { ...@@ -605,6 +629,37 @@ export default {
}, },
data: wellData.depthIntervals.map((item) => item.interval), data: wellData.depthIntervals.map((item) => item.interval),
}, },
// 底部显示 interval 数值的透明条,用于放置底部标签
{
name: '深度区间-底部标签',
type: 'bar',
// 与主柱重叠以便把标签放在柱底部区域内
barGap: '-100%',
barWidth: '6%',
itemStyle: {
color: 'transparent',
borderColor: 'transparent'
},
emphasis: { itemStyle: { color: 'transparent', borderColor: 'transparent' } },
label: {
show: true,
position: 'insideBottom',
color: '#fff',
fontSize: 11,
fontWeight: 600,
backgroundColor: 'rgba(0,0,0,0.1)',
padding: [2, 3],
borderRadius: 4,
borderColor: 'rgba(255,255,255,0.3)',
borderWidth: 1,
distance: 0,
formatter: (params) => {
const di = wellData.depthIntervals[params.dataIndex];
return di && di.interval !== undefined ? di.interval : params.data;
}
},
data: wellData.depthIntervals.map((item) => item.interval)
},
...areaSeries, ...areaSeries,
]; ];
}, },
...@@ -682,6 +737,209 @@ export default { ...@@ -682,6 +737,209 @@ export default {
}; };
img.src = svgUrl; img.src = svgUrl;
}); });
},
// 使用像素坐标绘制地层标签(透明背景)
drawStratumLabels(stackedAreas, chartConfig, xAxisLabels) {
if (!this.myChart || !stackedAreas || stackedAreas.length === 0) return;
const totalDepth = chartConfig.yAxis.max - chartConfig.yAxis.min;
let currentDepth = chartConfig.yAxis.min;
this.myChart.setOption({ graphic: { elements: [] } });
const graphics = [];
const lastXIndex = Math.max(0, (xAxisLabels?.length || 1) - 1);
const xOffset = 16;
stackedAreas.forEach((area) => {
if (!area.points || area.points.length === 0) return;
const thickness = area.points[0].y;
const centerDepth = currentDepth + thickness / 2;
const pixelRight = this.myChart.convertToPixel({ xAxisIndex: 0, yAxisIndex: 0 }, [lastXIndex, centerDepth]);
if (!pixelRight || !Array.isArray(pixelRight) || pixelRight.length < 2) {
console.warn('convertToPixel 返回无效值:', pixelRight);
return;
}
const [pxRight, py] = pixelRight;
graphics.push({
type: 'text',
position: [pxRight + xOffset, py],
style: {
text: area.name,
fontSize: 12,
fontWeight: 600,
fill: '#333',
backgroundColor: 'transparent',
padding: [0, 0],
borderRadius: 0,
lineWidth: 0,
stroke: 'transparent',
align: 'left',
verticalAlign: 'middle'
},
origin: [0, 0],
z: 10,
bounding: 'raw',
silent: true
});
currentDepth += thickness;
});
this.currentGraphicElements = graphics;
this.myChart.setOption({ graphic: { elements: graphics } });
},
// 根据 depthIntervals 的顺序按 jh 分段,绘制虚线与顶部井号
drawJhSeparators(depthIntervals, xAxisLabels, chartConfig) {
if (!this.myChart || !depthIntervals || depthIntervals.length === 0) return;
// 扫描 depthIntervals 顺序,形成段
const segments = [];
let currentJh = null;
let currentMin = Infinity;
let currentMax = -Infinity;
let started = false;
for (let i = 0; i < depthIntervals.length; i++) {
// 直接使用在 depthIntervals 中的顺序索引作为 x 轴位置,
// 以避免相同 x 标签造成的覆盖与错位
const { jh } = depthIntervals[i];
const idx = i;
if (!started) {
currentJh = jh;
currentMin = currentMax = idx;
started = true;
continue;
}
if (jh === currentJh) {
currentMin = Math.min(currentMin, idx);
currentMax = Math.max(currentMax, idx);
} else {
segments.push({ jh: currentJh, startIdx: Math.min(currentMin, currentMax), endIdx: Math.max(currentMin, currentMax) });
// 开始新段
currentJh = jh;
currentMin = currentMax = idx;
}
}
if (started) {
segments.push({ jh: currentJh, startIdx: Math.min(currentMin, currentMax), endIdx: Math.max(currentMin, currentMax) });
}
const graphics = [];
// 垂直范围(像素)——考虑 y 轴 inverse,取像素最小为顶部、最大为底部
const yMinPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.min);
const yMaxPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.max);
if (yMinPx === null || yMaxPx === null) {
console.warn('convertToPixel 返回 null 值,跳过绘制井号分隔符');
return;
}
const yTopPx = Math.min(yMinPx, yMaxPx);
const yBottomPx = Math.max(yMinPx, yMaxPx);
// 边界虚线(段与段之间),黑色虚线
for (let i = 0; i < segments.length - 1; i++) {
const leftEnd = segments[i].endIdx;
const rightStart = segments[i + 1].startIdx;
const pxLeft = this.myChart.convertToPixel({ xAxisIndex: 0 }, leftEnd);
const pxRight = this.myChart.convertToPixel({ xAxisIndex: 0 }, rightStart);
if (pxLeft === null || pxRight === null) {
console.warn('convertToPixel 返回 null 值,跳过绘制边界虚线');
continue;
}
const midX = (pxLeft + pxRight) / 2;
graphics.push({
type: 'line',
shape: { x1: midX, y1: yTopPx, x2: midX, y2: yBottomPx },
style: { stroke: '#000', lineDash: [6, 6], lineWidth: 1 },
silent: true,
z: 100
});
}
// 每段顶部显示 jh(居中),带背景标签并做简单防重叠处理
let lastLabelRight = -Infinity;
let rowShift = 0; // 逐行上移避免覆盖
segments.forEach((seg, idx) => {
if (!seg.jh) return;
const pxStart = this.myChart.convertToPixel({ xAxisIndex: 0 }, seg.startIdx);
const pxEnd = this.myChart.convertToPixel({ xAxisIndex: 0 }, seg.endIdx);
if (pxStart === null || pxEnd === null) {
console.warn('convertToPixel 返回 null 值,跳过绘制井号标签');
return;
}
const midX = (pxStart + pxEnd) / 2;
let topY = yTopPx - 30; // 再上移,避免遮挡
// 估算标签宽度用于避免与上一个重叠
const fontSize = 12;
const paddingH = 6;
const estimatedWidth = seg.jh.length * fontSize * 0.6 + paddingH * 2 + 10;
const labelLeft = midX - estimatedWidth / 2;
const labelRight = midX + estimatedWidth / 2;
if (labelLeft < lastLabelRight) {
rowShift += 18; // 叠一行
} else {
rowShift = 0;
}
lastLabelRight = Math.max(lastLabelRight, labelRight);
topY -= rowShift;
const labelWidth = Math.max(estimatedWidth, 80);
const labelHeight = 22;
const pointerSize = 6;
graphics.push({
type: 'group',
x: midX - labelWidth / 2,
y: topY - labelHeight,
z: 101,
silent: true,
children: [
{
type: 'rect',
shape: { x: 0, y: 0, width: labelWidth, height: labelHeight, r: 8 },
style: {
fill: '#2563eb',
stroke: '#1e40af',
lineWidth: 1.5,
shadowBlur: 6,
shadowColor: 'rgba(37,99,235,0.35)'
}
},
{
type: 'polygon',
shape: {
points: [
[labelWidth / 2 - pointerSize, labelHeight],
[labelWidth / 2 + pointerSize, labelHeight],
[labelWidth / 2, labelHeight + pointerSize]
]
},
style: { fill: '#2563eb', stroke: '#1e40af' }
},
{
type: 'text',
style: {
x: labelWidth / 2,
y: labelHeight / 2,
text: seg.jh,
fill: '#fff',
fontSize: fontSize + 1,
fontWeight: 700,
align: 'center',
verticalAlign: 'middle'
}
}
]
});
});
// 叠加到现有 graphic 上(保留原有 graphic)
const prevElements = Array.isArray(this.currentGraphicElements) ? this.currentGraphicElements : [];
const merged = prevElements.concat(graphics);
this.currentGraphicElements = merged;
this.myChart.setOption({ graphic: { elements: merged } });
} }
}, },
}; };
...@@ -697,7 +955,40 @@ export default { ...@@ -697,7 +955,40 @@ export default {
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
/* position: relative; */ position: relative;
}
/* 井号显示样式 */
.well-number-display {
position: absolute;
top: 16px;
left: 16px;
z-index: 5;
background: transparent;
padding: 8px 12px;
display: flex;
align-items: center;
gap: 6px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
transition: all 0.3s ease;
opacity: 0.9;
}
.well-number-display:hover {
opacity: 1;
}
.well-label {
color: #6b7280;
font-size: 13px;
font-weight: 500;
white-space: nowrap;
}
.well-number {
color: #3b82f6;
font-size: 14px;
font-weight: 600;
} }
/* 图表容器样式 */ /* 图表容器样式 */
......
...@@ -54,26 +54,111 @@ export default { ...@@ -54,26 +54,111 @@ export default {
}; };
}, },
created() { created() {
// 获取路由参数 // 获取路由参数(使用query)
console.log('详情页面created,完整路由对象:', this.$route); console.log('详情页面created,完整路由对象:', this.$route);
const { id, jh, famc, qk, jhs } = this.$route.params; let { id, jh, famc, qk, jhs } = this.$route.query || {};
console.log('路由参数:', { id, jh, famc, qk, jhs }); console.log('路由query参数:', { id, jh, famc, qk, jhs });
// 优先使用query,其次使用sessionStorage
if (!jh || jh === 'undefined' || jh === 'null') {
try {
const cached = JSON.parse(sessionStorage.getItem('djxxDetailParams') || '{}');
({ id, jh, famc, qk, jhs } = { ...cached, ...this.$route.query });
console.log('使用缓存参数:', { id, jh, famc, qk, jhs });
} catch (e) {
console.warn('读取缓存失败', e);
}
}
// 检查参数是否为空或undefined
if (jh && jh !== 'undefined' && jh !== 'null') { if (jh && jh !== 'undefined' && jh !== 'null') {
this.queryParams.id = id; this.queryParams.id = id || '';
this.queryParams.jh = jh; this.queryParams.jh = jh || '';
this.queryParams.famc = famc || ''; this.queryParams.famc = famc || '';
this.queryParams.qk = qk || ''; this.queryParams.qk = qk || '';
this.queryParams.jhs = jhs || ''; this.queryParams.jhs = jhs || '';
console.log('设置 queryParams:', this.queryParams); // 缓存参数,便于刷新后保留
sessionStorage.setItem('djxxDetailParams', JSON.stringify(this.queryParams));
console.log('设置并缓存 queryParams:', this.queryParams);
// 进入页面后,按当前激活的tab触发一次加载
this.$nextTick(() => this.refreshActiveTab());
} else { } else {
console.warn('未获取到有效的路由参数 jh,当前参数:', { id, jh, famc, qk, jhs }); console.warn('未获取到有效的参数 jh');
} }
// 确保第一次进入页面时不会自动初始化组件 // 确保第一次进入页面时不会自动初始化组件
console.log('页面初始化完成,等待用户点击tab'); console.log('页面初始化完成,等待用户点击tab');
}, },
activated() {
// 组件被 keep-alive 缓存时,返回本页会触发此钩子
const { id, jh, famc, qk, jhs } = this.$route.query || {};
if (jh && jh !== 'undefined' && jh !== 'null') {
this.queryParams.id = id || '';
this.queryParams.jh = jh || '';
this.queryParams.famc = famc || '';
this.queryParams.qk = qk || '';
this.queryParams.jhs = jhs || '';
sessionStorage.setItem('djxxDetailParams', JSON.stringify(this.queryParams));
this.$nextTick(() => this.refreshActiveTab());
} else {
try {
const cached = JSON.parse(sessionStorage.getItem('djxxDetailParams') || '{}');
if (cached && cached.jh) {
this.queryParams = { ...this.queryParams, ...cached };
this.$nextTick(() => this.refreshActiveTab());
}
} catch (e) { }
}
},
beforeRouteUpdate(to, from, next) {
// 同一路由切换不同 query 时触发
const { id, jh, famc, qk, jhs } = to.query || {};
if (jh && jh !== 'undefined' && jh !== 'null') {
this.queryParams.id = id || '';
this.queryParams.jh = jh || '';
this.queryParams.famc = famc || '';
this.queryParams.qk = qk || '';
this.queryParams.jhs = jhs || '';
sessionStorage.setItem('djxxDetailParams', JSON.stringify(this.queryParams));
this.$nextTick(() => this.refreshActiveTab());
}
next();
},
watch: {
// 当从列表页连续点击"查看"跳转到同一路由时,组件会复用,这里监听路由变化并刷新当前激活tab
'$route.query'(to) {
const { id, jh, famc, qk, jhs } = to || {};
if (jh && jh !== 'undefined' && jh !== 'null') {
this.queryParams.id = id || '';
this.queryParams.jh = jh || '';
this.queryParams.famc = famc || '';
this.queryParams.qk = qk || '';
this.queryParams.jhs = jhs || '';
sessionStorage.setItem('djxxDetailParams', JSON.stringify(this.queryParams));
// 当前就在某个tab上,路由参数变更后需要立刻刷新该tab的数据
this.$nextTick(() => {
if (this.activeTab === 'dataTable') {
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
} else if (this.activeTab === 'curveGraph') {
this.$refs.curveGraphRef && this.$refs.curveGraphRef.loadData && this.$refs.curveGraphRef.loadData();
} else if (this.activeTab === 'histogramGraph') {
this.$refs.histogramGraphRef && this.$refs.histogramGraphRef.loadData && this.$refs.histogramGraphRef.loadData();
}
});
}
}
},
methods: { methods: {
refreshActiveTab() {
// 每次调用都执行loadData
if (this.activeTab === 'dataTable') {
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
} else if (this.activeTab === 'curveGraph') {
this.$refs.curveGraphRef && this.$refs.curveGraphRef.loadData && this.$refs.curveGraphRef.loadData();
} else if (this.activeTab === 'histogramGraph') {
this.$refs.histogramGraphRef && this.$refs.histogramGraphRef.loadData && this.$refs.histogramGraphRef.loadData();
}
},
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
this.loading = true; this.loading = true;
...@@ -105,6 +190,8 @@ export default { ...@@ -105,6 +190,8 @@ export default {
console.log('切换到tab:', tab.name); console.log('切换到tab:', tab.name);
// 标记已经不是第一次加载 // 标记已经不是第一次加载
this.isFirstLoad = false; this.isFirstLoad = false;
// 每次点击tab都调用loadData
if (tab.name === 'dataTable') { if (tab.name === 'dataTable') {
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData(); this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
} else if (tab.name === 'curveGraph') { } else if (tab.name === 'curveGraph') {
......
...@@ -137,7 +137,7 @@ ...@@ -137,7 +137,7 @@
<template slot="footer"> <template slot="footer">
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleWellCancel">取 消</el-button> <el-button @click="handleWellCancel">取 消</el-button>
<el-button type="primary" @click="handleWellSubmit">提 交</el-button> <el-button type="primary" @click="handleWellSubmit">确 定</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
...@@ -322,7 +322,7 @@ export default { ...@@ -322,7 +322,7 @@ export default {
this.$router.push({ this.$router.push({
name: 'DjxxDetail', name: 'DjxxDetail',
params: params query: params
}).then(() => { }).then(() => {
console.log('路由跳转成功'); console.log('路由跳转成功');
}).catch(err => { }).catch(err => {
...@@ -380,6 +380,25 @@ export default { ...@@ -380,6 +380,25 @@ export default {
// 选择邻井 // 选择邻井
handleSelectAdjacentWell() { handleSelectAdjacentWell() {
console.log('点击选择邻井输入框') console.log('点击选择邻井输入框')
// 验证必要参数是否已填写
if (!this.formData.qk) {
this.$message.warning('请先选择区块')
return
}
if (!this.formData.jh) {
this.$message.warning('请先输入井号')
return
}
if (!this.formData.jl) {
this.$message.warning('请先输入距离')
return
}
if (!this.formData.wjsjks || !this.formData.wjsjjs) {
this.$message.warning('请先选择完井时间')
return
}
this.dialogVisible = false this.dialogVisible = false
this.wellDialogVisible = true this.wellDialogVisible = true
......
<template> <template>
<div class="drilling-chart-container" v-loading="loading"> <div class="drilling-chart-container" v-loading="loading">
<!-- 最优值显示区域 - 左上角紧凑版 -->
<div class="optimal-values">
<div class="optimal-item">
<span class="label">机速最优:</span>
<span class="value">{{ (chartData && chartData.optimalValues && chartData.optimalValues.jszy) || '--'
}}</span>
</div>
<div class="optimal-item">
<span class="label">进尺最优:</span>
<span class="value">{{ (chartData && chartData.optimalValues && chartData.optimalValues.jczy) || '--'
}}</span>
</div>
<div class="optimal-item">
<span class="label">综合最优:</span>
<span class="value">{{ (chartData && chartData.optimalValues && chartData.optimalValues.zhzy) || '--'
}}</span>
</div>
</div>
<div id="drillingEfficiencyChartDJ" class="chart"></div> <div id="drillingEfficiencyChartDJ" class="chart"></div>
</div> </div>
</template> </template>
...@@ -53,7 +71,7 @@ export default { ...@@ -53,7 +71,7 @@ export default {
}, },
getList() { getList() {
const params = { zbid: this.zbid,ztccs:this.ztcc ,qk:this.qk}; const params = { zbid: this.zbid, ztccs: this.ztcc, qk: this.qk };
this.loading = true; this.loading = true;
getDjztqxt(params) getDjztqxt(params)
.then(res => { .then(res => {
...@@ -231,10 +249,107 @@ export default { ...@@ -231,10 +249,107 @@ export default {
.drilling-chart-container { .drilling-chart-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: relative;
padding: 20px; padding: 20px;
box-sizing: border-box; box-sizing: border-box;
} }
.optimal-values {
position: absolute;
top: 15px;
left: 15px;
z-index: 10;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 250, 252, 0.95) 100%);
border: 1px solid rgba(64, 158, 255, 0.15);
border-radius: 4px;
padding: 6px 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.6);
backdrop-filter: blur(8px);
min-width: 120px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.optimal-values:hover {
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.12), 0 1px 4px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.8);
border-color: rgba(64, 158, 255, 0.25);
}
.optimal-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 3px;
font-size: 10px;
padding: 2px 4px;
border-radius: 3px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
}
.optimal-item:last-child {
margin-bottom: 0;
}
.optimal-item:hover {
background: linear-gradient(135deg, rgba(64, 158, 255, 0.08) 0%, rgba(103, 194, 58, 0.08) 100%);
transform: translateX(2px);
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
}
.optimal-item::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 0;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
border-radius: 2px;
transition: height 0.2s ease;
}
.optimal-item:hover::before {
height: 60%;
}
.optimal-item .label {
color: #5a5e66;
font-weight: 500;
margin-right: 6px;
font-size: 9px;
letter-spacing: 0.1px;
opacity: 0.9;
}
.optimal-item .value {
color: #2c3e50;
font-weight: 700;
font-size: 10px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
position: relative;
}
.optimal-item .value::after {
content: '';
position: absolute;
bottom: -1px;
left: 0;
width: 100%;
height: 1px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
opacity: 0;
transition: opacity 0.2s ease;
}
.optimal-item:hover .value::after {
opacity: 0.3;
}
.chart { .chart {
width: 100%; width: 100%;
height: calc(100vh - 220px); height: calc(100vh - 220px);
......
...@@ -3,15 +3,13 @@ ...@@ -3,15 +3,13 @@
<div class="app-container"> <div class="app-container">
<el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick" style="margin-top: -10px;"> <el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick" style="margin-top: -10px;">
<el-tab-pane label="数据表格" name="dataTable"> <el-tab-pane label="数据表格" name="dataTable">
<DataTable ref="dataTableRef" :jh="queryParams.jh" :famc="queryParams.famc" :qk="queryParams.qk" :ztcc="queryParams.ztcc" <DataTable ref="dataTableRef" :jh="queryParams.jh" :famc="queryParams.famc" :qk="queryParams.qk"
:jhs="queryParams.jhs" /> :ztcc="queryParams.ztcc" :jhs="queryParams.jhs" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="曲线图形" name="curveGraph"> <el-tab-pane label="曲线图形" name="curveGraph">
<CurveGraph ref="curveGraphRef" :jh="queryParams.jh" :famc="queryParams.famc" :qk="queryParams.qk" <CurveGraph ref="curveGraphRef" :jh="queryParams.jh" :famc="queryParams.famc" :qk="queryParams.qk"
:jhs="queryParams.jhs" :zbid="queryParams.zbid" :ztcc="queryParams.ztcc" /> :jhs="queryParams.jhs" :zbid="queryParams.zbid" :ztcc="queryParams.ztcc" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
...@@ -42,8 +40,8 @@ export default { ...@@ -42,8 +40,8 @@ export default {
famc: '', famc: '',
qk: '', qk: '',
jhs: '', jhs: '',
ztcc:'', ztcc: '',
zbid:'' zbid: ''
}, },
// 标记是否是第一次进入页面 // 标记是否是第一次进入页面
isFirstLoad: true isFirstLoad: true
...@@ -52,8 +50,8 @@ export default { ...@@ -52,8 +50,8 @@ export default {
created() { created() {
// 获取路由参数 // 获取路由参数
console.log('详情页面created,完整路由对象:', this.$route); console.log('详情页面created,完整路由对象:', this.$route);
const { jh, famc, qk, jhs ,ztcc,zbid} = this.$route.params; const { jh, famc, qk, jhs, ztcc, zbid } = this.$route.params;
console.log('路由参数:', { jh, famc, qk, jhs,ztcc ,zbid}); console.log('路由参数:', { jh, famc, qk, jhs, ztcc, zbid });
// 检查参数是否为空或undefined // 检查参数是否为空或undefined
// if (jh && jh !== 'undefined' && jh !== 'null') { // if (jh && jh !== 'undefined' && jh !== 'null') {
...@@ -61,8 +59,8 @@ export default { ...@@ -61,8 +59,8 @@ export default {
this.queryParams.famc = famc || ''; this.queryParams.famc = famc || '';
this.queryParams.qk = qk || ''; this.queryParams.qk = qk || '';
this.queryParams.jhs = jhs || ''; this.queryParams.jhs = jhs || '';
this.queryParams.ztcc= ztcc||'' this.queryParams.ztcc = ztcc || ''
this.queryParams.zbid= zbid||'' this.queryParams.zbid = zbid || ''
console.log('设置 queryParams:', this.queryParams); console.log('设置 queryParams:', this.queryParams);
// } else { // } else {
// console.warn('未获取到有效的路由参数 jh,当前参数:', { jh, famc, qk, jhs,ztcc }); // console.warn('未获取到有效的路由参数 jh,当前参数:', { jh, famc, qk, jhs,ztcc });
...@@ -114,13 +112,11 @@ export default { ...@@ -114,13 +112,11 @@ export default {
// 标记已经不是第一次加载 // 标记已经不是第一次加载
this.isFirstLoad = false; this.isFirstLoad = false;
// 只有在用户主动点击tab时才加载数据,避免初始化时的自动加载 // 每次点击tab都调用loadData
if (tab.name === 'dataTable') { if (tab.name === 'dataTable') {
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData(); this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
} else if (tab.name === 'curveGraph') { } else if (tab.name === 'curveGraph') {
this.$refs.curveGraphRef && this.$refs.curveGraphRef.loadData && this.$refs.curveGraphRef.loadData(); this.$refs.curveGraphRef && this.$refs.curveGraphRef.loadData && this.$refs.curveGraphRef.loadData();
} else if (tab.name === 'histogramGraph') {
this.$refs.histogramGraphRef && this.$refs.histogramGraphRef.loadData && this.$refs.histogramGraphRef.loadData();
} }
} }
} }
......
...@@ -23,13 +23,14 @@ ...@@ -23,13 +23,14 @@
<!-- 表格区域 --> <!-- 表格区域 -->
<el-table :data="tableData" border stripe v-loading="loading" style="width: 100%; height: calc(100vh - 230px)"> <el-table :data="tableData" border stripe v-loading="loading" style="width: 100%; height: calc(100vh - 230px)">
<el-table-column prop="qk" label="区块" min-width="120"></el-table-column> <el-table-column prop="qk" label="区块" align="center" min-width="120"></el-table-column>
<el-table-column prop="famc" label="方案名称" min-width="200" align="center" show-overflow-tooltip sortable /> <el-table-column prop="famc" label="方案名称" align="center" min-width="200" show-overflow-tooltip sortable />
<el-table-column prop="ztcc" label="钻头尺寸" min-width="150"></el-table-column> <el-table-column prop="ztcc" label="钻头尺寸" align="center" min-width="150"></el-table-column>
<el-table-column prop="dc" label="地层" min-width="150"></el-table-column> <el-table-column prop="dc" label="地层" align="center" min-width="150"></el-table-column>
<el-table-column prop="yxzt" label="优选钻头" min-width="200" align="center" show-overflow-tooltip sortable /> <el-table-column prop="yxzt" label="优选钻头" align="center" min-width="200" show-overflow-tooltip sortable />
<el-table-column prop="bz" label="备注" min-width="200" show-overflow-tooltip></el-table-column> <el-table-column prop="bz" label="备注" align="center" min-width="200"
show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="150" fixed="right"> <el-table-column label="操作" width="150" fixed="right">
<template #default="scope"> <template #default="scope">
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">查看</el-button> <el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">查看</el-button>
...@@ -47,28 +48,34 @@ ...@@ -47,28 +48,34 @@
@current-change="handleCurrentChange" background /> @current-change="handleCurrentChange" background />
<!-- 新增/编辑对话框 --> <!-- 新增/编辑对话框 -->
<el-dialog :title="dialogTitle" width="600px" :close-on-click-modal="false" :visible.sync="dialogVisible"> <el-dialog :title="dialogTitle" width="900px" :close-on-click-modal="false" :visible.sync="dialogVisible">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px"> <el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="方案名称" prop="famc"> <el-form-item label="方案名称" prop="famc">
<el-input v-model="formData.famc" placeholder="请输入方案名称" /> <el-input v-model="formData.famc" placeholder="请输入方案名称" />
</el-form-item> </el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="区块" prop="qk"> <el-form-item label="区块" prop="qk">
<el-select v-model="formData.qk" placeholder="请选择区块名称" clearable filterable style="width: 100%;"> <el-select v-model="formData.qk" placeholder="请选择区块名称" clearable filterable
style="width: 100%;">
<el-option v-for="item in blockOptions" :key="item.qk" :label="item.qk" :value="item.qk" <el-option v-for="item in blockOptions" :key="item.qk" :label="item.qk" :value="item.qk"
v-if="item && item.qk" style="width: 100%;" /> v-if="item && item.qk" style="width: 100%;" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="钻头尺寸" prop="ztcc"> </el-col>
<el-select v-model="formData.ztcc" multiple filterable allow-create default-first-option </el-row>
placeholder="请选择或输入钻头尺寸" style="width: 100%" :loading="ztxxLoading"> <el-row>
<el-option v-for="item in ztxxOptions" :key="item.value" :label="item.label" <el-col :span="12">
:value="item.value" /> <el-form-item label="完井时间" prop="wjsjks" required>
</el-select> <el-date-picker v-model="formData.wjsjks" type="year" placeholder="选择年份" value-format="yyyy"
style="width: 50%;" />
<el-date-picker v-model="formData.wjsjjs" type="year" placeholder="选择年份" value-format="yyyy"
style="width: 50%;" />
</el-form-item> </el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="层位" prop="cw"> <el-form-item label="层位" prop="cw">
<el-input v-if="!showCascader" v-model="formData.cw" readonly style="width: 100%;"> <el-input v-if="!showCascader" v-model="formData.cw" readonly style="width: 100%;">
<template slot="append"> <template slot="append">
...@@ -81,9 +88,24 @@ ...@@ -81,9 +88,24 @@
style="width: 200px;" popper-class="cascader-popper"> style="width: 200px;" popper-class="cascader-popper">
</el-cascader> </el-cascader>
</el-form-item> </el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="钻头尺寸" prop="ztcc">
<el-select v-model="formData.ztcc" multiple filterable allow-create default-first-option
placeholder="请选择或输入钻头尺寸" style="width: 100%" :loading="ztxxLoading">
<el-option v-for="item in ztxxOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="bz"> <el-form-item label="备注" prop="bz">
<el-input v-model="formData.bz" type="textarea" :rows="3" placeholder="请输入备注信息"></el-input> <el-input v-model="formData.bz" type="textarea" :rows="3" placeholder="请输入备注信息"></el-input>
</el-form-item> </el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
...@@ -144,6 +166,8 @@ export default { ...@@ -144,6 +166,8 @@ export default {
cwid: null, // 层位ID cwid: null, // 层位ID
mdcid: null, // 目的层ID mdcid: null, // 目的层ID
dzsdmc: '', // 地质时代名称 dzsdmc: '', // 地质时代名称
wjsjks: (new Date().getFullYear() - 4).toString(), // 完井开始年份默认近五年
wjsjjs: new Date().getFullYear().toString(), // 完井结束年份默认当前年
bz: '' bz: ''
}, },
// 表单验证规则 // 表单验证规则
...@@ -158,9 +182,19 @@ export default { ...@@ -158,9 +182,19 @@ export default {
ztxxLoading: false, ztxxLoading: false,
} }
}, },
watch: {
'formData.qk'() {
this.updateZtccOptionsIfReady()
},
'formData.wjsjks'() {
this.updateZtccOptionsIfReady()
},
'formData.wjsjjs'() {
this.updateZtccOptionsIfReady()
}
},
created() { created() {
this.getBlockOptions(); this.getBlockOptions();
this.getZtxxOptions();
this.getList(); this.getList();
}, },
mounted() { mounted() {
...@@ -171,7 +205,7 @@ export default { ...@@ -171,7 +205,7 @@ export default {
async handleView(row) { async handleView(row) {
try { try {
const res = await getDjzt(row.id) const res = await getDjzt(row.id)
console.log(res,55555); console.log(res, 55555);
if (res.code === 200) { if (res.code === 200) {
// 将获取到的详细信息传递给详情页面 // 将获取到的详细信息传递给详情页面
const params = { const params = {
...@@ -254,6 +288,8 @@ export default { ...@@ -254,6 +288,8 @@ export default {
this.showCascader = false; this.showCascader = false;
// 强制更新视图 // 强制更新视图
this.$forceUpdate(); this.$forceUpdate();
// 层位选择完成后尝试加载钻头尺寸
this.updateZtccOptionsIfReady();
}, 100); }, 100);
} else { } else {
this.showCascader = false; this.showCascader = false;
...@@ -382,15 +418,16 @@ export default { ...@@ -382,15 +418,16 @@ export default {
}); });
}, },
/** 获取钻头信息下拉选项 */ /** 获取钻头信息下拉选项 */
getZtxxOptions() { getZtxxOptions(queryParams) {
this.ztxxLoading = true; // 开始加载 this.ztxxLoading = true; // 开始加载
selectZtccList().then(response => { selectZtccList(queryParams).then(response => {
console.log(response,22222);
if (response.code === 200 && response.data && Array.isArray(response.data)) { if (response.code === 200 && response.data && Array.isArray(response.data)) {
this.ztxxOptions = response.data.map(item => ({ this.ztxxOptions = response.data.map(item => ({
value: item, value: item,
label: item label: item
})) }))
} else {
this.ztxxOptions = []
} }
}).catch(error => { }).catch(error => {
console.error('获取钻头信息选项失败:', error) console.error('获取钻头信息选项失败:', error)
...@@ -399,6 +436,14 @@ export default { ...@@ -399,6 +436,14 @@ export default {
this.ztxxLoading = false; // 加载完成 this.ztxxLoading = false; // 加载完成
}); });
}, },
// 条件满足后再请求钻头尺寸
updateZtccOptionsIfReady() {
const { qk, wjsjks, wjsjjs, cwid, mdcid } = this.formData;
if (qk && wjsjks && wjsjjs && (cwid || mdcid)) {
const params = { qk, wjsjks, wjsjjs, cwid: cwid || undefined, mdcid: mdcid || undefined };
this.getZtxxOptions(params);
}
},
// 获取表格数据 // 获取表格数据
async getTableData() { async getTableData() {
this.loading = true this.loading = true
...@@ -448,7 +493,7 @@ export default { ...@@ -448,7 +493,7 @@ export default {
this.resetForm("formData"); this.resetForm("formData");
this.showCascader = false; this.showCascader = false;
this.cascaderValue = []; // 重置 cascaderValue this.cascaderValue = []; // 重置 cascaderValue
this.getZtxxOptions(); // 重新获取钻头信息选项 this.ztxxOptions = []; // 清空钻头信息选项,等待条件满足后再加载
}, },
// 新增 // 新增
...@@ -462,9 +507,13 @@ export default { ...@@ -462,9 +507,13 @@ export default {
cwid: null, // 层位ID cwid: null, // 层位ID
mdcid: null, // 目的层ID mdcid: null, // 目的层ID
dzsdmc: '', // 地质时代名称 dzsdmc: '', // 地质时代名称
wjsjks: (new Date().getFullYear() - 4).toString(),
wjsjjs: new Date().getFullYear().toString(),
bz: '' bz: ''
} }
this.dialogVisible = true this.dialogVisible = true
// 新增打开时尝试基于默认年份加载(需等区块与层位选择后)
this.ztxxOptions = []
}, },
// 编辑 // 编辑
...@@ -478,10 +527,14 @@ export default { ...@@ -478,10 +527,14 @@ export default {
cwid: row.cwid || null, // 层位ID cwid: row.cwid || null, // 层位ID
mdcid: row.mdcid || null, // 目的层ID mdcid: row.mdcid || null, // 目的层ID
dzsdmc: row.dzsdmc || '', // 地质时代名称 dzsdmc: row.dzsdmc || '', // 地质时代名称
wjsjks: row.wjsjks || (new Date().getFullYear() - 4).toString(),
wjsjjs: row.wjsjjs || new Date().getFullYear().toString(),
bz: row.bz, bz: row.bz,
famc:row.famc famc: row.famc
} }
this.dialogVisible = true this.dialogVisible = true
// 编辑时若条件已满足,立即加载钻头尺寸
this.updateZtccOptionsIfReady()
}, },
// 删除 // 删除
......
<template> <template>
<div class="drilling-chart-container"> <div class="drilling-chart-container">
<div id="drillingEfficiencyChart" class="chart"></div> <div id="drillingEfficiencyChart" class="chart"></div>
<!-- 最优值显示区域 - 图表内部左上角 -->
<div class="optimal-values">
<div class="optimal-item">
<span class="label">机速最优:</span>
<span class="value">{{ (chartData && chartData.optimalValues && chartData.optimalValues.jszy) || '--'
}}</span>
</div>
<div class="optimal-item">
<span class="label">进尺最优:</span>
<span class="value">{{ (chartData && chartData.optimalValues && chartData.optimalValues.jczy) || '--'
}}</span>
</div>
<div class="optimal-item">
<span class="label">综合最优:</span>
<span class="value">{{ (chartData && chartData.optimalValues && chartData.optimalValues.zhzy) || '--'
}}</span>
</div>
</div>
</div> </div>
</template> </template>
...@@ -246,10 +264,107 @@ export default { ...@@ -246,10 +264,107 @@ export default {
.drilling-chart-container { .drilling-chart-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
/* padding: 20px; */ position: relative;
box-sizing: border-box; box-sizing: border-box;
} }
.optimal-values {
position: absolute;
top: 5px;
left: 5px;
z-index: 10;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 250, 252, 0.95) 100%);
border: 1px solid rgba(64, 158, 255, 0.15);
border-radius: 4px;
padding: 4px 8px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.6);
backdrop-filter: blur(6px);
min-width: 120px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.optimal-values:hover {
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12), 0 3px 8px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.8);
transform: translateY(-2px);
border-color: rgba(64, 158, 255, 0.25);
}
.optimal-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2px;
font-size: 10px;
padding: 1px 4px;
border-radius: 3px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
}
.optimal-item:last-child {
margin-bottom: 0;
}
.optimal-item:hover {
background: linear-gradient(135deg, rgba(64, 158, 255, 0.08) 0%, rgba(103, 194, 58, 0.08) 100%);
transform: translateX(2px);
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
}
.optimal-item::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 0;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
border-radius: 2px;
transition: height 0.2s ease;
}
.optimal-item:hover::before {
height: 60%;
}
.optimal-item .label {
color: #5a5e66;
font-weight: 500;
margin-right: 6px;
font-size: 10px;
letter-spacing: 0.1px;
opacity: 0.9;
}
.optimal-item .value {
color: #2c3e50;
font-weight: 700;
font-size: 10px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
position: relative;
}
.optimal-item .value::after {
content: '';
position: absolute;
bottom: -1px;
left: 0;
width: 100%;
height: 1px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
opacity: 0;
transition: opacity 0.2s ease;
}
.optimal-item:hover .value::after {
opacity: 0.3;
}
.chart { .chart {
width: 100%; width: 100%;
height: calc(100vh - 220px); height: calc(100vh - 220px);
......
<template> <template>
<div class="chart-container"> <div class="chart-container">
<!-- 井号显示 -->
<div v-if="jh" class="well-number-display">
<span class="well-label">井号:</span>
<span class="well-number">{{ jh }}</span>
</div>
<div id="mainzft" class="chart" ref="chartRef"></div> <div id="mainzft" class="chart" ref="chartRef"></div>
<div v-if="loading" class="loading-overlay"> <div v-if="loading" class="loading-overlay">
<div class="loading-spinner"></div> <div class="loading-spinner"></div>
...@@ -259,6 +265,10 @@ export default { ...@@ -259,6 +265,10 @@ export default {
this.setChartDimensions(chartDom); this.setChartDimensions(chartDom);
} }
this.myChart.resize(); this.myChart.resize();
// 重新绘制地层标签,确保在缩放/尺寸变化后位置正确
if (this.lastStackedAreas && this.lastChartConfig && this.lastXAxisLabels) {
this.drawStratumLabels(this.lastStackedAreas, this.lastChartConfig, this.lastXAxisLabels);
}
} }
}, },
...@@ -290,6 +300,11 @@ export default { ...@@ -290,6 +300,11 @@ export default {
// 确保图表完全渲染后再resize // 确保图表完全渲染后再resize
this.$nextTick(() => { this.$nextTick(() => {
this.myChart.resize(); this.myChart.resize();
// 存储用于重绘的数据并绘制一次
this.lastStackedAreas = wellData.stackedAreas;
this.lastChartConfig = mockData.chartConfig;
this.lastXAxisLabels = xAxisLabels;
this.drawStratumLabels(this.lastStackedAreas, this.lastChartConfig, this.lastXAxisLabels);
}); });
} catch (error) { } catch (error) {
...@@ -319,10 +334,10 @@ export default { ...@@ -319,10 +334,10 @@ export default {
extraCssText: 'box-shadow: 0 4px 12px rgba(0,0,0,0.15); border-radius: 8px;' extraCssText: 'box-shadow: 0 4px 12px rgba(0,0,0,0.15); border-radius: 8px;'
}, },
grid: { grid: {
top: 30, top: 10,
left: "2%", left: "4%",
right: "2%", right: "4%",
bottom: "2%", bottom: "5%",
containLabel: true, containLabel: true,
show: false, show: false,
}, },
...@@ -553,7 +568,7 @@ export default { ...@@ -553,7 +568,7 @@ export default {
barWidth: "6%", barWidth: "6%",
label: { label: {
show: true, show: true,
position: (params) => params.data <= 200 ? "top" : "inside", position: 'insideTop',
color: '#fff', color: '#fff',
fontSize: 11, fontSize: 11,
fontWeight: 600, fontWeight: 600,
...@@ -562,6 +577,10 @@ export default { ...@@ -562,6 +577,10 @@ export default {
borderRadius: 4, borderRadius: 4,
borderColor: 'rgba(255,255,255,0.3)', borderColor: 'rgba(255,255,255,0.3)',
borderWidth: 1, borderWidth: 1,
formatter: (params) => {
const di = wellData.depthIntervals[params.dataIndex];
return di && di.ztcc !== undefined ? di.ztcc : params.data;
}
}, },
itemStyle: { itemStyle: {
color: { color: {
...@@ -599,6 +618,33 @@ export default { ...@@ -599,6 +618,33 @@ export default {
}, },
data: wellData.depthIntervals.map((item) => item.interval), data: wellData.depthIntervals.map((item) => item.interval),
}, },
// 底部显示 placeholder 数值的透明条,用于放置底部标签
{
name: '深度区间-底部标签',
type: 'bar',
barGap: '-100%',
barWidth: '6%',
itemStyle: { color: 'transparent', borderColor: 'transparent' },
emphasis: { itemStyle: { color: 'transparent', borderColor: 'transparent' } },
label: {
show: true,
position: 'insideBottom',
color: '#fff',
fontSize: 11,
fontWeight: 600,
backgroundColor: 'rgba(0,0,0,0.1)',
padding: [2, 3],
borderRadius: 4,
borderColor: 'rgba(255,255,255,0.3)',
borderWidth: 1,
distance: 0,
formatter: (params) => {
const di = wellData.depthIntervals[params.dataIndex];
return di && di.interval !== undefined ? di.interval : params.data;
}
},
data: wellData.depthIntervals.map((item) => item.interval)
},
...areaSeries, ...areaSeries,
]; ];
}, },
...@@ -676,6 +722,64 @@ export default { ...@@ -676,6 +722,64 @@ export default {
}; };
img.src = svgUrl; img.src = svgUrl;
}); });
},
// 使用像素坐标绘制地层标签,精确对齐
drawStratumLabels(stackedAreas, chartConfig, xAxisLabels) {
if (!this.myChart || !stackedAreas || stackedAreas.length === 0) return;
const totalDepth = chartConfig.yAxis.max - chartConfig.yAxis.min;
let currentDepth = chartConfig.yAxis.min;
// 清理旧的 graphic
this.myChart.setOption({ graphic: [] });
const graphics = [];
const lastXIndex = Math.max(0, (xAxisLabels?.length || 1) - 1);
const xOffset = 16; // 与图形右边缘的间距
stackedAreas.forEach((area) => {
if (!area.points || area.points.length === 0) return;
const thickness = area.points[0].y;
const centerDepth = currentDepth + thickness / 2;
// 将值坐标转换为像素坐标(使用最右一个类目,确保靠近右侧)
const pixelRight = this.myChart.convertToPixel({ xAxisIndex: 0, yAxisIndex: 0 }, [lastXIndex, centerDepth]);
if (!pixelRight || !Array.isArray(pixelRight) || pixelRight.length < 2) {
console.warn('convertToPixel 返回无效值:', pixelRight);
return;
}
const [pxRight, py] = pixelRight;
graphics.push({
type: 'text',
position: [pxRight + xOffset, py],
style: {
text: area.name,
fontSize: 12,
fontWeight: 600,
fill: '#333',
backgroundColor: 'transparent',
padding: [0, 0],
borderRadius: 0,
lineWidth: 0,
stroke: 'transparent',
align: 'left',
verticalAlign: 'middle'
},
// anchor 让文本垂直居中
origin: [0, 0],
z: 10,
// 使用 position 计算,避免随缩放偏移
bounding: 'raw',
silent: true
});
currentDepth += thickness;
});
this.myChart.setOption({ graphic: graphics });
} }
}, },
}; };
...@@ -694,6 +798,39 @@ export default { ...@@ -694,6 +798,39 @@ export default {
position: relative; position: relative;
} }
/* 井号显示样式 */
.well-number-display {
position: absolute;
top: 16px;
left: 16px;
z-index: 5;
background: transparent;
padding: 8px 12px;
display: flex;
align-items: center;
gap: 6px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
transition: all 0.3s ease;
opacity: 0.9;
}
.well-number-display:hover {
opacity: 1;
}
.well-label {
color: #6b7280;
font-size: 13px;
font-weight: 500;
white-space: nowrap;
}
.well-number {
color: #3b82f6;
font-size: 14px;
font-weight: 600;
}
/* 图表容器样式 */ /* 图表容器样式 */
.chart { .chart {
flex: 1; flex: 1;
...@@ -744,8 +881,13 @@ export default { ...@@ -744,8 +881,13 @@ export default {
} }
@keyframes spin { @keyframes spin {
0% { transform: rotate(0deg); } 0% {
100% { transform: rotate(360deg); } transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
} }
/* 响应式优化 */ /* 响应式优化 */
...@@ -758,6 +900,20 @@ export default { ...@@ -758,6 +900,20 @@ export default {
min-height: 300px; min-height: 300px;
border-radius: 12px; border-radius: 12px;
} }
.well-number-display {
top: 8px;
left: 8px;
padding: 6px 10px;
}
.well-label {
font-size: 11px;
}
.well-number {
font-size: 12px;
}
} }
/* 深色模式支持 */ /* 深色模式支持 */
...@@ -767,7 +923,8 @@ export default { ...@@ -767,7 +923,8 @@ export default {
/* box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); */ /* box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); */
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.1);
} }
/*
/*
.chart:hover { .chart:hover {
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5); box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
} */ } */
...@@ -775,12 +932,35 @@ export default { ...@@ -775,12 +932,35 @@ export default {
.loading-overlay { .loading-overlay {
background: rgba(17, 24, 39, 0.95); background: rgba(17, 24, 39, 0.95);
} }
.well-number-display {
background: transparent;
}
.well-number-display:hover {
background: transparent;
}
.well-label {
color: #6b7280;
}
.well-number {
color: #3b82f6;
}
} }
/* 动画效果 */ /* 动画效果 */
@keyframes fadeIn { @keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); } from {
to { opacity: 1; transform: translateY(0); } opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
} }
.chart-container { .chart-container {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleImport2">导入las文件</el-button> <el-button type="primary" @click="handleImport2">导入las文件</el-button>
<el-button type="primary" @click="handleExport">导出</el-button> <el-button type="primary" @click="handleExport">导出</el-button>
<el-button type="primary" @click="handleImport">导入</el-button> <el-button type="primary" @click="handleImport">导入Excel</el-button>
<el-button type="primary" @click="cjsz">设置</el-button> <el-button type="primary" @click="cjsz">设置</el-button>
<el-button type="primary" @click="jscs">计算参数</el-button> <el-button type="primary" @click="jscs">计算参数</el-button>
<el-button type="primary" @click="js">计算</el-button> <el-button type="primary" @click="js">计算</el-button>
...@@ -21,7 +21,12 @@ ...@@ -21,7 +21,12 @@
<!-- <el-button type="warning" plain icon="el-icon-download" size="mini" <!-- <el-button type="warning" plain icon="el-icon-download" size="mini"
@click="handleExport">导出</el-button> --> @click="handleExport">导出</el-button> -->
</el-form-item> </el-form-item>
<right-toolbar :search="false" :show-refresh="false" :showSearch.sync="showSearch"
@queryTable="handleCjData" :columns="columns" @columns-change="onColumnsChange" />
</el-form> </el-form>
<div style="background-color: #fff;"> <div style="background-color: #fff;">
<!-- <el-form style="background-color: #fff" ref="queryForm" size="small" :inline="true" v-show="showSearch" <!-- <el-form style="background-color: #fff" ref="queryForm" size="small" :inline="true" v-show="showSearch"
label-width="68px"> label-width="68px">
...@@ -37,8 +42,9 @@ ...@@ -37,8 +42,9 @@
}" :header-cell-class-name="'table-header'" :cell-style="{ }" :header-cell-class-name="'table-header'" :cell-style="{
padding: '1px 0' padding: '1px 0'
}" :tooltip-effect="'dark'" header-overflow-tooltip v-loading="loading"> }" :tooltip-effect="'dark'" header-overflow-tooltip v-loading="loading">
<el-table-column v-for="(col, index) in tableColumns" :key="index" :label="col.label" :prop="col.prop" <el-table-column v-for="(col, index) in filteredTableColumns" :key="index" :label="col.label"
:width="col.width || 120" align="center" show-overflow-tooltip :render-header="renderTableHeader" /> :prop="col.prop" :width="col.width || 120" align="center" show-overflow-tooltip
:render-header="renderTableHeader" />
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" :page.sync="cjqueryParams.pageNum" <pagination v-show="total > 0" :total="total" :page.sync="cjqueryParams.pageNum"
:limit.sync="cjqueryParams.pageSize" @pagination="handleCjData" /> :limit.sync="cjqueryParams.pageSize" @pagination="handleCjData" />
...@@ -269,6 +275,8 @@ export default { ...@@ -269,6 +275,8 @@ export default {
}, },
openjscs: false, openjscs: false,
showSearch: true, showSearch: true,
// 显隐列配置(配合 RightToolbar)
columns: [],
total: 0, total: 0,
cjsjLasList: [], cjsjLasList: [],
form: {}, form: {},
...@@ -389,6 +397,13 @@ export default { ...@@ -389,6 +397,13 @@ export default {
] ]
}; };
}, },
computed: {
// 过滤出可见列供模板渲染,避免 v-for 搭配 v-if
filteredTableColumns() {
if (!Array.isArray(this.columns) || this.columns.length === 0) return this.tableColumns;
return this.tableColumns.filter((_, idx) => this.columns[idx] ? this.columns[idx].visible !== false : true);
}
},
mounted() { mounted() {
this.cjqueryParams = { this.cjqueryParams = {
pageNum: 1, pageNum: 1,
...@@ -396,6 +411,8 @@ export default { ...@@ -396,6 +411,8 @@ export default {
jh: this.jh || this.$route.query.jh jh: this.jh || this.$route.query.jh
} }
this.handleCjData(); this.handleCjData();
// 初始化显隐列(默认全部显示)
this.columns = this.tableColumns.map((col, idx) => ({ key: idx, label: col.label, visible: true }));
}, },
watch: { watch: {
activeTab: { activeTab: {
...@@ -417,6 +434,11 @@ export default { ...@@ -417,6 +434,11 @@ export default {
} }
}, },
methods: { methods: {
onColumnsChange({ index, visible }) {
if (Array.isArray(this.columns) && this.columns[index]) {
this.$set(this.columns[index], 'visible', visible);
}
},
TableHeight() { TableHeight() {
const windowHeight = window.innerHeight; const windowHeight = window.innerHeight;
const topBarHeight = 130; const topBarHeight = 130;
...@@ -735,4 +757,12 @@ export default { ...@@ -735,4 +757,12 @@ export default {
overflow: hidden !important; overflow: hidden !important;
text-overflow: ellipsis !important; text-overflow: ellipsis !important;
} }
/* 顶部右侧容器,放置列设置按钮 */
.columns-top-right {
display: flex;
justify-content: flex-end;
align-items: center;
padding: 0 10px 6px 10px;
}
</style> </style>
...@@ -10,6 +10,18 @@ ...@@ -10,6 +10,18 @@
<svg class="trackSvg2"></svg> <svg class="trackSvg2"></svg>
</div> </div>
</div> </div>
<div class="svgContainer">
<div style="display: flex; width: 100%; justify-content: space-around">
<div style="display: flex; flex-direction: column; margin: 10px 0 0 0">
<svg class="trackSvgXs1"></svg>
<div class="svgTitle2">全角变化率</div>
</div>
<div style="display: flex; flex-direction: column; margin: 10px 0 0 0">
<svg class="trackSvgXs3"></svg>
<div class="svgTitle2">井斜</div>
</div>
</div>
</div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="三维视图" name="2" style="height: calc(100vh - 250px)"> <el-tab-pane label="三维视图" name="2" style="height: calc(100vh - 250px)">
<div style="position: relative"> <div style="position: relative">
...@@ -91,11 +103,9 @@ ...@@ -91,11 +103,9 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" :page-sizes="[20, 50, 80, 100]" @pagination="getList" :limit.sync="queryParams.pageSize" :page-sizes="[20, 50, 80, 100]" @pagination="getList"
class="pagination-fixed" /> class="pagination-fixed" />
<!-- 添加或修改定向井测斜数据计算数据对话框 --> <!-- 添加或修改定向井测斜数据计算数据对话框 -->
<el-dialog :title="title" :visible.sync="open" width="90%" append-to-body> <el-dialog :title="title" :visible.sync="open" width="90%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px"> <el-form ref="form" :model="form" :rules="rules" label-width="120px">
...@@ -235,7 +245,7 @@ import 'echarts-gl' ...@@ -235,7 +245,7 @@ import 'echarts-gl'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { listJskd, getJskd, delJskd, addJskd, updateJskd } from "@/api/system/jskd"; import { listJskd, getJskd, delJskd, addJskd, updateJskd } from "@/api/system/jskd";
import { getBlockName, getQkxl } from "@/api/system/jsaa"; import { getBlockName, getQkxl } from "@/api/system/jsaa";
import { getTwoViews, getThreeViews } from '@/api/optimization/initialization' import { getTwoViews, getThreeViews, getXsViews } from '@/api/optimization/initialization'
import * as d3 from 'd3' import * as d3 from 'd3'
export default { export default {
...@@ -321,6 +331,7 @@ export default { ...@@ -321,6 +331,7 @@ export default {
mounted() { mounted() {
this.getJygjEw(); this.getJygjEw();
this.getJygjSw(); this.getJygjSw();
this.getJygjXs();
window.addEventListener('resize', this.adjustChartSize); window.addEventListener('resize', this.adjustChartSize);
this.adjustChartSize(); this.adjustChartSize();
}, },
...@@ -336,6 +347,7 @@ export default { ...@@ -336,6 +347,7 @@ export default {
this.getList(); this.getList();
this.getJygjEw(); this.getJygjEw();
this.getJygjSw(); this.getJygjSw();
this.getJygjXs();
} }
}, },
immediate: true immediate: true
...@@ -351,6 +363,127 @@ export default { ...@@ -351,6 +363,127 @@ export default {
windowHeight - topBarHeight - componentMargin - tabsMargin windowHeight - topBarHeight - componentMargin - tabsMargin
return tableHeight return tableHeight
}, },
getJygjXs() {
// 获取斜深相关小图(全角变化率/井斜)
if (this.jh) {
getXsViews({ jh: this.jh })
.then((res) => {
if (res && res.code == 200) {
if (res.qjbhlmap && Array.isArray(res.qjbhlmap.data)) {
this.renderSmallCurve(
'.trackSvgXs1',
res.qjbhlmap.data,
res.qjbhlmap.xmin,
res.qjbhlmap.xmax,
res.qjbhlmap.ymax,
res.qjbhlmap.ymin
)
} else {
d3.select('.trackSvgXs1').selectAll('*').remove()
}
if (res.jxmap && Array.isArray(res.jxmap.data)) {
this.renderSmallCurve(
'.trackSvgXs3',
res.jxmap.data,
res.jxmap.xmin,
res.jxmap.xmax,
res.jxmap.ymax,
res.jxmap.ymin
)
} else {
d3.select('.trackSvgXs3').selectAll('*').remove()
}
}
})
.catch((err) => {
// 后端数据存在空值等校验失败时,避免未捕获异常
this.$modal && this.$modal.msgWarning((err && (err.msg || err.message)) || '小图数据获取失败')
d3.select('.trackSvgXs1').selectAll('*').remove()
d3.select('.trackSvgXs3').selectAll('*').remove()
})
}
},
// 通用小曲线渲染
renderSmallCurve(selector, curveData, xmin, xmax, ymax, ymin) {
if (!Array.isArray(curveData) || curveData.length === 0) {
d3.select(selector).selectAll('*').remove()
return
}
// 过滤掉空值点
const safeData = curveData
.filter((d) => d && typeof d.x === 'number' && typeof d.y === 'number' && !isNaN(d.x) && !isNaN(d.y))
if (safeData.length === 0) {
d3.select(selector).selectAll('*').remove()
return
}
xmin = typeof xmin === 'number' ? xmin : d3.min(safeData, (d) => d.x)
xmax = typeof xmax === 'number' ? xmax : d3.max(safeData, (d) => d.x)
ymin = typeof ymin === 'number' ? ymin : d3.min(safeData, (d) => d.y)
ymax = typeof ymax === 'number' ? ymax : d3.max(safeData, (d) => d.y)
const width = this.width
const height = this.height
const marginLeft = this.marginLeft
const marginBottom = this.marginBottom
const marginTop = this.marginTop
d3.select(selector).selectAll('*').remove()
const x = d3.scaleLinear([xmin, xmax], [marginLeft, width])
const y = d3.scaleLinear([ymax, ymin], [height - marginBottom, marginTop])
const svg = d3
.select(selector)
.attr('viewBox', [0, 0, this.svgWidth, height])
.attr('width', '100%')
.attr('height', height)
.attr('style', 'max-width: 100%; height: auto; height: intrinsic; font: 14px sans-serif;')
svg
.append('g')
.attr('transform', `translate(0,${height - marginBottom})`)
.call(
d3.axisBottom(x)
.ticks(25)
.tickSizeOuter(0)
.tickFormat((d, i) => (i % 5 === 0 || d == 0 ? d : ''))
)
.call((g) => g.selectAll('.tick line').clone().attr('y2', -(height - 25)).attr('stroke', (d, i) => (i % 5 === 0 ? '#000' : '#ccc')))
svg
.append('g')
.attr('transform', `translate(${width},0)`)
.call(d3.axisLeft(y).ticks(6).tickSizeOuter(0))
svg
.append('g')
.attr('transform', `translate(${marginLeft},0)`)
.call(
d3.axisLeft(y)
.ticks(25)
.tickSizeOuter(0)
.tickFormat((d, i) => (i % 5 === 0 || d == 0 ? d : ''))
)
.call((g) => g.selectAll('.tick line').clone().attr('x2', width - marginLeft).attr('stroke', (d, i) => (i % 5 === 0 ? '#000' : '#ccc')))
const line = d3
.line()
.x((d) => x(d.x))
.y((d) => y(d.y))
const y0Data = [
{ x: 0, y: ymax },
{ x: 0, y: ymin },
]
const x0Data = [
{ x: xmin, y: 0 },
{ x: xmax, y: 0 },
]
svg.append('path').attr('fill', 'none').attr('stroke', '#000').attr('stroke-width', 1).attr('d', line(x0Data))
svg.append('path').attr('fill', 'none').attr('stroke', '#000').attr('stroke-width', 1).attr('d', line(y0Data))
svg.append('path').attr('fill', 'none').attr('stroke', 'rgb(239,83,83)').attr('stroke-width', 3).attr('d', line(safeData))
},
adjustChartSize() { adjustChartSize() {
// 调整图表大小的方法 // 调整图表大小的方法
}, },
......
<!-- 井基础信息详情 -->
<template> <template>
<div class="app-container"> <div class="app-container">
<el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick" style="margin-top: -10px;"> <el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick" style="margin-top: -10px;">
<el-tab-pane label="数据表格" name="dataTable"> <el-tab-pane label="数据表格" name="dataTable">
<DataTable :jh="queryParams.jh" /> <DataTable v-if="activeTab === 'dataTable'" :jh="queryParams.jh" :key="`dataTable-${queryParams.jh}`" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="曲线图形" name="curveGraph"> <el-tab-pane label="曲线图形" name="curveGraph">
<CurveGraph :jh="queryParams.jh" /> <CurveGraph v-if="activeTab === 'curveGraph'" :jh="queryParams.jh"
:key="`curveGraph-${queryParams.jh}`" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="直方图形" name="histogramGraph"> <el-tab-pane label="直方图形" name="histogramGraph">
<HistogramGraph :jh="queryParams.jh" /> <HistogramGraph v-if="activeTab === 'histogramGraph'" :jh="queryParams.jh"
<!-- <HistogramGraph :jh="wellId" theme="elegant" /> :key="`histogramGraph-${queryParams.jh}`" />
<HistogramGraph :jh="wellId" theme="vibrant" /> -->
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="测井数据" name="loggingData"> <el-tab-pane label="测井数据" name="loggingData">
<LoggingData :jh="queryParams.jh" /> <LoggingData v-if="activeTab === 'loggingData'" :jh="queryParams.jh"
:key="`loggingData-${queryParams.jh}`" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="测井曲线" name="loggingCurve"> <el-tab-pane label="测井曲线" name="loggingCurve">
<keep-alive> <keep-alive>
<LoggingCurve ref="loggingCurveComponent" :jh="queryParams.jh" /> <LoggingCurve v-if="activeTab === 'loggingCurve'" ref="loggingCurveComponent" :jh="queryParams.jh"
:key="`loggingCurve-${queryParams.jh}`" />
</keep-alive> </keep-alive>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="录井数据" name="drillingData"> <el-tab-pane label="录井数据" name="drillingData">
<DrillingData :jh="queryParams.jh" /> <DrillingData v-if="activeTab === 'drillingData'" :jh="queryParams.jh"
:key="`drillingData-${queryParams.jh}`" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="录井曲线" name="drillingCurve"> <el-tab-pane label="录井曲线" name="drillingCurve">
<keep-alive> <keep-alive>
<DrillingCurve ref="drillingCurveComponent" :jh="queryParams.jh" /> <DrillingCurve v-if="activeTab === 'drillingCurve'" ref="drillingCurveComponent"
:jh="queryParams.jh" :key="`drillingCurve-${queryParams.jh}`" />
</keep-alive> </keep-alive>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="井眼轨迹" name="wellboreTrajectory"> <el-tab-pane label="井眼轨迹" name="wellboreTrajectory">
<WellboreTrajectory :jh="queryParams.jh" /> <WellboreTrajectory v-if="activeTab === 'wellboreTrajectory'" :jh="queryParams.jh"
:key="`wellboreTrajectory-${queryParams.jh}`" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="井身结构" name="wellDepthStructure"> <el-tab-pane label="井身结构" name="wellDepthStructure">
<WellDepthStructure :jh="queryParams.jh" /> <WellDepthStructure v-if="activeTab === 'wellDepthStructure'" :jh="queryParams.jh"
:key="`wellDepthStructure-${queryParams.jh}`" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
<script> <script>
import DataTable from './components/DataTable.vue'; import DataTable from './components/DataTable.vue';
import CurveGraph from './components/CurveGraph.vue'; import CurveGraph from './components/CurveGraph.vue';
...@@ -85,53 +81,21 @@ export default { ...@@ -85,53 +81,21 @@ export default {
queryParams: { queryParams: {
jh: '' jh: ''
}, },
// 标记是否是第一次进入页面
isFirstLoad: true,
// 表格数据 // 表格数据
tableData: [ tableData: [
{
qk: '克深',
jh: '克深1102',
ztcc: '241.3',
ztxh: 'GT56S',
qsjd: '500',
jsjd: '2735',
xrcw: '',
qccw: '',
jc: '2235',
jxzs: '23.75',
ztcj: 'DBS',
ztbh: '2'
},
{
qk: '克深',
jh: '克深1102',
ztcc: '165.3',
ztxh: 'MDI513',
qsjd: '3586',
jsjd: '4068',
xrcw: '',
qccw: '',
jc: '482',
jxzs: '5.59',
ztcj: '史密斯',
ztbh: '7'
}
] ]
}; };
}, },
created() { created() {
// 获取路由参数 // 获取路由参数
const { jh } = this.$route.params; const { jh } = this.$route.params;
console.log('路由参数 jh:', jh);
if (jh) { if (jh) {
this.queryParams.jh = jh; this.queryParams.jh = jh;
console.log('设置 queryParams.jh:', this.queryParams.jh);
} else { } else {
console.warn('未获取到路由参数 jh'); console.warn('未获取到路由参数 jh');
} }
// 确保第一次进入页面时不会自动初始化测井曲线组件
console.log('页面初始化完成,等待用户点击tab');
}, },
methods: { methods: {
/** 搜索按钮操作 */ /** 搜索按钮操作 */
...@@ -150,7 +114,6 @@ export default { ...@@ -150,7 +114,6 @@ export default {
return; return;
} }
this.$modal.confirm('是否确认移除选中的记录?').then(() => { this.$modal.confirm('是否确认移除选中的记录?').then(() => {
// 这里可以调用API进行删除操作
this.$modal.msgSuccess("移除成功"); this.$modal.msgSuccess("移除成功");
}).catch(() => { }); }).catch(() => { });
}, },
...@@ -163,26 +126,7 @@ export default { ...@@ -163,26 +126,7 @@ export default {
/** tab切换事件 */ /** tab切换事件 */
handleTabClick(tab) { handleTabClick(tab) {
console.log('切换到tab:', tab.name); console.log('切换到tab:', tab.name);
// 当切换到测井曲线tab时,触发子组件的重新初始化
if (tab.name === 'loggingCurve') {
this.$nextTick(() => {
if (this.$refs.loggingCurveComponent) {
console.log('触发测井曲线组件重新初始化');
this.$refs.loggingCurveComponent.refreshChart();
}
});
}
// 当切换到录井曲线tab时,触发子组件的重新初始化
if (tab.name === 'drillingCurve') {
this.$nextTick(() => {
if (this.$refs.drillingCurveComponent) {
console.log('触发录井曲线组件重新初始化');
this.$refs.drillingCurveComponent.refreshChart();
}
});
}
// 标记已经不是第一次加载
this.isFirstLoad = false;
} }
} }
}; };
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
<el-button type="primary" @click="jscs">计算参数</el-button> <el-button type="primary" @click="jscs">计算参数</el-button>
<el-button type="primary" @click="js">计算</el-button> --> <el-button type="primary" @click="js">计算</el-button> -->
</el-form-item> </el-form-item>
<right-toolbar :search="false" :show-refresh="false" :showSearch.sync="showSearch"
@queryTable="handleCjData" :columns="columns" @columns-change="onColumnsChange" />
</el-form> </el-form>
<div style="background-color: #fff;"> <div style="background-color: #fff;">
<!-- <el-form style="background-color: #fff" ref="queryForm" size="small" :inline="true" v-show="showSearch" <!-- <el-form style="background-color: #fff" ref="queryForm" size="small" :inline="true" v-show="showSearch"
...@@ -36,8 +39,9 @@ ...@@ -36,8 +39,9 @@
}" :header-cell-class-name="'table-header'" :cell-style="{ }" :header-cell-class-name="'table-header'" :cell-style="{
padding: '1px 0' padding: '1px 0'
}" :tooltip-effect="'dark'" header-overflow-tooltip v-loading="loading"> }" :tooltip-effect="'dark'" header-overflow-tooltip v-loading="loading">
<el-table-column v-for="(col, index) in tableColumns" :key="index" :label="col.label" :prop="col.prop" <el-table-column v-for="(col, index) in filteredTableColumns" :key="index" :label="col.label"
:width="col.width || 120" align="center" show-overflow-tooltip :render-header="renderTableHeader" /> :prop="col.prop" :width="col.width || 120" align="center" show-overflow-tooltip
:render-header="renderTableHeader" />
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" :page.sync="cjqueryParams.pageNum" <pagination v-show="total > 0" :total="total" :page.sync="cjqueryParams.pageNum"
:limit.sync="cjqueryParams.pageSize" @pagination="handleCjData" /> :limit.sync="cjqueryParams.pageSize" @pagination="handleCjData" />
...@@ -264,6 +268,8 @@ export default { ...@@ -264,6 +268,8 @@ export default {
}, },
openjscs: false, openjscs: false,
showSearch: true, showSearch: true,
// 显隐列配置(配合 RightToolbar)
columns: [],
total: 0, total: 0,
cjsjLasList: [], cjsjLasList: [],
form: {}, form: {},
...@@ -384,6 +390,13 @@ export default { ...@@ -384,6 +390,13 @@ export default {
] ]
}; };
}, },
computed: {
// 过滤出可见列供模板渲染,避免 v-for 搭配 v-if
filteredTableColumns() {
if (!Array.isArray(this.columns) || this.columns.length === 0) return this.tableColumns;
return this.tableColumns.filter((_, idx) => this.columns[idx] ? this.columns[idx].visible !== false : true);
}
},
mounted() { mounted() {
this.cjqueryParams = { this.cjqueryParams = {
pageNum: 1, pageNum: 1,
...@@ -391,6 +404,8 @@ export default { ...@@ -391,6 +404,8 @@ export default {
jh: this.$route.query.jh jh: this.$route.query.jh
} }
this.handleCjData(); this.handleCjData();
// 初始化显隐列(默认全部显示)
this.columns = this.tableColumns.map((col, idx) => ({ key: idx, label: col.label, visible: true }));
}, },
watch: { watch: {
activeTab: { activeTab: {
...@@ -403,6 +418,11 @@ export default { ...@@ -403,6 +418,11 @@ export default {
} }
}, },
methods: { methods: {
onColumnsChange({ index, visible }) {
if (Array.isArray(this.columns) && this.columns[index]) {
this.$set(this.columns[index], 'visible', visible);
}
},
TableHeight() { TableHeight() {
const windowHeight = window.innerHeight; const windowHeight = window.innerHeight;
const topBarHeight = 100; const topBarHeight = 100;
......
...@@ -475,7 +475,7 @@ ...@@ -475,7 +475,7 @@
<el-form-item style="margin: 5px 0 5px 10px;"> <el-form-item style="margin: 5px 0 5px 10px;">
<el-button type="primary" @click="handleImport2">导入las文件</el-button> <el-button type="primary" @click="handleImport2">导入las文件</el-button>
<el-button type="primary" @click="handleExport">导出</el-button> <el-button type="primary" @click="handleExport">导出</el-button>
<el-button type="primary" @click="handleImport">导入</el-button> <el-button type="primary" @click="handleImport">导入Excel</el-button>
<el-button type="primary" @click="cjsz">设置</el-button> <el-button type="primary" @click="cjsz">设置</el-button>
<el-button type="primary" @click="jscs">计算参数</el-button> <el-button type="primary" @click="jscs">计算参数</el-button>
<el-button type="primary" @click="js">计算</el-button> <el-button type="primary" @click="js">计算</el-button>
......
<!-- 钻头基础信息 basicInformationOfDrillBit -->
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- 查询表单 --> <!-- 查询表单 -->
...@@ -24,8 +22,6 @@ ...@@ -24,8 +22,6 @@
<el-button @click="onReset" size="mini">重置</el-button> <el-button @click="onReset" size="mini">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="onAdd" <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="onAdd"
...@@ -43,9 +39,12 @@ ...@@ -43,9 +39,12 @@
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
v-hasPermi="['system:ztxxJcxx:export']">导出</el-button> v-hasPermi="['system:ztxxJcxx:export']">导出</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="el-icon-upload2" size="mini" @click="handleImport"
v-hasPermi="['system:user:import']">导入</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="onSearch"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="onSearch"></right-toolbar>
</el-row> </el-row>
<!-- 数据表格 --> <!-- 数据表格 -->
<el-table :data="tableData" style="width: 100%;margin: 10px 0;" stripe highlight-current-row border <el-table :data="tableData" style="width: 100%;margin: 10px 0;" stripe highlight-current-row border
v-loading="loading" @selection-change="handleSelectionChange"> v-loading="loading" @selection-change="handleSelectionChange">
...@@ -75,8 +74,6 @@ ...@@ -75,8 +74,6 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 新增弹窗 --> <!-- 新增弹窗 -->
<el-dialog title="新增钻头" :visible.sync="dialogVisible" width="90%" @close="handleDialogClose"> <el-dialog title="新增钻头" :visible.sync="dialogVisible" width="90%" @close="handleDialogClose">
<div class="dialog-card"> <div class="dialog-card">
...@@ -124,8 +121,6 @@ ...@@ -124,8 +121,6 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-collapse-item> </el-collapse-item>
<el-collapse-item title="布齿密度" name="bcmd"> <el-collapse-item title="布齿密度" name="bcmd">
<el-form-item prop="tzdm02"> <el-form-item prop="tzdm02">
<el-radio-group v-model="form.tzdm02" style="width:100%"> <el-radio-group v-model="form.tzdm02" style="width:100%">
...@@ -204,7 +199,6 @@ ...@@ -204,7 +199,6 @@
</span> </span>
</div> </div>
</el-dialog> </el-dialog>
<!-- 详情弹窗 --> <!-- 详情弹窗 -->
<el-dialog title="查看" :visible.sync="detailVisible" width="95%" @close="detailVisible = false"> <el-dialog title="查看" :visible.sync="detailVisible" width="95%" @close="detailVisible = false">
<div class="detail-container"> <div class="detail-container">
...@@ -221,7 +215,6 @@ ...@@ -221,7 +215,6 @@
<span class="info-value">{{ detailData.ztbh }}</span> <span class="info-value">{{ detailData.ztbh }}</span>
</div> </div>
</div> </div>
<!-- 现代化特征代码卡片区 --> <!-- 现代化特征代码卡片区 -->
<div class="feature-code-cards"> <div class="feature-code-cards">
<div class="code-card" v-for="(item, i) in featureMap" :key="i"> <div class="code-card" v-for="(item, i) in featureMap" :key="i">
...@@ -230,7 +223,6 @@ ...@@ -230,7 +223,6 @@
<!-- <div class="code-value">{{ detailData[item.codeField + '_value'] || (detailData[item.codeField] || '--') }}</div> --> <!-- <div class="code-value">{{ detailData[item.codeField + '_value'] || (detailData[item.codeField] || '--') }}</div> -->
</div> </div>
</div> </div>
<!-- 特征参数 --> <!-- 特征参数 -->
<div class="feature-params"> <div class="feature-params">
<div class="params-header"> <div class="params-header">
...@@ -259,6 +251,27 @@ ...@@ -259,6 +251,27 @@
:show-close="true" center> :show-close="true" center>
<img :src="imgPreviewUrl" style="max-width:80vw;max-height:80vh;border-radius:18px;" /> <img :src="imgPreviewUrl" style="max-width:80vw;max-height:80vh;border-radius:18px;" />
</el-dialog> </el-dialog>
<!-- 用户导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<div class="el-upload__tip" slot="tip">
<el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
</div>
<span>仅允许导入xls、xlsx格式文件。</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
@click="importTemplate">下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
...@@ -266,10 +279,25 @@ ...@@ -266,10 +279,25 @@
<script> <script>
import { listTzsj } from "@/api/system/jsha"; import { listTzsj } from "@/api/system/jsha";
import { listZtxxJcxx, addZtxxJcxx, updateZtxxJcxx, delZtxxJcxx, getZtxxJcxx } from '@/api/ztxx'; import { listZtxxJcxx, addZtxxJcxx, updateZtxxJcxx, delZtxxJcxx, getZtxxJcxx } from '@/api/ztxx';
import { getToken } from "@/utils/auth";
export default { export default {
data() { data() {
return { return {
// 用户导入参数
upload: {
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: "",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
// 上传的地址
url: process.env.VUE_APP_BASE_API + "/system/ztxxJcxx/importData"
},
// 遮罩层 // 遮罩层
loading: true, loading: true,
// 选中数组 // 选中数组
...@@ -416,6 +444,32 @@ export default { ...@@ -416,6 +444,32 @@ export default {
this.onSearch(); this.onSearch();
}, },
methods: { methods: {
/** 导入按钮操作 */
handleImport() {
this.upload.title = "用户导入";
this.upload.open = true;
},
/** 下载模板操作 */
importTemplate() {
this.download('system/ztxxJcxx/downdrmb', {
}, `钻头基本信息_${new Date().getTime()}.xlsx`)
},
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });
this.getList();
},
// 提交上传文件
submitFileForm() {
this.$refs.upload.submit();
},
onSearch() { onSearch() {
// 查询接口 // 查询接口
listZtxxJcxx(this.queryParams).then(res => { listZtxxJcxx(this.queryParams).then(res => {
...@@ -531,11 +585,11 @@ export default { ...@@ -531,11 +585,11 @@ export default {
// 编辑 // 编辑
onEdit(row) { onEdit(row) {
this.editType = 'edit'; this.editType = 'edit';
this.onReset(); this.onReset();
const id = row.id || this.ids const id = row.id || this.ids
getZtxxJcxx(id).then(response => { getZtxxJcxx(id).then(response => {
this.form = response.data; this.form = response.data;
console.log(this.form, 'this.form');
this.openDialog(); this.openDialog();
this.title = "修改钻头基础信息"; this.title = "修改钻头基础信息";
}); });
...@@ -558,6 +612,7 @@ export default { ...@@ -558,6 +612,7 @@ export default {
const selectedOption = this[mapping.options].find(opt => opt.id === idValue); const selectedOption = this[mapping.options].find(opt => opt.id === idValue);
if (selectedOption) { if (selectedOption) {
this.form[mapping.valueField] = selectedOption.value; this.form[mapping.valueField] = selectedOption.value;
console.log(this.form[mapping.valueField], 'this.form[mapping.valueField]');
} }
} }
}); });
......
<!-- 测井数据 --> <!-- 测井数据 -->
<template> <template>
<div class="app-containercj"> <div class="app-containercj">
<!-- <el-tabs v-model="activeTab" v-loading="loading"> <!-- <el-tabs v-model="activeTab" v-loading="loading">
<el-tab-pane label="测井数据" name="loggingData"> --> <el-tab-pane label="测井数据" name="loggingData"> -->
<el-form :model="cjqueryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" <el-form :model="cjqueryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
label-width="100px"> label-width="100px">
<el-form-item label="井号" prop="jh"> <el-form-item label="井号11" prop="jh">
<el-input v-model="cjqueryParams.jh" placeholder="请输入井号" clearable @keyup.enter.native="handleQuery" /> <el-input v-model="cjqueryParams.jh" placeholder="请输入井号" clearable @keyup.enter.native="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleImport2">导入las文件</el-button> <el-button type="primary" @click="handleImport2">导入las文件</el-button>
<el-button type="primary" @click="handleExport">导出</el-button> <el-button type="primary" @click="handleExport">导出</el-button>
<el-button type="primary" @click="handleImport">导入</el-button> <el-button type="primary" @click="handleImport">导入Excel</el-button>
<el-button type="primary" @click="cjsz">设置</el-button> <el-button type="primary" @click="cjsz">设置</el-button>
<el-button type="primary" @click="jscs">计算参数</el-button> <el-button type="primary" @click="jscs">计算参数</el-button>
<el-button type="primary" @click="js">计算</el-button> <el-button type="primary" @click="js">计算</el-button>
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
<!-- <el-button type="warning" plain icon="el-icon-download" size="mini" <!-- <el-button type="warning" plain icon="el-icon-download" size="mini"
@click="handleExport">导出</el-button> --> @click="handleExport">导出</el-button> -->
</el-form-item> </el-form-item>
<right-toolbar :search="false" :show-refresh="false" :showSearch.sync="showSearch"
@queryTable="handleCjData" :columns="columns" @columns-change="onColumnsChange" />
</el-form> </el-form>
<div style="background-color: #fff;"> <div style="background-color: #fff;">
<!-- <el-form style="background-color: #fff" ref="queryForm" size="small" :inline="true" v-show="showSearch" <!-- <el-form style="background-color: #fff" ref="queryForm" size="small" :inline="true" v-show="showSearch"
...@@ -38,8 +41,9 @@ ...@@ -38,8 +41,9 @@
}" :header-cell-class-name="'table-header'" :cell-style="{ }" :header-cell-class-name="'table-header'" :cell-style="{
padding: '1px 0' padding: '1px 0'
}" :tooltip-effect="'dark'" header-overflow-tooltip v-loading="loading"> }" :tooltip-effect="'dark'" header-overflow-tooltip v-loading="loading">
<el-table-column v-for="(col, index) in tableColumns" :key="index" :label="col.label" :prop="col.prop" <el-table-column v-for="(col, index) in filteredTableColumns" :key="index" :label="col.label"
:width="col.width || 120" align="center" show-overflow-tooltip :render-header="renderTableHeader" /> :prop="col.prop" :width="col.width || 120" align="center" show-overflow-tooltip
:render-header="renderTableHeader" />
</el-table> </el-table>
<pagination :total="total" :page.sync="cjqueryParams.pageNum" :limit.sync="cjqueryParams.pageSize" <pagination :total="total" :page.sync="cjqueryParams.pageNum" :limit.sync="cjqueryParams.pageSize"
@pagination="handleCjData" /> @pagination="handleCjData" />
...@@ -292,7 +296,7 @@ ...@@ -292,7 +296,7 @@
<template slot="footer"> <template slot="footer">
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleWellCancel">取 消</el-button> <el-button @click="handleWellCancel">取 消</el-button>
<el-button type="primary" @click="handleWellSubmit">提 交</el-button> <el-button type="primary" @click="handleWellSubmit">确 定</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
...@@ -340,6 +344,8 @@ export default { ...@@ -340,6 +344,8 @@ export default {
}, },
openjscs: false, openjscs: false,
showSearch: true, showSearch: true,
// 显隐列配置(配合 RightToolbar)
columns: [],
total: 0, total: 0,
cjsjLasList: [], cjsjLasList: [],
form: {}, form: {},
...@@ -494,6 +500,11 @@ export default { ...@@ -494,6 +500,11 @@ export default {
b1: this.formjscs?.b1 || '', b1: this.formjscs?.b1 || '',
b2: this.formjscs?.b2 || '' b2: this.formjscs?.b2 || ''
}; };
},
// 过滤出可见列供模板渲染,避免 v-for 搭配 v-if
filteredTableColumns() {
if (!Array.isArray(this.columns) || this.columns.length === 0) return this.tableColumns;
return this.tableColumns.filter((_, idx) => this.columns[idx] ? this.columns[idx].visible !== false : true);
} }
}, },
mounted() { mounted() {
...@@ -505,6 +516,8 @@ export default { ...@@ -505,6 +516,8 @@ export default {
jh: this.wellInfo.jh || this.$route.query.jh jh: this.wellInfo.jh || this.$route.query.jh
} }
this.handleCjData(); this.handleCjData();
// 初始化显隐列(默认全部显示)
this.columns = this.tableColumns.map((col, idx) => ({ key: idx, label: col.label, visible: true }));
this.getBlockOptions().then(() => { this.getBlockOptions().then(() => {
// 区块选项加载完成后,设置默认区块值 // 区块选项加载完成后,设置默认区块值
if (this.qkmc) { if (this.qkmc) {
...@@ -533,6 +546,11 @@ export default { ...@@ -533,6 +546,11 @@ export default {
} }
}, },
methods: { methods: {
onColumnsChange({ index, visible }) {
if (Array.isArray(this.columns) && this.columns[index]) {
this.$set(this.columns[index], 'visible', visible);
}
},
TableHeight() { TableHeight() {
const windowHeight = window.innerHeight; const windowHeight = window.innerHeight;
const topBarHeight = 130; const topBarHeight = 130;
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
<el-table-column prop="ztxh" label="钻头型号" min-width="150" align="center" /> <el-table-column prop="ztxh" label="钻头型号" min-width="150" align="center" />
<el-table-column prop="ztlb" label="钻头类别" min-width="120" align="center" /> <el-table-column prop="ztlb" label="钻头类别" min-width="120" align="center" />
<el-table-column prop="sccj" label="生产厂家" min-width="120" align="center" /> <el-table-column prop="sccj" label="生产厂家" min-width="120" align="center" />
<el-table-column label="操作" min-width="100" align="center"> <el-table-column label="操作" min-width="100" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="handleView(scope.row)">查看</el-button> <el-button type="text" @click="handleView(scope.row)">查看</el-button>
......
...@@ -26,7 +26,6 @@ import AdjacentWell from './components/AdjacentWell.vue' ...@@ -26,7 +26,6 @@ import AdjacentWell from './components/AdjacentWell.vue'
import FormationAnalysis from './components/FormationAnalysis.vue' import FormationAnalysis from './components/FormationAnalysis.vue'
import BitDesign from './components/BitDesign.vue' import BitDesign from './components/BitDesign.vue'
import FormationMaintenance from './components/FormationMaintenance.vue' import FormationMaintenance from './components/FormationMaintenance.vue'
export default { export default {
name: 'WellDesign', name: 'WellDesign',
components: { components: {
...@@ -49,7 +48,6 @@ export default { ...@@ -49,7 +48,6 @@ export default {
} }
}, },
watch: { watch: {
// 监听路由变化,确保参数正确传递
$route: { $route: {
handler(to, from) { handler(to, from) {
this.getWellInfo(); this.getWellInfo();
...@@ -58,28 +56,23 @@ export default { ...@@ -58,28 +56,23 @@ export default {
} }
}, },
created() { created() {
// 从路由参数或store获取井信息
this.getWellInfo() this.getWellInfo()
// 确保默认选中井身结构标签页
this.$nextTick(() => { this.$nextTick(() => {
this.activeTab = 'wellStructure'; this.activeTab = 'wellStructure';
}); });
}, },
beforeRouteUpdate(to, from, next) { beforeRouteUpdate(to, from, next) {
// 当路由参数变化时,重新获取井信息
this.getWellInfo(); this.getWellInfo();
next(); next();
}, },
methods: { methods: {
getWellInfo() { getWellInfo() {
// 从路由参数获取井信息
const { jh, jhdm, qkmc } = this.$route.query const { jh, jhdm, qkmc } = this.$route.query
console.log('wellDesign getWellInfo - route query:', this.$route.query); console.log('wellDesign getWellInfo - route query:', this.$route.query);
console.log('wellDesign getWellInfo - qkmc from route:', qkmc); console.log('wellDesign getWellInfo - qkmc from route:', qkmc);
if (jh && jhdm) { if (jh && jhdm) {
this.wellInfo.jh = jh this.wellInfo.jh = jh
this.wellInfo.jhdm = jhdm this.wellInfo.jhdm = jhdm
// 可以从store获取更多井信息
this.wellInfo.jd = this.$store.state.app.jd || '' this.wellInfo.jd = this.$store.state.app.jd || ''
this.wellInfo.ytgs = this.$store.state.app.ytgs || '' this.wellInfo.ytgs = this.$store.state.app.ytgs || ''
} }
...@@ -88,12 +81,10 @@ export default { ...@@ -88,12 +81,10 @@ export default {
console.log('wellDesign getWellInfo - qkmc set to:', this.qkmc); console.log('wellDesign getWellInfo - qkmc set to:', this.qkmc);
} }
// 强制更新子组件
this.reloadComponents(); this.reloadComponents();
}, },
reloadComponents() { reloadComponents() {
// 通过重置tab的方式强制刷新子组件
const currentTab = this.activeTab; const currentTab = this.activeTab;
this.activeTab = ''; this.activeTab = '';
this.$nextTick(() => { this.$nextTick(() => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment